import 'dart:async';
import 'dart:typed_data';
import 'dart:io';

import 'package:alp_animated_splashscreen/alp_animated_splashscreen.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get/get.dart';
import 'package:nearledaily/constants/color_constants.dart';
import 'package:nearledaily/view/authentication/app_update_view.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_android/webview_flutter_android.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:new_version_plus/new_version_plus.dart';

import 'constants/api_constants.dart';
import 'controllers/account_controller/faq_controller.dart';
import 'controllers/authentication/auth_controller.dart';
import 'controllers/cart_controller/cart.dart';
import 'controllers/dashboard_controller/dashboard_controller.dart';
import 'controllers/intro_controller/intro_screen_controller.dart';
import 'controllers/order_controller/create_order_controller.dart';
import 'controllers/tenant/get_tenant.dart';
import 'controllers/tenant_controller /tenant_list.dart';
import 'helper/firebase_options.dart';
import 'service/bindings.dart';
import 'service/device_info/device_info.dart';
import 'view/home_view.dart';
import 'view/splash_view/splash_view.dart';

// -------------------------
// FIREBASE BACKGROUND HANDLER
// -------------------------
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
  FlutterLocalNotificationsPlugin();

  const AndroidInitializationSettings androidSettings =
  AndroidInitializationSettings('@mipmap/ic_launcher');

  await flutterLocalNotificationsPlugin.initialize(
    const InitializationSettings(android: androidSettings),
  );

  final androidPlugin = flutterLocalNotificationsPlugin
      .resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>();

  await androidPlugin?.createNotificationChannel(
    const AndroidNotificationChannel(
      'nearle_channel',
      'Nearle Notifications',
      importance: Importance.max,
    ),
  );

  final data = message.data;
  final title = data['title'] as String?;
  final body = data['body'] as String?;

  if (title != null && title.isNotEmpty) {
    await flutterLocalNotificationsPlugin.show(
      999,
      title,
      body?.isNotEmpty == true ? body : null,
      NotificationDetails(
        android: AndroidNotificationDetails(
          'nearle_channel',
          'Nearle Notifications',
          importance: Importance.max,
          priority: Priority.high,
          fullScreenIntent: true,
          playSound: true,
          enableVibration: true,
          largeIcon: const DrawableResourceAndroidBitmap('nearle_logo.jpeg'),
        ),
      ),
    );
  }
}

// -------------------------
// LOCAL NOTIFICATIONS SETUP
// -------------------------
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();

Future<void> _setupLocalNotifications() async {
  // Android settings
  const AndroidInitializationSettings initializationSettingsAndroid =
  AndroidInitializationSettings('@mipmap/ic_launcher');

  // iOS/macOS settings
  const DarwinInitializationSettings initializationSettingsIOS =
  DarwinInitializationSettings(
    requestSoundPermission: true,
    requestBadgePermission: true,
    requestAlertPermission: true,
  );

  // Combine all platforms
  const InitializationSettings initializationSettings = InitializationSettings(
    android: initializationSettingsAndroid,
    iOS: initializationSettingsIOS,
    macOS: initializationSettingsIOS,
  );

  await flutterLocalNotificationsPlugin.initialize(initializationSettings);

  // Android-only notification channel
  if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) {
    const AndroidNotificationChannel channel = AndroidNotificationChannel(
      'nearle_channel',
      'Nearle Notifications',
      description: 'High priority notifications',
      importance: Importance.max,
      playSound: true,
      enableVibration: true,
    );

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

// -------------------------
// ROUTE OBSERVER
// -------------------------
final RouteObserver<ModalRoute<void>> routeObserver =
RouteObserver<ModalRoute<void>>();

// -------------------------
// APP VERSION CHECK
// -------------------------
Future<void> _printAndCheckAppVersions() async {
  try {
    final PackageInfo packageInfo = await PackageInfo.fromPlatform();
    final String currentVersion = packageInfo.version;
    final String buildNumber = packageInfo.buildNumber;
    final String packageName = packageInfo.packageName;

    print("==================================================");
    print("CURRENT APP VERSION: $currentVersion");
    print("BUILD NUMBER: $buildNumber");
    print("PACKAGE NAME: $packageName");
    print("==================================================");

    final prefs = await SharedPreferences.getInstance();
    await prefs.setString('currentAppVersion', currentVersion);

    if (defaultTargetPlatform == TargetPlatform.android) {
      final newVersion = NewVersionPlus(androidId: "com.nearle.gear");
      final status = await newVersion.getVersionStatus();
      if (status != null) {
        print("PLAY STORE VERSION: ${status.storeVersion}");
        print("CAN UPDATE: ${status.canUpdate}");
        print("APP STORE LINK: ${status.appStoreLink}");
        print("==================================================");

        await prefs.setString('storeAppVersion', status.storeVersion);
        await prefs.setBool('updateAvailable', status.canUpdate);
      } else {
        print("Could not fetch Play Store version");
        await prefs.setString('storeAppVersion', 'Unknown');
      }
    }
  } catch (e) {
    print("Version check error: $e");
  }
}

// Returns true if update available
Future<bool> _checkForAppUpdate() async {
  if (defaultTargetPlatform != TargetPlatform.android) return false;

  try {
    final newVersion = NewVersionPlus(androidId: "com.nearle.gear");
    final status = await newVersion.getVersionStatus();

    if (status != null && status.canUpdate) {
      print("UPDATE DETECTED! Redirecting to AppUpdateView");
      print("Current: ${status.localVersion} → Store: ${status.storeVersion}");
      return true;
    }
  } catch (e) {
    print("Version check failed: $e");
  }
  return false;
}

// -------------------------
// HANDLE NOTIFICATION TAP
// -------------------------
void _handleMessage(RemoteMessage message) {
  print("Notification tapped: ${message.data}");
}

// -------------------------
// ANIMATED SPLASH
// -------------------------
class AnimatedSplashWithNavigation extends StatefulWidget {
  final Widget nextScreen;
  const AnimatedSplashWithNavigation({super.key, required this.nextScreen});

  @override
  State<AnimatedSplashWithNavigation> createState() =>
      _AnimatedSplashWithNavigationState();
}

class _AnimatedSplashWithNavigationState
    extends State<AnimatedSplashWithNavigation> {
  @override
  void initState() {
    super.initState();
    Future.delayed(const Duration(milliseconds: 5200), () {
      if (mounted) {
        Get.offAll(() => widget.nextScreen);
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedSplashScreen(
      logo: 'assets/images/splashimg.png',
      brandname: 'Nearle Daily',
      backgroundcolor: Colors.white,
      foregroundcolor: ColorConstants.primaryColor,
      brandnamecolor: ColorConstants.primaryColor,
    );
  }
}

// -------------------------
// MAIN ENTRY POINT
// -------------------------
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Firebase initialize with options (iOS/web safe)
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  await _printAndCheckAppVersions();
  await _setupLocalNotifications();

  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

  SystemChrome.setSystemUIOverlayStyle(
    SystemUiOverlayStyle(statusBarColor: Colors.grey[200]),
  );

  final prefs = await SharedPreferences.getInstance();
  prefs.setBool("firstTime", true);

  // -------------------------
  // NOTIFICATION PERMISSIONS & FCM TOKEN
  // -------------------------
  if (!kIsWeb) {
    if (Platform.isIOS) {
      NotificationSettings settings =
      await FirebaseMessaging.instance.requestPermission(
        alert: true,
        badge: true,
        sound: true,
      );

      if (settings.authorizationStatus == AuthorizationStatus.authorized) {
        print('User granted permission');

        // Listen for token refresh (APNs ready)
        FirebaseMessaging.instance.onTokenRefresh.listen((newToken) async {
          print('FCM Token (iOS APNs ready): $newToken');
          await prefs.setString('fcmToken', newToken);
        });

        // Optional: small delay initial attempt
        Future.delayed(const Duration(seconds: 2), () async {
          String? token = await FirebaseMessaging.instance.getToken();
          print('FCM Token initial attempt (iOS): $token');
          if (token != null) await prefs.setString('fcmToken', token);
        });
      } else {
        print('User declined notification permission');
      }
    } else {
      // Android: get token immediately
      String? token = await FirebaseMessaging.instance.getToken();
      print('FCM Token (Android): $token');
      if (token != null) await prefs.setString('fcmToken', token);
    }
  }

  // Foreground notifications
  FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
    final data = message.data;
    final title = data['title'] ?? message.notification?.title ?? 'Nearle';
    final body = data['body'] ?? message.notification?.body ?? '';

    final ByteData jpegData =
    await rootBundle.load('assets/images/nearledaily.png');
    final Uint8List jpegBytes = jpegData.buffer.asUint8List();

    await flutterLocalNotificationsPlugin.show(
      DateTime.now().millisecondsSinceEpoch ~/ 1000,
      title,
      body,
      NotificationDetails(
        android: AndroidNotificationDetails(
          'nearle_channel',
          'Nearle Notifications',
          importance: Importance.max,
          priority: Priority.high,
          fullScreenIntent: true,
          playSound: true,
          enableVibration: true,
          largeIcon: ByteArrayAndroidBitmap(jpegBytes),
        ),
        iOS: const DarwinNotificationDetails(),
      ),
    );
  });

  // Android WebView Controller
  if (defaultTargetPlatform == TargetPlatform.android) {
    final params = PlatformWebViewControllerCreationParams();
    AndroidWebViewController(params);
  }

  // API constants
  ApiConstants.tenantCustomers = ApiConstants.tenantCustomerLive;
  ApiConstants.orderedtenantCustomers = ApiConstants.orderedtenantCustomerLive;
  ApiConstants.login = ApiConstants.loginLive;

  // Controllers
  Get.put(TenantController(), permanent: true);
  Get.lazyPut(() => AuthController(), fenix: true);
  Get.lazyPut(() => DashboardController(), fenix: true);
  Get.lazyPut(() => CartController(), fenix: true);
  Get.lazyPut(() => BottomNavController(), fenix: true);
  Get.lazyPut(() => OrderedTenantController(), fenix: true);
  Get.lazyPut(() => OrderController(), fenix: true);
  Get.lazyPut(() => FaqController(), fenix: true);
  Get.lazyPut(() => IntroScreenController(), fenix: true);

  DeviceInfo deviceInfo = DeviceInfo();
  await deviceInfo.getDeviceInfo();

  await SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown,
  ]);

  final int? customerId = prefs.getInt('customerId');
  final String? contactNo = prefs.getString('contactno');
  bool updateAvailable = await _checkForAppUpdate();

  Widget nextScreen;
  if (updateAvailable) {
    nextScreen = const AppUpdateView();
  } else if (customerId != null && contactNo != null && contactNo.isNotEmpty) {
    nextScreen = BottomNavigation();
  } else {
    nextScreen = const SplashScreenView();
  }

  SystemChrome.setSystemUIOverlayStyle(
    const SystemUiOverlayStyle(
      statusBarColor: Colors.white,
      statusBarIconBrightness: Brightness.dark,
      statusBarBrightness: Brightness.light,
    ),
  );

  runApp(MyApp(startScreen: nextScreen));
}

// -------------------------
// MAIN APP
// -------------------------
class MyApp extends StatelessWidget {
  final Widget startScreen;
  const MyApp({super.key, required this.startScreen});

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Nearle Daily',
      navigatorObservers: [routeObserver],
      theme: ThemeData(
        fontFamily: 'Proxima Nova',
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      ),
      initialBinding: GlobalBinding(),
      home: AnimatedSplashWithNavigation(nextScreen: startScreen),
    );
  }
}