import 'dart:async';
import 'dart:io';

import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;

import '../../main.dart';

class NotificationController extends GetxController {
  final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();

  @override
  void onInit() {
    super.onInit();
    initNotifications();
  }

  // Initializes the local notifications plugin
  Future<void> initNotifications() async {
    const AndroidInitializationSettings android =
        AndroidInitializationSettings('@mipmap/launcher_icon');
    DarwinInitializationSettings ios = DarwinInitializationSettings(
      requestAlertPermission: true,
      requestBadgePermission: true,
      requestSoundPermission: true,
      // onDidReceiveLocalNotification:
      //     (int id, String? title, String? body, String? payload) async {},
    );
    InitializationSettings initializationSettings =
        InitializationSettings(android: android, iOS: ios);
    await _flutterLocalNotificationsPlugin.initialize(initializationSettings);

    tz.initializeTimeZones();
    print('Notifications initialized');
  }

  // Displays a notification with the given title and message
  void showNotification(String title, String message, String tone) async {
    final AndroidNotificationDetails android = AndroidNotificationDetails(
      'high_importance_channel',
      'High Importance Notifications',
      importance: Importance.max,
      priority: Priority.high,
      showWhen: false,
      sound: RawResourceAndroidNotificationSound(tone),
    );

    const DarwinNotificationDetails ios = DarwinNotificationDetails(
      sound: 'default',
      presentAlert: true,
      presentBadge: true,
      presentSound: true,
    );

    final NotificationDetails details =
        NotificationDetails(android: android, iOS: ios);
    await _flutterLocalNotificationsPlugin.show(0, title, message, details);
    print('Notification shown: $title - $message');
  }
// /Users/hamzaaleghwairyeen/development/App/ride 2/lib/controller/firebase/local_notification.dart

// Assume _flutterLocalNotificationsPlugin is initialized somewhere in your code

  // void scheduleNotificationsForSevenDays(
  //     String title, String message, String tone) async {
  //   final AndroidNotificationDetails android = AndroidNotificationDetails(
  //     'high_importance_channel',
  //     'High Importance Notifications',
  //     importance: Importance.max,
  //     priority: Priority.high,
  //     sound: RawResourceAndroidNotificationSound(tone),
  //   );

  //   const DarwinNotificationDetails ios = DarwinNotificationDetails(
  //     sound: 'default',
  //     presentAlert: true,
  //     presentBadge: true,
  //     presentSound: true,
  //   );

  //   final NotificationDetails details =
  //       NotificationDetails(android: android, iOS: ios);

  //   // Check for the exact alarm permission on Android 12 and above
  //   if (Platform.isAndroid) {
  //     if (await Permission.scheduleExactAlarm.isDenied) {
  //       if (await Permission.scheduleExactAlarm.request().isGranted) {
  //         print('SCHEDULE_EXACT_ALARM permission granted');
  //       } else {
  //         print('SCHEDULE_EXACT_ALARM permission denied');
  //         return;
  //       }
  //     }
  //   }

  //   // Schedule notifications for the next 7 days
  //   for (int day = 0; day < 7; day++) {
  //     // Schedule for 8:00 AM
  //     await _scheduleNotificationForTime(
  //         day, 8, 0, title, message, details, day * 1000 + 1);

  //     // Schedule for 3:00 PM
  //     await _scheduleNotificationForTime(
  //         day, 15, 0, title, message, details, day * 1000 + 2); // Unique ID

  //     // Schedule for 8:00 PM
  //     await _scheduleNotificationForTime(
  //         day, 20, 0, title, message, details, day * 1000 + 3); // Unique ID
  //   }

  //   print('Notifications scheduled successfully for the next 7 days');
  // }
  void scheduleNotificationsForSevenDays(
      String title, String message, String tone) async {
    final AndroidNotificationDetails android = AndroidNotificationDetails(
      'high_importance_channel',
      'High Importance Notifications',
      importance: Importance.max,
      priority: Priority.high,
      sound: RawResourceAndroidNotificationSound(tone),
    );

    const DarwinNotificationDetails ios = DarwinNotificationDetails(
      sound: 'default',
      presentAlert: true,
      presentBadge: true,
      presentSound: true,
    );

    final NotificationDetails details =
        NotificationDetails(android: android, iOS: ios);

    // Check for the exact alarm permission on Android 12 and above
    if (Platform.isAndroid) {
      if (await Permission.scheduleExactAlarm.isDenied) {
        if (await Permission.scheduleExactAlarm.request().isGranted) {
          print('SCHEDULE_EXACT_ALARM permission granted');
        } else {
          print('SCHEDULE_EXACT_ALARM permission denied');
          return;
        }
      }
    }

    // Schedule notifications for the next 7 days
    for (int day = 0; day < 7; day++) {
      // List of notification times
      final notificationTimes = [
        {'hour': 8, 'minute': 0, 'id': day * 1000 + 1}, // 8:00 AM
        {'hour': 15, 'minute': 0, 'id': day * 1000 + 2}, // 3:00 PM
        {'hour': 20, 'minute': 0, 'id': day * 1000 + 3}, // 8:00 PM
      ];

      for (var time in notificationTimes) {
        final notificationId = time['id'] as int;

        // Check if this notification ID is already stored
        bool isScheduled = box.read('notification_$notificationId') ?? false;

        if (!isScheduled) {
          // Schedule the notification if not already scheduled
          await _scheduleNotificationForTime(
            day,
            time['hour'] as int,
            time['minute'] as int,
            title,
            message,
            details,
            notificationId,
          );

          // Mark this notification ID as scheduled in GetStorage
          box.write('notification_$notificationId', true);
        } else {
          print('Notification with ID $notificationId is already scheduled.');
        }
      }
    }

    print('Notifications scheduled successfully for the next 7 days');
  }

  void scheduleNotificationsForTimeSelected(
      String title, String message, String tone, DateTime timeSelected) async {
    final AndroidNotificationDetails android = AndroidNotificationDetails(
      'high_importance_channel',
      'High Importance Notifications',
      importance: Importance.max,
      priority: Priority.high,
      sound: RawResourceAndroidNotificationSound(tone),
    );

    const DarwinNotificationDetails ios = DarwinNotificationDetails(
      sound: 'default',
      presentAlert: true,
      presentBadge: true,
      presentSound: true,
    );

    final NotificationDetails details =
        NotificationDetails(android: android, iOS: ios);

    // Check for the exact alarm permission on Android 12 and above
    if (Platform.isAndroid) {
      if (await Permission.scheduleExactAlarm.isDenied) {
        if (await Permission.scheduleExactAlarm.request().isGranted) {
          print('SCHEDULE_EXACT_ALARM permission granted');
        } else {
          print('SCHEDULE_EXACT_ALARM permission denied');
          return;
        }
      }
    }

    // Schedule notifications for 10 and 30 minutes before the timeSelected
    await _scheduleNotificationForTimeVIP(
      timeSelected.subtract(const Duration(minutes: 10)), // 10 minutes before
      title,
      message,
      details,
      1, // Unique ID for 10-minute before notification
    );

    await _scheduleNotificationForTimeVIP(
      timeSelected.subtract(const Duration(minutes: 30)), // 30 minutes before
      title,
      message,
      details,
      2, // Unique ID for 30-minute before notification
    );

    print('Notifications scheduled successfully for the time selected');
  }

  Future<void> _scheduleNotificationForTimeVIP(
    DateTime scheduledDate,
    String title,
    String message,
    NotificationDetails details,
    int notificationId,
  ) async {
    // Initialize and set Cairo timezone
    tz.initializeTimeZones();
    var cairoLocation = tz.getLocation('Africa/Cairo');

    final now = tz.TZDateTime.now(cairoLocation);

    // Convert to Cairo time
    tz.TZDateTime scheduledTZDateTime =
        tz.TZDateTime.from(scheduledDate, cairoLocation);

    // Check if 10 minutes before the scheduled time is in the past
    if (scheduledTZDateTime
        .subtract(const Duration(minutes: 10))
        .isBefore(now)) {
      // If the 10 minutes before the scheduled time is in the past, don't schedule
      print(
          'Scheduled time minus 10 minutes is in the past. Skipping notification.');
      return; // Skip this notification
    }

    print('Current time (Cairo): $now');
    print('Scheduling notification for: $scheduledTZDateTime');

    await _flutterLocalNotificationsPlugin.zonedSchedule(
      notificationId, // Unique ID for each notification
      title,
      message,
      scheduledTZDateTime,
      details,
      androidScheduleMode: AndroidScheduleMode.exact,
      // uiLocalNotificationDateInterpretation:
      //     UILocalNotificationDateInterpretation.absoluteTime,
      matchDateTimeComponents:
          null, // Don't repeat automatically; we handle manually
    );

    print('Notification scheduled successfully for: $scheduledTZDateTime');
  }

  Future<void> _scheduleNotificationForTime(
    int dayOffset,
    int hour,
    int minute,
    String title,
    String message,
    NotificationDetails details,
    int notificationId,
  ) async {
    // Initialize and set Cairo timezone
    tz.initializeTimeZones();
    var cairoLocation = tz.getLocation('Africa/Cairo');

    final now = tz.TZDateTime.now(cairoLocation);
    tz.TZDateTime scheduledDate = tz.TZDateTime(
      cairoLocation,
      now.year,
      now.month,
      now.day + dayOffset, // Add offset to schedule for the next days
      hour,
      minute,
    );

    // If the scheduled time is in the past, move it to the next day
    if (scheduledDate.isBefore(now)) {
      scheduledDate = scheduledDate.add(const Duration(days: 1));
    }

    print('Current time (Cairo): $now');
    print('Scheduling notification for: $scheduledDate');

    await _flutterLocalNotificationsPlugin.zonedSchedule(
      notificationId, // Unique ID for each notification
      title,
      message,
      scheduledDate,
      details,
      androidScheduleMode: AndroidScheduleMode.exact,
      // uiLocalNotificationDateInterpretation:
      //     UILocalNotificationDateInterpretation.absoluteTime,
      matchDateTimeComponents:
          null, // Don't repeat automatically; we handle 7 days manually
    );

    print('Notification scheduled successfully for: $scheduledDate');
  }
}
