import 'dart:developer';

import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:injectable/injectable.dart';

/// Background message handler — harus top-level function
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  log('[FCM] Background message: ${message.messageId}');
}

@lazySingleton
class FcmService {
  FcmService(this._messaging, this._localNotifications);

  final FirebaseMessaging _messaging;
  final FlutterLocalNotificationsPlugin _localNotifications;

  /// Inisialisasi FCM: minta permission, set handler, ambil token
  Future<void> initialize() async {
    // Setup local notifications
    await _setupLocalNotifications();

    // Register background handler
    FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

    // Minta permission notifikasi (iOS & Android 13+)
    final settings = await _messaging.requestPermission(
      alert: true,
      badge: true,
      sound: true,
      provisional: false,
    );

    log('[FCM] Permission status: ${settings.authorizationStatus}');

    if (settings.authorizationStatus == AuthorizationStatus.authorized ||
        settings.authorizationStatus == AuthorizationStatus.provisional) {
      await _setupTokenHandling();
      _setupForegroundHandler();
      _setupOpenedAppHandler();
    }
  }

  Future<void> _setupLocalNotifications() async {
    const androidSettings = AndroidInitializationSettings('@drawable/ic_notification');
    const iosSettings = DarwinInitializationSettings(
      requestAlertPermission: true,
      requestBadgePermission: true,
      requestSoundPermission: true,
    );

    const initSettings = InitializationSettings(
      android: androidSettings,
      iOS: iosSettings,
    );

    await _localNotifications.initialize(
      initSettings,
      onDidReceiveNotificationResponse: _onNotificationTapped,
    );

    // Android notification channel
    const channel = AndroidNotificationChannel(
      'high_importance_channel',
      'High Importance Notifications',
      description: 'This channel is used for important notifications.',
      importance: Importance.high,
      playSound: true,
    );

    await _localNotifications
        .resolvePlatformSpecificImplementation<
            AndroidFlutterLocalNotificationsPlugin>()
        ?.createNotificationChannel(channel);
  }

  void _onNotificationTapped(NotificationResponse response) {
    log('[FCM] Notification tapped: ${response.payload}');
    // TODO: handle navigation berdasarkan payload
  }

  Future<void> _setupTokenHandling() async {
    final token = await getToken();
    log('========================================');
    log('[FCM] TOKEN: $token');
    log('========================================');
    // TODO: kirim token ke server jika diperlukan

    _messaging.onTokenRefresh.listen((newToken) {
      log('========================================');
      log('[FCM] TOKEN REFRESHED: $newToken');
      log('========================================');
      // TODO: kirim token baru ke server jika diperlukan
    });
  }

  void _setupForegroundHandler() {
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      log('[FCM] Foreground message: ${message.messageId}');
      log('[FCM] Title: ${message.notification?.title}');
      log('[FCM] Body: ${message.notification?.body}');
      log('[FCM] Data: ${message.data}');

      // Tampilkan notifikasi lokal saat app di foreground
      final notification = message.notification;
      if (notification != null) {
        _showLocalNotification(
          id: message.hashCode,
          title: notification.title ?? '',
          body: notification.body ?? '',
          payload: message.data.toString(),
        );
      }
    });
  }

  void _setupOpenedAppHandler() {
    // App dibuka dari notifikasi saat terminated
    _messaging.getInitialMessage().then((RemoteMessage? message) {
      if (message != null) {
        log('[FCM] App opened from terminated via: ${message.messageId}');
        _handleMessageNavigation(message);
      }
    });

    // App dibuka dari notifikasi saat background
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      log('[FCM] App opened from background via: ${message.messageId}');
      _handleMessageNavigation(message);
    });
  }

  void _handleMessageNavigation(RemoteMessage message) {
    // TODO: tambahkan logika navigasi berdasarkan message.data
    log('[FCM] Handle navigation for: ${message.data}');
  }

  Future<void> _showLocalNotification({
    required int id,
    required String title,
    required String body,
    String? payload,
  }) async {
    const androidDetails = AndroidNotificationDetails(
      'high_importance_channel',
      'High Importance Notifications',
      channelDescription: 'This channel is used for important notifications.',
      importance: Importance.max,
      priority: Priority.max,
      showWhen: true,
      playSound: true,
      enableVibration: true,
      enableLights: true,
      fullScreenIntent: true,
      icon: 'ic_notification',
    );

    const iosDetails = DarwinNotificationDetails(
      presentAlert: true,
      presentBadge: true,
      presentSound: true,
    );

    const details = NotificationDetails(
      android: androidDetails,
      iOS: iosDetails,
    );

    await _localNotifications.show(id, title, body, details, payload: payload);
    log('[FCM] Local notification shown: $title');
  }

  /// Ambil FCM token perangkat
  Future<String?> getToken() async {
    try {
      return await _messaging.getToken();
    } catch (e) {
      log('[FCM] Failed to get token: $e');
      return null;
    }
  }

  /// Subscribe ke topic tertentu
  Future<void> subscribeToTopic(String topic) async {
    await _messaging.subscribeToTopic(topic);
    log('[FCM] Subscribed to topic: $topic');
  }

  /// Unsubscribe dari topic tertentu
  Future<void> unsubscribeFromTopic(String topic) async {
    await _messaging.unsubscribeFromTopic(topic);
    log('[FCM] Unsubscribed from topic: $topic');
  }
}
