import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:logger/logger.dart';

import 'package:on_field_work/helpers/services/local_notification_service.dart';
import 'package:on_field_work/helpers/services/storage/local_storage.dart';
import 'package:on_field_work/helpers/services/auth_service.dart';
import 'package:on_field_work/helpers/services/notification_action_handler.dart';

/// Firebase Notification Service
class FirebaseNotificationService {
  final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
  final Logger _logger = Logger();

  /// Initialize FCM (Firebase.initializeApp() should be called once globally)
  Future<void> initialize() async {
    _logger.i('✅ FirebaseMessaging initializing...');

    await _requestNotificationPermission();
    _registerMessageListeners();
    _registerTokenRefreshListener();

    // Fetch token on app start (and register with server if JWT available)
    await getFcmToken(registerOnServer: true);
  }

  /// Request notification permission
  Future<void> _requestNotificationPermission() async {
    final settings = await _firebaseMessaging.requestPermission();
    _logger.i('📩 Permission Status: ${settings.authorizationStatus}');
  }

  /// Foreground, background, and tap listeners
  void _registerMessageListeners() {
    FirebaseMessaging.onMessage.listen((message) {
      _logger.i('📩 Foreground Notification');
      _logNotificationDetails(message);

      // Handle custom actions
      NotificationActionHandler.handle(message.data);

      // Show local notification
      if (message.notification != null) {
        LocalNotificationService.showNotification(
          title: message.notification!.title ?? "No title",
          body: message.notification!.body ?? "No body",
        );
      }
    });

    FirebaseMessaging.onMessageOpenedApp.listen(_handleNotificationTap);

    // Background messages
    FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
  }

  /// Token refresh handler
  void _registerTokenRefreshListener() {
    _firebaseMessaging.onTokenRefresh.listen((newToken) async {
      _logger.i('🔄 Token refreshed: $newToken');
      if (newToken.isEmpty) return;

      await LocalStorage.setFcmToken(newToken);

      final jwt = await LocalStorage.getJwtToken();
      if (jwt?.isNotEmpty ?? false) {
        final success = await AuthService.registerDeviceToken(newToken);
        _logger.i(success
            ? '✅ Device token updated on server after refresh.'
            : '⚠️ Failed to update device token on server.');
      } else {
        _logger.w('⚠️ JWT not available — will retry after login.');
      }
    });
  }

  /// Get current token (optionally sync to server if logged in)
  Future<String?> getFcmToken({bool registerOnServer = false}) async {
    try {
      final token = await _firebaseMessaging.getToken();
      _logger.i('🔑 FCM token: $token');

      if (token?.isNotEmpty ?? false) {
        await LocalStorage.setFcmToken(token!);

        if (registerOnServer) {
          final jwt = await LocalStorage.getJwtToken();
          if (jwt?.isNotEmpty ?? false) {
            final success = await AuthService.registerDeviceToken(token);
            _logger.i(success
                ? '✅ Device token registered on server.'
                : '⚠️ Failed to register device token on server.');
          } else {
            _logger.w('⚠️ JWT not available — skipping server registration.');
          }
        }
      }
      return token;
    } catch (e, s) {
      _logger.e('❌ Failed to get FCM token', error: e, stackTrace: s);
      return null;
    }
  }

  /// Re-register token with server (useful after login)
  Future<void> registerTokenAfterLogin() async {
    final token = await LocalStorage.getFcmToken();
    if (token?.isNotEmpty ?? false) {
      final success = await AuthService.registerDeviceToken(token!);
      _logger.i(success
          ? "✅ FCM token registered after login."
          : "⚠️ Failed to register FCM token after login.");
    }
  }

  /// Handle tap on notification
  void _handleNotificationTap(RemoteMessage message) {
    _logger.i('📌 Notification tapped: ${message.data}');
    NotificationActionHandler.handle(message.data);
  }

  /// Log notification details
  void _logNotificationDetails(RemoteMessage message) {
    _logger
      ..i('🆔 ID: ${message.messageId}')
      ..i('📜 Title: ${message.notification?.title}')
      ..i('📜 Body: ${message.notification?.body}')
      ..i('📦 Data: ${message.data}');
  }
}

/// 🔹 Background handler (required by Firebase)
/// Must be a top-level function and annotated for AOT
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  final logger = Logger();
  logger
    ..i('⚡ Handling background notification...')
    ..i('📦 Data: ${message.data}');

  NotificationActionHandler.handle(message.data);
}
