import 'dart:io';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:get/get.dart';
import 'package:file_picker/file_picker.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:taxglide/consts/notification_webscoket.dart';

import 'firebase_options.dart';
import 'package:taxglide/router/router.dart';
import 'package:taxglide/services/notification_service.dart';

final GlobalKey<ScaffoldMessengerState> rootScaffoldMessengerKey =
    GlobalKey<ScaffoldMessengerState>();

/// ---------------------------------------------------------------------------
/// 🚨 BACKGROUND HANDLER - Must be top-level function (outside main)
/// This handles notifications when app is CLOSED/TERMINATED
/// ---------------------------------------------------------------------------
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  debugPrint("📩 Background Notification Received!");
}

Future<void> main() async {
  try {
    WidgetsFlutterBinding.ensureInitialized();

    // 1. Initialize Firebase first (required)
    debugPrint("🔥 Initializing Firebase...");
    await Firebase.initializeApp(
      options: DefaultFirebaseOptions.currentPlatform,
    );
    debugPrint("✅ Firebase Initialized");

    // ✅ Register background handler as early as possible
    FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

    // 2. Fetch initial FCM message (terminated → tapped notification)
    RemoteMessage? initialMessage;
    try {
      debugPrint("📩 Fetching initial message...");
      initialMessage = await FirebaseMessaging.instance
          .getInitialMessage()
          .timeout(
            const Duration(seconds: 2),
            onTimeout: () {
              debugPrint("⚠️ Firebase getInitialMessage timed out!");
              return null;
            },
          );
      debugPrint("📥 Initial message fetched: ${initialMessage != null}");
    } catch (e) {
      debugPrint("⚠️ Could not fetch initial message: $e");
    }

    Get.put<NotificationService>(
      NotificationService(initialMessage),
      permanent: true,
    );

    // 3. Initialize local notifications plugin (must happen before runApp)
    await initLocalNotifications();

    // 4. Start the app
    debugPrint("🚀 Calling runApp...");
    runApp(const ProviderScope(child: TaxglideApp()));

    // 4. Run FCM/permission setup in background (non-blocking)
    _runBackgroundTasks();
  } catch (e, stack) {
    debugPrint("❌ CRITICAL BOOT ERROR: $e");
    debugPrint(stack.toString());
    runApp(const ProviderScope(child: TaxglideApp()));
  }
}

/// Helper to run non-critical startup tasks without blocking the UI
Future<void> _runBackgroundTasks() async {
  try {
    FirebaseMessaging messaging = FirebaseMessaging.instance;

    // Request permissions (Non-blocking)
    await messaging.requestPermission(
      alert: true,
      badge: true,
      sound: true,
      provisional: false,
    );

    // Request notification permission for Android 13+
    if (Platform.isAndroid) {
      await Permission.notification.request();
    }

    // Setup messaging (tokens, etc)
    await _setupMessaging(messaging);

    // On iOS, set alert to true – we show foreground FCM messages naturally.
    await messaging.setForegroundNotificationPresentationOptions(
      alert: true,
      badge: true,
      sound: true,
    );

    // Set up FCM foreground listener
    _setupFcmListeners();

    // Other plugins
    await _initializePlugins();

    debugPrint("✅ All background initializations complete");
  } catch (e) {
    debugPrint("⚠️ Background task failed: $e");
  }
}

void _setupFcmListeners() {
  FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
    debugPrint(
      "🔔 Foreground FCM received! Notification block: ${message.notification}",
    );
    debugPrint("🔍 Foreground FCM Data block: ${message.data}");

    // Show custom in-app notification for Android (since system doesn't show it in foreground)
    // On iOS, setForegroundNotificationPresentationOptions handles this.
    if (Platform.isAndroid) {
      // Pass a dedup tag (chat/page id) so that if the WebSocket fires for the
      // same event, the second notification replaces the first instead of
      // showing a double notification.
      final String? dedupTag =
          message.data['page_id']?.toString() ??
          message.data['chat_id']?.toString() ??
          message.data['id']?.toString();
      Get.find<NotificationService>().showForegroundNotification(
        message,
        tag: dedupTag,
      );

      // 🔄 Trigger live refresh for detail screens/badge counts
      NotificationWebSocket().triggerRefresh();
    }
  });

  // Background tap
  FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
    debugPrint("📥 Notification tapped from background!");
    Get.find<NotificationService>().handleNavigation(message.data);
  });
}

/// ---------------------------------------------------------------------------
/// Non-blocking Messaging Setup
/// ---------------------------------------------------------------------------
Future<void> _setupMessaging(FirebaseMessaging messaging) async {
  if (Platform.isIOS) {
    debugPrint("🍎 iOS Detected: Requesting notification permissions...");
    NotificationSettings settings = await messaging.requestPermission(
      alert: true,
      badge: true,
      sound: true,
    );

    if (settings.authorizationStatus == AuthorizationStatus.authorized) {
      debugPrint("✅ User granted notification permissions");
    } else if (settings.authorizationStatus ==
        AuthorizationStatus.provisional) {
      debugPrint("✅ User granted provisional notification permissions");
    } else {
      debugPrint(
        "❌ User declined or has not accepted notification permissions",
      );
    }

    // Checking for APNS token - essential for FCM on iOS
    String? apnsToken = await messaging.getAPNSToken();

    if (apnsToken == null) {
      debugPrint("⏳ APNS Token not ready. Retrying (Max 10s)...");
      // Simulators will stay null here. Physical devices might take a few seconds.
      for (int i = 0; i < 10; i++) {
        await Future.delayed(const Duration(seconds: 1));
        apnsToken = await messaging.getAPNSToken();
        if (apnsToken != null) {
          debugPrint("✅ APNS Token received after retry");
          break;
        }
      }
    }

    if (apnsToken != null) {
      debugPrint("✅ APNS Token: $apnsToken");
    } else {
      debugPrint(
        "⚠️ APNS Token is NULL. "
        "IMPORTANT: Push notifications require a PHYSICAL DEVICE and valid Xcode Push Capability. "
        "Tokens are NOT available on Simulators.",
      );
      return;
    }
  }

  // FCM Token generation is now handled EXCLUSIVELY during OTP verification in ApiRepository.
}

/// ---------------------------------------------------------------------------
/// Plugin Initializer
/// ---------------------------------------------------------------------------
Future<void> _initializePlugins() async {
  try {
    await FilePicker.platform.clearTemporaryFiles();
    debugPrint("✅ Plugins initialized");
  } catch (e) {
    debugPrint("⚠️ Plugin init failed: $e");
  }
}

class TaxglideApp extends StatefulWidget {
  const TaxglideApp({super.key});

  @override
  State<TaxglideApp> createState() => _TaxglideAppState();
}

class _TaxglideAppState extends State<TaxglideApp> {
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Taxglide App',
      debugShowCheckedModeBanner: false,
      scaffoldMessengerKey: rootScaffoldMessengerKey,
      initialRoute: '/splash',
      getPages: AppRoutes.routes,
      theme: ThemeData(
        useMaterial3: true,
        fontFamily: 'Gilroy',
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
      ),
    );
  }
}
