import 'dart:convert';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:go_router/go_router.dart';

/// Handles FCM foreground/background notifications and local notification display.
class NotificationService {
  static final _localNotifications = FlutterLocalNotificationsPlugin();
  static GoRouter? _router;

  /// Callback for when a chat request notification is tapped.
  /// Set this from the app to bridge notifications → Riverpod state.
  static void Function(String sessionId)? onChatRequestTapped;

  static const _channel = AndroidNotificationChannel(
    'chat_messages',
    'Chat Messages',
    description: 'Notifications for incoming chat messages',
    importance: Importance.high,
  );

  static Future<void> initialize(GoRouter router) async {
    _router = router;

    // Create Android notification channel
    await _localNotifications
        .resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
        ?.createNotificationChannel(_channel);

    // Initialize local notifications
    await _localNotifications.initialize(
      settings: const InitializationSettings(
        android: AndroidInitializationSettings('@mipmap/ic_launcher'),
        iOS: DarwinInitializationSettings(),
      ),
      onDidReceiveNotificationResponse: _onNotificationTap,
    );

    // FCM foreground messages → show local notification
    FirebaseMessaging.onMessage.listen(_onForegroundMessage);

    // FCM notification tap (app was in background)
    FirebaseMessaging.onMessageOpenedApp.listen(_onMessageOpenedApp);

    // Check if app was opened from a terminated state via notification
    final initialMessage = await FirebaseMessaging.instance.getInitialMessage();
    if (initialMessage != null) {
      _navigateFromMessage(initialMessage.data);
    }
  }

  static void _onForegroundMessage(RemoteMessage message) {
    final notification = message.notification;
    if (notification == null) return;

    _localNotifications.show(
      id: notification.hashCode,
      title: notification.title,
      body: notification.body,
      notificationDetails: NotificationDetails(
        android: AndroidNotificationDetails(
          _channel.id,
          _channel.name,
          channelDescription: _channel.description,
          importance: Importance.high,
          priority: Priority.high,
        ),
        iOS: const DarwinNotificationDetails(
          presentAlert: true,
          presentBadge: true,
          presentSound: true,
        ),
      ),
      payload: jsonEncode(message.data),
    );
  }

  static void _onNotificationTap(NotificationResponse response) {
    if (response.payload == null) return;
    try {
      final data = jsonDecode(response.payload!) as Map<String, dynamic>;
      _navigateFromMessage(data);
    } catch (_) {}
  }

  static void _onMessageOpenedApp(RemoteMessage message) {
    _navigateFromMessage(message.data);
  }

  /// Show a local notification programmatically (e.g. from WebSocket while backgrounded)
  static Future<void> showLocalNotification({
    required String title,
    required String body,
    Map<String, dynamic>? data,
  }) async {
    await _localNotifications.show(
      id: DateTime.now().millisecondsSinceEpoch % 100000,
      title: title,
      body: body,
      notificationDetails: NotificationDetails(
        android: AndroidNotificationDetails(
          _channel.id,
          _channel.name,
          channelDescription: _channel.description,
          importance: Importance.high,
          priority: Priority.high,
          playSound: true,
          enableVibration: true,
        ),
        iOS: const DarwinNotificationDetails(
          presentAlert: true,
          presentBadge: true,
          presentSound: true,
        ),
      ),
      payload: data != null ? jsonEncode(data) : null,
    );
  }

  static void _navigateFromMessage(Map<String, dynamic> data) {
    if (_router == null) return;
    final sessionId = data['session_id'] as String?;
    final type = data['type'] as String?;
    final action = data['action'] as String?;

    if (type == 'chat_request' && action == 'open_accept' && sessionId != null) {
      // Update the notifier state with this session, then navigate
      onChatRequestTapped?.call(sessionId);
      _router!.go('/home');
    } else if (type == 'session_closing' || type == 'session_expired') {
      // Navigate to the chat session closure screen
      if (sessionId != null) {
        _router!.push('/chat/session/$sessionId', extra: {'customerName': 'Customer'});
      }
    } else if (type == 'chat_message' && sessionId != null) {
      _router!.push('/chat/session/$sessionId', extra: {'customerName': 'Customer'});
    }
  }
}
