import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:flutter/foundation.dart';
import '../services/notification_service.dart';
import '../providers/subscription_provider.dart';

class NotificationProvider extends ChangeNotifier {
  final FlutterSecureStorage _secureStorage = const FlutterSecureStorage();
  static const String _paymentNotificationKey = 'payment_notification_enabled';
  static const String _unusedServiceNotificationKey =
      'unused_service_notification_enabled';
  static const String _reminderDaysKey = 'reminder_days';
  static const String _reminderHourKey = 'reminder_hour';
  static const String _reminderMinuteKey = 'reminder_minute';
  static const String _dailyReminderKey = 'daily_reminder_enabled';
  static const String _firstPermissionGrantedKey = 'first_permission_granted';

  bool _isEnabled = false;
  bool _isPaymentEnabled = true;
  bool _isUnusedServiceNotificationEnabled = false;
  int _reminderDays = 3; // 기본값: 3일 전
  int _reminderHour = 10; // 기본값: 오전 10시
  int _reminderMinute = 0; // 기본값: 0분
  bool _isDailyReminderEnabled = false; // 기본값: 반복 알림 비활성화

  // 웹 플랫폼 여부 확인 (웹에서는 알림이 지원되지 않음)
  bool get _isWeb => kIsWeb;

  // SubscriptionProvider 인스턴스 (알림 재예약 시 사용)
  SubscriptionProvider? _subscriptionProvider;

  bool get isEnabled => _isEnabled;
  bool get isPaymentEnabled => _isPaymentEnabled;
  bool get isUnusedServiceNotificationEnabled =>
      _isUnusedServiceNotificationEnabled;
  int get reminderDays => _reminderDays;
  int get reminderHour => _reminderHour;
  int get reminderMinute => _reminderMinute;
  bool get isDailyReminderEnabled => _isDailyReminderEnabled;

  NotificationProvider() {
    _loadSettings();
  }

  // SubscriptionProvider 설정 (알림 재예약 시 사용)
  void setSubscriptionProvider(SubscriptionProvider provider) {
    _subscriptionProvider = provider;
  }

  Future<void> _loadSettings() async {
    final paymentValue =
        await _secureStorage.read(key: _paymentNotificationKey);
    final unusedValue =
        await _secureStorage.read(key: _unusedServiceNotificationKey);
    final reminderDaysValue = await _secureStorage.read(key: _reminderDaysKey);
    final reminderHourValue = await _secureStorage.read(key: _reminderHourKey);
    final reminderMinuteValue =
        await _secureStorage.read(key: _reminderMinuteKey);
    final dailyReminderValue =
        await _secureStorage.read(key: _dailyReminderKey);

    _isPaymentEnabled = paymentValue == 'true';
    _isUnusedServiceNotificationEnabled = unusedValue == 'true';
    _reminderDays =
        reminderDaysValue != null ? int.tryParse(reminderDaysValue) ?? 3 : 3;
    _reminderHour =
        reminderHourValue != null ? int.tryParse(reminderHourValue) ?? 10 : 10;
    _reminderMinute = reminderMinuteValue != null
        ? int.tryParse(reminderMinuteValue) ?? 0
        : 0;
    _isDailyReminderEnabled = dailyReminderValue == 'true';
    notifyListeners();
  }

  Future<void> init() async {
    try {
      _isEnabled = await NotificationService.isNotificationEnabled();
      _isPaymentEnabled =
          await NotificationService.isPaymentNotificationEnabled();
      notifyListeners();
    } catch (e) {
      debugPrint('알림 설정 초기화 중 오류 발생: $e');
    }
  }

  Future<void> setEnabled(bool value) async {
    try {
      _isEnabled = value;
      await NotificationService.setNotificationEnabled(value);

      // 첫 권한 부여 시 기본 설정 적용
      if (value) {
        await initializeDefaultSettingsOnFirstPermission();
      }

      notifyListeners();
    } catch (e) {
      debugPrint('알림 활성화 설정 중 오류 발생: $e');
    }
  }

  Future<void> setPaymentEnabled(bool value) async {
    try {
      // 설정값이 변경된 경우에만 처리
      if (_isPaymentEnabled != value) {
        _isPaymentEnabled = value;
        await NotificationService.setPaymentNotificationEnabled(value);

        // 웹에서는 알림 기능 비활성화
        if (_isWeb) {
          debugPrint('웹 플랫폼에서는 알림 기능이 지원되지 않습니다.');
          notifyListeners();
          return;
        }

        // 알림이 활성화된 경우에만 알림 재예약 (비활성화 시에는 필요 없음)
        if (value) {
          final hasPermission = await NotificationService.checkPermission();
          if (!hasPermission) {
            final granted = await NotificationService.requestPermission();
            if (!granted) {
              debugPrint('알림 권한이 부여되지 않았습니다. 일부 알림이 제한될 수 있습니다.');
            }
          }

          final canExact = await NotificationService.canScheduleExactAlarms();
          if (!canExact) {
            final exactGranted =
                await NotificationService.requestExactAlarmsPermission();
            if (!exactGranted) {
              debugPrint('정확 알람 권한이 없어 근사 알림으로 예약됩니다.');
            }
          }

          // 알림 설정 변경 시 모든 구독의 알림 재예약
          // 지연 실행으로 UI 응답성 향상
          Future.microtask(() => _rescheduleNotificationsIfNeeded());
        } else {
          // 알림이 비활성화되면 모든 알림 취소
          try {
            await NotificationService.cancelAllNotifications();
          } catch (e) {
            debugPrint('알림 취소 중 오류 발생: $e');
          }
        }

        notifyListeners();
      }
    } catch (e) {
      debugPrint('결제 알림 설정 중 오류 발생: $e');
    }
  }

  Future<void> setUnusedServiceNotificationEnabled(bool value) async {
    try {
      _isUnusedServiceNotificationEnabled = value;
      await _secureStorage.write(
        key: _unusedServiceNotificationKey,
        value: value.toString(),
      );
      notifyListeners();
    } catch (e) {
      debugPrint('미사용 서비스 알림 설정 중 오류 발생: $e');
    }
  }

  // 알림 시점 설정 (1일전, 2일전, 3일전)
  Future<void> setReminderDays(int days) async {
    try {
      // 값이 변경된 경우에만 처리
      if (_reminderDays != days) {
        _reminderDays = days;
        await _secureStorage.write(
          key: _reminderDaysKey,
          value: days.toString(),
        );

        // 웹에서는 알림 기능 비활성화
        if (_isWeb) {
          debugPrint('웹 플랫폼에서는 알림 기능이 지원되지 않습니다.');
          notifyListeners();
          return;
        }

        // 1일 전으로 설정되면 반복 알림 자동 비활성화
        if (days == 1 && _isDailyReminderEnabled) {
          await setDailyReminderEnabled(false);
        } else if (_isPaymentEnabled) {
          // 알림이 활성화된 경우에만 처리
          // 알림 설정 변경 시 모든 구독의 알림 재예약 (백그라운드에서 처리)
          Future.microtask(() => _rescheduleNotificationsIfNeeded());
        }

        notifyListeners();
      }
    } catch (e) {
      debugPrint('알림 시점 설정 중 오류 발생: $e');
    }
  }

  // 알림 시간 설정
  Future<void> setReminderTime(int hour, int minute) async {
    try {
      // 값이 변경된 경우에만 처리
      if (_reminderHour != hour || _reminderMinute != minute) {
        _reminderHour = hour;
        _reminderMinute = minute;
        await _secureStorage.write(
          key: _reminderHourKey,
          value: hour.toString(),
        );
        await _secureStorage.write(
          key: _reminderMinuteKey,
          value: minute.toString(),
        );

        // 웹에서는 알림 기능 비활성화
        if (_isWeb) {
          debugPrint('웹 플랫폼에서는 알림 기능이 지원되지 않습니다.');
          notifyListeners();
          return;
        }

        // 알림이 활성화된 경우에만 처리
        if (_isPaymentEnabled) {
          // 알림 설정 변경 시 모든 구독의 알림 재예약 (백그라운드에서 처리)
          Future.microtask(() => _rescheduleNotificationsIfNeeded());
        }

        notifyListeners();
      }
    } catch (e) {
      debugPrint('알림 시간 설정 중 오류 발생: $e');
    }
  }

  // 반복 알림 설정
  Future<void> setDailyReminderEnabled(bool value) async {
    try {
      // 값이 변경된 경우에만 처리
      if (_isDailyReminderEnabled != value) {
        _isDailyReminderEnabled = value;
        await _secureStorage.write(
          key: _dailyReminderKey,
          value: value.toString(),
        );

        // 웹에서는 알림 기능 비활성화
        if (_isWeb) {
          debugPrint('웹 플랫폼에서는 알림 기능이 지원되지 않습니다.');
          notifyListeners();
          return;
        }

        // 알림이 활성화된 경우에만 처리
        if (_isPaymentEnabled) {
          // 알림 설정 변경 시 모든 구독의 알림 재예약 (백그라운드에서 처리)
          Future.microtask(() => _rescheduleNotificationsIfNeeded());
        }

        notifyListeners();
      }
    } catch (e) {
      debugPrint('반복 알림 설정 중 오류 발생: $e');
    }
  }

  // 알림 설정 변경 시 모든 구독의 알림 일정 재예약
  Future<void> _rescheduleNotificationsIfNeeded() async {
    try {
      // 웹 플랫폼에서는 지원하지 않음
      if (_isWeb) {
        debugPrint('웹 플랫폼에서는 알림 기능이 지원되지 않습니다.');
        return;
      }

      // 구독 목록을 가져올 수 있고, 알림이 활성화된 경우에만 재예약
      if (_subscriptionProvider != null && _isPaymentEnabled) {
        final subscriptions = _subscriptionProvider!.subscriptions;
        await NotificationService.reschedulAllNotifications(subscriptions);
      }
    } catch (e) {
      debugPrint('알림 재예약 중 오류 발생: $e');
      // 오류가 발생해도 앱 동작에 영향을 주지 않도록 처리
    }
  }

  // 첫 권한 부여 시 기본 설정 초기화
  Future<void> initializeDefaultSettingsOnFirstPermission() async {
    try {
      final firstGranted =
          await _secureStorage.read(key: _firstPermissionGrantedKey);
      if (firstGranted != 'true') {
        // 첫 권한 부여 시 기본값 설정
        await setReminderDays(2); // 2일 전 알림
        await setDailyReminderEnabled(true); // 반복 알림 활성화
        await setPaymentEnabled(true); // 결제 예정 알림 활성화

        // 첫 권한 부여 플래그 저장
        await _secureStorage.write(
            key: _firstPermissionGrantedKey, value: 'true');
      }
    } catch (e) {
      debugPrint('기본 설정 초기화 중 오류 발생: $e');
    }
  }
}
