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

import 'package:sefer_driver/constant/colors.dart';
import 'package:sefer_driver/views/home/Captin/orderCaptin/order_request_page.dart';
import 'package:sefer_driver/views/home/Captin/orderCaptin/order_speed_request.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';

import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import '../../constant/box_name.dart';
import '../../main.dart';
import '../../print.dart';
import '../../views/notification/notification_captain.dart';
import '../home/captin/home_captain_controller.dart';

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

  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);
    tz.initializeTimeZones();
    print('Notifications initialized');
    await _flutterLocalNotificationsPlugin.initialize(
      initializationSettings,
      onDidReceiveNotificationResponse: onDidReceiveNotificationResponse,
      onDidReceiveBackgroundNotificationResponse: notificationTapBackground,
    );

    // Create a notification channel
    const AndroidNotificationChannel channel = AndroidNotificationChannel(
      'high_importance_channel', // Use the same ID as in strings.xml
      'High Importance Notifications',
      description: 'This channel is used for important notifications.',
      importance: Importance.high,
    );

    // Register the channel with the system
    await _flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
            AndroidFlutterLocalNotificationsPlugin>()
        ?.createNotificationChannel(channel);
  }

  // Displays a notification with the given title and message
  void showNotification(
      String title, String message, String tone, String payLoad) async {
    BigTextStyleInformation bigTextStyleInformation = BigTextStyleInformation(
      message,
      contentTitle: title.tr,
      htmlFormatContent: true,
      htmlFormatContentTitle: true,
    );
    AndroidNotificationDetails android = AndroidNotificationDetails(
      'high_importance_channel',
      'High Importance Notifications',
      importance: Importance.max,
      priority: Priority.high,
      sound: RawResourceAndroidNotificationSound(tone),
    );

    // AndroidNotificationDetails android = AndroidNotificationDetails(
    //   'high_importance_channel', // Use the same ID as before
    //   'High Importance Notifications',
    //   importance: Importance.high,
    //   priority: Priority.high,
    //   styleInformation: bigTextStyleInformation,
    //   playSound: true,
    //   sound: RawResourceAndroidNotificationSound(tone),
    //   // audioAttributesUsage: AudioAttributesUsage.alarm,
    //   visibility: NotificationVisibility.public,
    //   autoCancel: false,
    //   color: AppColor.primaryColor,
    //   showProgress: true,
    //   showWhen: true,
    //   ongoing: true,
    //   enableVibration: true,
    //   vibrationPattern: Int64List.fromList([0, 1000, 500, 1000]),
    //   timeoutAfter: 14500,
    //   setAsGroupSummary: true,
    //   subText: message, fullScreenIntent: true,
    //   actions: [
    //     AndroidNotificationAction(
    //       allowGeneratedReplies: true,
    //       'id',
    //       title.tr,
    //       titleColor: AppColor.blueColor,
    //       showsUserInterface: true,
    //     )
    //   ],
    //   category: AndroidNotificationCategory.message,
    // );

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

    await _flutterLocalNotificationsPlugin.show(0, title, message, details,
        payload: jsonEncode({'title': title, 'data': payLoad}));
  }

  void scheduleNotificationAtSpecificTime(
      String title, String message, String tone, int hour, int minute) async {
    // Initialize and set Cairo time zone
    tz.initializeTimeZones();
    var cairoLocation;
    if (box.read(BoxName.countryCode).toString() == 'Egypt') {
      cairoLocation = tz.getLocation('Africa/Cairo');
    } else {} // todo get for location country

    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);

    final now =
        tz.TZDateTime.now(cairoLocation); // Use Cairo timezone for current time
    tz.TZDateTime scheduledTime = tz.TZDateTime(
        cairoLocation, now.year, now.month, now.day, hour, minute);

    // If the scheduled time has already passed for today, schedule it for the next day
    if (scheduledTime.isBefore(now)) {
      scheduledTime = scheduledTime.add(const Duration(days: 1));
    }

    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;
        }
      }
    }

    print('Current time: $now');
    print('Scheduling notification for: $scheduledTime');
    await _flutterLocalNotificationsPlugin.zonedSchedule(
      0,
      title,
      message,
      scheduledTime,
      details,
      // androidAllowWhileIdle: true,
      uiLocalNotificationDateInterpretation:
          UILocalNotificationDateInterpretation.absoluteTime,
      matchDateTimeComponents: DateTimeComponents.time,
      androidScheduleMode:
          AndroidScheduleMode.alarmClock, // Triggers daily at the same time
    );
    print('Notification scheduled successfully');
  }

  void scheduleNotificationAfter1Minute(
      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);

// Schedule the notification to be shown after 1 minute
    Timer.periodic(const Duration(seconds: 15), (timer) async {
      final now = tz.TZDateTime.now(tz.local);
      final scheduledTime = now.add(const Duration(seconds: 10));
      Log.print('scheduledTime: ${scheduledTime}');
      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;
          }
        }
      }

      print('Scheduling notification for: $scheduledTime');
      await _flutterLocalNotificationsPlugin.zonedSchedule(
        0,
        title,
        message,
        scheduledTime,
        details,
        uiLocalNotificationDateInterpretation:
            UILocalNotificationDateInterpretation.absoluteTime,
        matchDateTimeComponents: DateTimeComponents.time,
        androidScheduleMode: AndroidScheduleMode.alarmClock,
      );
      print('Notification scheduled successfully');
    });
  }

  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');
  }

  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(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');
  }

  void scheduleNotificationEvery10Hours(
      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);

    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;
        }
      }
    }

    Timer.periodic(const Duration(hours: 10), (timer) async {
      final now = tz.TZDateTime.now(tz.local);
      final scheduledTime = now.add(const Duration(minutes: 10));

      print('Scheduling notification for: $scheduledTime');
      await _flutterLocalNotificationsPlugin.zonedSchedule(
        0,
        title.tr,
        message.tr,
        scheduledTime,
        details,
        // androidAllowWhileIdle: true,
        uiLocalNotificationDateInterpretation:
            UILocalNotificationDateInterpretation.absoluteTime,
        matchDateTimeComponents: DateTimeComponents.time,
        androidScheduleMode: AndroidScheduleMode.alarmClock,
      );
    });

    print('Notifications scheduled every 5 seconds');
  }

  void showTimerNotification(String title, String message, String tone) async {
    final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
        FlutterLocalNotificationsPlugin();

    // Setup Android notification
    final AndroidNotificationDetails android = AndroidNotificationDetails(
      'high_importance_channel',
      'High Importance Notifications',
      importance: Importance.max,
      priority: Priority.high,
      showWhen: false,
      sound: RawResourceAndroidNotificationSound(
          tone), // tone without the file extension
    );

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

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

    // Request permission on Android
    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;
        }
      }
    }

    // Timer duration (e.g., 120 seconds countdown)
    int countdown = 12;

    // Display the notification initially with the full countdown time

    // Timer to update the notification every second
    Timer.periodic(const Duration(seconds: 1), (timer) async {
      // if (countdown > 0) {
      // Update the existing notification with the updated countdown

      // Decrease the countdown by 1
      countdown--;
      // } else {
      //   // Cancel the timer when the countdown reaches zero
      //   timer.cancel();
      // }
    });
    await flutterLocalNotificationsPlugin.show(
      0,
      title,
      '$message Remaining: $countdown seconds', // Initial message
      details,
    );
    print('Notification will update every second');
  }

  // Callback when the notification is tapped
  void onDidReceiveNotificationResponse(NotificationResponse response) {
    handleNotificationResponse(response);
  }

  // Callback when the notification is tapped while the app is in the background
  void onDidReceiveBackgroundNotificationResponse(
      NotificationResponse response) {
    handleNotificationResponse(response);
  }

  // Handle notification response for both foreground and background
  void handleNotificationResponse(NotificationResponse response) {
    print('Notification tapped!');
    Log.print('response.payload: ${response.payload}');
    if (response.payload != null) {
      print('Notification payload: ${response.payload}');
      var payloadData = jsonDecode(response.payload.toString());

      if (payloadData is Map<String, dynamic>) {
        String title = payloadData['title'];
        var data = payloadData['data'];

        switch (title) {
          case 'Order':
            _handleOrderNotification(data);
            break;
          case 'OrderSpeed':
            _handleOrderSpeedNotification(data);
            break;
          case 'ADS':
            _handleADSNotification();
            break;
          default:
            Log.print('Unknown notification type');
        }
      } else {
        Log.print('Invalid payload format');
      }
    } else {
      Log.print('Payload is null');
    }
  }

  void _handleOrderNotification(dynamic data) {
    if (data is String) {
      var orderData = jsonDecode(data);
      if (orderData is List && orderData.length == 34) {
        //closeOverLay();
        Get.put(HomeCaptainController()).changeRideId();
        Get.to(() => OrderRequestPage(), arguments: {'myListString': data});
      } else {
        Log.print('Invalid order data');
      }
    } else {
      Log.print('Invalid order payload');
    }
  }

  void _handleOrderSpeedNotification(dynamic data) {
    if (data is String) {
      var orderData = jsonDecode(data);
      if (orderData is List && orderData.length == 34) {
        //closeOverLay();
        Get.put(HomeCaptainController()).changeRideId();
        Get.to(() => OrderRequestPage(), arguments: {'myListString': data});
      } else {
        Log.print('Invalid order data');
      }
    } else {
      Log.print('Invalid order payload');
    }
  }

  void _handleADSNotification() {
    // var orderData = jsonDecode(data);
    //closeOverLay();
    Get.to(
      () => const NotificationCaptain(),
    );
  }

  void onDidReceiveLocalNotification(
      int id, String? title, String? body, String? payload) async {
    // display a dialog with the notification details, tap ok to go to another page
  }
}

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

  // Initializes the local notifications plugin
  Future<void> initNotifications() async {
    const AndroidInitializationSettings android =
        AndroidInitializationSettings('@mipmap/launcher_icon');
    const InitializationSettings initializationSettings =
        InitializationSettings(android: android);
    await _flutterLocalNotificationsPlugin.initialize(initializationSettings);
  }

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

    NotificationDetails details = NotificationDetails(android: android);
    await _flutterLocalNotificationsPlugin.show(0, title, message, details);
  }
}
