import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:icalendar_parser/icalendar_parser.dart'; import 'package:path_provider/path_provider.dart'; import 'package:open_filex/open_filex.dart'; import 'package:universal_html/html.dart' as html; import 'package:intl/intl.dart'; import '../models/cycle_entry.dart'; class IcsService { static Future generateCycleCalendar(List entries) async { final iCalendar = ICalendar( properties: { 'prodid': '-//Christian Period Tracker//NONSGML v1.0//EN', 'version': '2.0', 'calscale': 'GREGORIAN', 'x-wr-calname': 'Cycle Tracking', 'x-wr-timezone': DateTime.now().timeZoneName, }, components: [], ); // Sort entries by date to ensure proper calendar order entries.sort((a, b) => a.date.compareTo(b.date)); for (var entry in entries) { if (entry.isPeriodDay) { final date = entry.date; final formattedDate = DateFormat('yyyyMMdd').format(date); final uid = '${date.year}${date.month}${date.day}-${entry.id}@christianperiodtracker.app'; iCalendar.components.add( CalendarEvent( properties: { 'uid': uid, 'dtstamp': IcsDateTime(dt: DateTime.now()), 'dtstart': IcsDateTime(dt: date, isUtc: false, date: true), // All-day event 'dtend': IcsDateTime(dt: date.add(const Duration(days: 1)), isUtc: false, date: true), // End on next day for all-day 'summary': 'Period Day', 'description': 'Period tracking for ${DateFormat.yMMMd().format(date)}', }, ), ); } } final String icsContent = iCalendar.serialize(); final String fileName = 'cycle_calendar_${DateFormat('yyyyMMdd').format(DateTime.now())}.ics'; if (kIsWeb) { // Web platform final bytes = icsContent.codeUnits; final blob = html.Blob([bytes], 'text/calendar'); final url = html.Url.createObjectUrlFromBlob(blob); html.AnchorElement(href: url) ..setAttribute('download', fileName) ..click(); html.Url.revokeObjectUrl(url); } else { // Mobile platform final directory = await getApplicationDocumentsDirectory(); final filePath = '${directory.path}/$fileName'; final file = File(filePath); await file.writeAsString(icsContent); await OpenFilex.open(filePath); } } }