import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:ui';

import 'package:device_calendar/device_calendar.dart';
import 'package:flutter/widgets.dart';
import 'package:hmg_patient_app_new/extensions/string_extensions.dart';
import 'package:hmg_patient_app_new/services/permission_service.dart';
import 'package:jiffy/jiffy.dart';
import 'package:manage_calendar_events/manage_calendar_events.dart' as ios;
import 'package:permission_handler/permission_handler.dart';
import 'package:timezone/data/latest.dart' as tzl;

final DeviceCalendarPlugin deviceCalendarPlugin = DeviceCalendarPlugin();
final ios.CalendarPlugin _myPlugin = ios.CalendarPlugin();

class CalendarUtils {
  static Completer<CalendarUtils>? _completer;

  dynamic get writableCalendars => calendars.firstWhere((c) => !c.isReadOnly!);
  dynamic calendars;

  CalendarUtils._(this.calendars);

  // static Future<CalendarUtils> getInstance() async {
  //   if (_completer == null) {
  //     _completer = Completer<CalendarUtils>();
  //     print(_completer!.isCompleted);
  //     try {
  //       final dynamic calendarsResult;
  //       if (Platform.isIOS) {
  //         calendarsResult = await _myPlugin.getCalendars();
  //         if (!_completer!.isCompleted) {
  //           _completer?.complete(CalendarUtils._(await calendarsResult!));
  //         }
  //       } else {
  //         calendarsResult = await deviceCalendarPlugin.retrieveCalendars();
  //         if (!_completer!.isCompleted) {
  //           _completer?.complete(CalendarUtils._(await calendarsResult.data!));
  //         }
  //       }
  //     } on Exception catch (e) {
  //       if (!_completer!.isCompleted) {
  //         _completer!.completeError(e);
  //       }
  //     }
  //   }
  //   return _completer!.future;
  // }

  Future<Map<Permission, PermissionStatus>> requestPermissions() async {
    var permissionResults = [Permission.calendarFullAccess].request();
    return permissionResults;
  }

  // showReminderDialog(BuildContext context, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted,
  //     {required Function() onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool isMultiAllowed = false}) async {
  //   if (Platform.isAndroid) {
  //     if (await PermissionService.isCalendarPermissionEnabled()) {
  //       _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted,
  //           onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed);
  //     } else {
  //       // Utils.showPermissionConsentDialog(context, TranslationBase.of(context).calendarPermission, () async {
  //       //   if (await Permission.calendarFullAccess.request().isGranted) {
  //       //     _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted,
  //       //         onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed);
  //       //   }
  //       // });
  //     }
  //   } else {
  //     if (await Permission.calendarWriteOnly.request().isGranted) {
  //       if (await Permission.calendarFullAccess.request().isGranted) {
  //         _showReminderDialog(context, dateTime, doctorName, eventId, appoDateFormatted, appoTimeFormatted,
  //             onSuccess: onSuccess, title: title, description: description, onMultiDateSuccess: onMultiDateSuccess, isMultiAllowed: isMultiAllowed);
  //       }
  //     }
  //   }
  // }

  // Future<void> _showReminderDialog(BuildContext providedContext, DateTime dateTime, String doctorName, String eventId, String appoDateFormatted, String appoTimeFormatted,
  //     {required Function onSuccess, String? title, String? description, Function(int)? onMultiDateSuccess, bool? isMultiAllowed}) async {
  //   return showDialog<void>(
  //     context: providedContext,
  //     barrierDismissible: true, // user must tap button!
  //     builder: (BuildContext context) {
  //       return Dialog(
  //         shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0.0)),
  //         insetPadding: EdgeInsets.all(21),
  //         child: ReminderDialog(
  //           onClick: (int i) async {
  //             String text = "";
  //             if (i == 0) {
  //               // Before 30 mints
  //               dateTime = Jiffy.parseFromDateTime(dateTime).subtract(minutes: 30).dateTime;
  //               text = "30 minutes";
  //               // dateTime.add(new Duration(minutes: -30));
  //             } else if (i == 1) {
  //               // Before 1 hour
  //               // dateTime.add(new Duration(minutes: -60));
  //               dateTime = Jiffy.parseFromDateTime(dateTime).subtract(hours: 1).dateTime;
  //               text = "1 hours";
  //             } else if (i == 2) {
  //               // Before 1 hour and 30 mints
  //               // dateTime.add(new Duration(minutes: -90));
  //               dateTime = Jiffy.parseFromDateTime(dateTime).subtract(hours: 1, minutes: 30).dateTime;
  //               text = "1 hours 30 minutes";
  //             } else if (i == 3) {
  //               // Before 2 hours
  //               // dateTime.add(new Duration(minutes: -120));
  //               dateTime = Jiffy.parseFromDateTime(dateTime).subtract(hours: 2).dateTime;
  //               text = "2 hours";
  //             }
  //             if (!isMultiAllowed!) {
  //               if (onMultiDateSuccess == null) {
  //                 CalendarUtils calendarUtils = await CalendarUtils.getInstance();
  //                 await calendarUtils.createOrUpdateEvent(
  //                     title: title ?? "TranslationBase.of(providedContext).reminderTitle".needTranslation + " " + doctorName,
  //                     description: description ?? "At " + appoDateFormatted + " " + appoTimeFormatted,
  //                     scheduleDateTime: dateTime,
  //                     eventId: eventId, location: '');
  //                 onSuccess();
  //               }
  //             } else {
  //               onMultiDateSuccess!(i);
  //             }
  //             // await _analytics.logEvent(
  //             //   name: name.trim().toLowerCase(),
  //             //   parameters: safeParameters,
  //             // );
  //             // todo @sikander discuss analytics for reminder
  //             // locator<GAnalytics>().appointment.appointment_reminder_time(reminde_before: text);
  //           },
  //         ),
  //       );
  //     },
  //   );
  // }

  static Future<CalendarUtils> getInstance() async {
    tzl.initializeTimeZones();
    if (_completer != null) {
      return _completer!.future;
    }
    _completer = Completer<CalendarUtils>();
    try {
      final dynamic calendarsResult;
      if (Platform.isIOS) {
        calendarsResult = await _myPlugin.getCalendars();
        _completer!.complete(CalendarUtils._(calendarsResult));
      } else {
        calendarsResult = await deviceCalendarPlugin.retrieveCalendars();
        _completer!.complete(CalendarUtils._(calendarsResult.data));
      }
    } catch (e) {
      _completer!.completeError(e);
    }

    return _completer!.future;
  }

  Future createOrUpdateEvents({List<DateTime>? scheduleList, String? title, String? description, List<DateTime>? scheduleDateTime, List<DayOfWeek>? daysOfWeek}) async {
    tzl.initializeTimeZones();
    List<Event> events = [];
    Location _currentLocation;
    if (DateTime.now().timeZoneName == "+04")
      _currentLocation = getLocation('Asia/Dubai');
    else
      _currentLocation = getLocation('Asia/Riyadh');

    scheduleDateTime!.forEach((element) {
      RecurrenceRule recurrenceRule = RecurrenceRule(
        // RecurrenceFrequency.Daily,
        // daysOfWeek: daysOfWeek,
        // endDate: element,
        until: element, frequency: Frequency.daily,
      );
      //added byAamir Tz Time
      Event event = Event(writableCalendars!.id,
          recurrenceRule: recurrenceRule,
          start: TZDateTime.from(element, _currentLocation),
          end: TZDateTime.from(element.add(Duration(minutes: 30)), _currentLocation),
          title: title,
          description: description);
      events.add(event);
    });

    events.forEach((element) {
      deviceCalendarPlugin.createOrUpdateEvent(element);
    });
  }

  Future createOrUpdateEvent({required String title, required String description, required String location, DateTime? scheduleDateTime, String? eventId}) async {
    RecurrenceRule recurrenceRule = RecurrenceRule(
      // RecurrenceFrequency.Daily,
      // daysOfWeek: daysOfWeek,
      // endDate: scheduleDateTime,
      until: scheduleDateTime, frequency: Frequency.daily,
    );

    Location _currentLocation;
    // if (DateTime.now().timeZoneName == "+04")
    //   _currentLocation = getLocation('Asia/Dubai');
    // else
    _currentLocation = getLocation('Asia/Riyadh');

    TZDateTime scheduleDateTimeUTZ = TZDateTime.from(scheduleDateTime!, _currentLocation);

    print("writableCalendars-name:  " + writableCalendars.name);
    print("writableCalendars-Id:  " + writableCalendars.id);
    print("writableCalendarsToString:  " + writableCalendars.toString());
    print("writableCalendarsToString:  " + writableCalendars!.id!);
    Event event = Event(
      writableCalendars!.id,
      start: scheduleDateTimeUTZ,
      end: scheduleDateTimeUTZ.add(Duration(minutes: 30)),
      title: title,
      description: description,
    );

    ios.CalendarEvent iosCalEvent =
        ios.CalendarEvent(location: location, startDate: scheduleDateTimeUTZ, endDate: scheduleDateTimeUTZ.add(Duration(minutes: 30)), title: title, description: description, isAllDay: false);

    if (Platform.isAndroid) {
      Result<bool> result = await deviceCalendarPlugin.hasPermissions();
      print(result);
      await deviceCalendarPlugin.createOrUpdateEvent(event).catchError((e) {
        print("catchError " + e.toString());
      }).whenComplete(() {
        print("whenComplete Calender ID " + eventId!);
      });
    } else {
      await _myPlugin.createEvent(calendarId: writableCalendars.id!, event: iosCalEvent).catchError((e) {
        print("catchError " + e.toString());
      }).whenComplete(() {
        print("whenComplete Calender ID iOS " + eventId!);
      });
    }
  }

  deleteEvent(String _calendarId, String _eventId) async {
    if (Platform.isIOS) {
      await _myPlugin.deleteEvent(calendarId: _calendarId, eventId: _eventId);
    } else {
      await deviceCalendarPlugin.deleteEvent(_calendarId, _eventId);
    }
  }

  Future retrieveEvents(
    String calendarId,
    RetrieveEventsParams retrieveEventsParams,
  ) async {
    if (Platform.isIOS) {
      return await _myPlugin.getEvents(calendarId: calendarId);
    } else {
      return await deviceCalendarPlugin.retrieveEvents(calendarId, retrieveEventsParams);
    }
  }

  Future createCalendar(
    String calendarName, {
    Color? calendarColor,
    String? localAccountName,
  }) async {
    return await deviceCalendarPlugin.createCalendar(calendarName, calendarColor: calendarColor, localAccountName: localAccountName);
  }
}
