import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';

/// 🔥 FCM Token Manager - Force regenerates token on logout/login
class FcmTokenManager {
  static final FcmTokenManager _instance = FcmTokenManager._internal();
  factory FcmTokenManager() => _instance;
  FcmTokenManager._internal();

  final FirebaseMessaging _messaging = FirebaseMessaging.instance;

  /// 🔑 Get current FCM token
  Future<String?> getCurrentToken() async {
    try {
      if (Platform.isIOS) {
        final apns = await _messaging.getAPNSToken();
        if (apns == null) {
          debugPrint('⚠️ APIs Token missing on iOS - Skipping FCM getToken');
          return null;
        }
      }

      debugPrint('🔄 Getting current FCM token...');
      final token = await _messaging.getToken();
      debugPrint('✅ Current FCM Token: $token');
      return token;
    } catch (e) {
      debugPrint('❌ Error getting FCM token: $e');
      return null;
    }
  }

  /// 🔄 Force regenerate FCM token (deletes old and creates new)
  /// Call this BEFORE login to ensure fresh token
  /// 🔄 Force regenerate FCM token (deletes old and creates new)
  Future<String?> regenerateToken() async {
    try {
      if (Platform.isIOS) {
        final apns = await _messaging.getAPNSToken();
        if (apns == null) {
          debugPrint(
            '⚠️ APIs Token missing on iOS - Cannot regenerate FCM token',
          );
          return null;
        }
      }

      debugPrint('🔄 Starting FCM token regeneration...');

      // Step 1: Get old token
      String? oldToken;
      try {
        oldToken = await _messaging.getToken();
        debugPrint('📋 OLD FCM Token: $oldToken');
      } catch (e) {
        debugPrint('⚠️ Could not get old token: $e');
      }

      // Step 2: Delete the old token
      try {
        debugPrint('🗑️ Deleting old FCM token...');
        await _messaging.deleteToken();
        debugPrint('✅ Old token deleted');
      } catch (e) {
        debugPrint('⚠️ Error deleting old token: $e');
      }

      // Step 3: Wait
      await Future.delayed(const Duration(milliseconds: 800));

      // Step 4: Request permission
      await _messaging.requestPermission(alert: true, badge: true, sound: true);

      // Step 5: Generate new token
      debugPrint('🔄 Generating new FCM token...');
      final newToken = await _messaging.getToken();

      if (newToken != null) {
        debugPrint('✅ NEW FCM Token: $newToken');
      } else {
        debugPrint('⚠️ Failed to generate new token');
      }

      return newToken;
    } catch (e) {
      debugPrint('❌ Error regenerating FCM token: $e');
      return null;
    }
  }

  /// 🗑️ Delete FCM token (call on logout)
  Future<bool> deleteToken() async {
    try {
      if (Platform.isIOS) {
        final apns = await _messaging.getAPNSToken();
        if (apns == null) return false;
      }

      // Print token before deletion
      final currentToken = await _messaging.getToken();
      debugPrint('📋 Current FCM Token (before delete): $currentToken');

      debugPrint('🗑️ Deleting FCM token...');
      await _messaging.deleteToken();
      debugPrint('✅ FCM token deleted successfully');

      return true;
    } catch (e) {
      debugPrint('❌ Error deleting FCM token: $e');
      return false;
    }
  }

  /// 📡 Listen to token refresh events
  void listenToTokenRefresh(Function(String) onTokenRefreshed) {
    _messaging.onTokenRefresh.listen((newToken) {
      debugPrint('🔔 FCM Token auto-refreshed by Firebase: $newToken');
      onTokenRefreshed(newToken);
    });
  }

  /// 🔄 Reset and get fresh token (comprehensive reset)
  Future<String?> resetAndGetFreshToken() async {
    try {
      // Delete existing token
      await deleteToken();

      // Wait longer to ensure complete reset
      await Future.delayed(const Duration(seconds: 1));

      // Regenerate
      return await regenerateToken();
    } catch (e) {
      debugPrint('❌ Error in resetAndGetFreshToken: $e');
      return null;
    }
  }
}
