import 'data/datasources/ws_client.dart';
import 'logic/auth_provider.dart';
import 'logic/contact_provider.dart';
import 'core/theme_manager.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:chepuhagram/domain/services/crypto_service.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'dart:convert';
import 'package:chepuhagram/presentation/screens/chat_screen.dart';
import 'package:chepuhagram/presentation/screens/contacts_screen.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'presentation/screens/splash_screen.dart';

final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
    FlutterLocalNotificationsPlugin();
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();

int? currentActiveChatContactId;

RemoteMessage? initialMessage;

// Ключ для SharedPreferences
const String _notificationLaunchKey = 'notification_launch_data';
const String _lastHandledNotificationLaunchPayloadKey =
    'notification_last_handled_payload';

Future<void> _onSelectNotification(
  NotificationResponse notificationResponse,
) async {
  final payload = notificationResponse.payload;
  if (payload != null) {
    try {
      final data = jsonDecode(payload);
      final senderId = int.tryParse(data['sender_id']?.toString() ?? '');
      if (senderId != null) {
        print('Notification selected, payload sender_id=$senderId');

        final context = navigatorKey.currentContext;
        final prefs = await SharedPreferences.getInstance();
        final canonicalPayload = jsonEncode(data);

        if (context == null) {
          final lastHandled = prefs.getString(
            _lastHandledNotificationLaunchPayloadKey,
          );
          if (lastHandled != canonicalPayload) {
            await prefs.setString(_notificationLaunchKey, canonicalPayload);
            await prefs.setString(
              _lastHandledNotificationLaunchPayloadKey,
              canonicalPayload,
            );
          }
          print(
            'Navigator context is null, saved notification payload to SharedPreferences',
          );
        } else {
          await prefs.remove(_notificationLaunchKey);
        }

        _navigateToChat(senderId);
      } else {
        print(
          'Notification payload has invalid sender_id: ${data['sender_id']}',
        );
      }
    } catch (e) {
      print('Error parsing notification payload: $e');
    }
  }
}

void _navigateToChat(int senderId) {
  print('Navigating to chat with senderId: $senderId');
  final context = navigatorKey.currentContext;
  if (context != null) {
    final contactProvider = Provider.of<ContactProvider>(
      context,
      listen: false,
    );

    // Check if contacts are loaded
    if (contactProvider.contacts.isEmpty) {
      print('Contacts not loaded yet, navigating to contacts screen first');
      // Navigate to contacts screen and pass the senderId to navigate to chat later
      Navigator.push(
        context,
        MaterialPageRoute(
          builder: (_) => ContactsScreen(targetChatId: senderId),
        ),
      );
      return;
    }

    try {
      final contact = contactProvider.contacts.firstWhere(
        (c) => c.id == senderId,
        orElse: () => throw Exception('Contact not found'),
      );
      print('Found contact: ${contact.username}, navigating to chat');
      currentActiveChatContactId = senderId; // Устанавливаем активный чат
      Navigator.push(
        context,
        MaterialPageRoute(builder: (_) => ChatScreen(contact: contact)),
      );
    } catch (e) {
      print(
        'Contact with id $senderId not found, navigating to contacts screen',
      );
      // Contact not found, go to contacts screen
      Navigator.push(
        context,
        MaterialPageRoute(builder: (_) => const ContactsScreen()),
      );
    }
  } else {
    print('Navigator context is null');
  }
}

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();

  await Future.delayed(const Duration(milliseconds: 500));
  initialMessage = await FirebaseMessaging.instance.getInitialMessage();
  print('Initial message from main() after delay: $initialMessage');
  // Сохраняем информацию в SharedPreferences для надежности
  final prefs = await SharedPreferences.getInstance();
  if (initialMessage != null) {
    print('App launched from notification: ${initialMessage!.data}');
    print('Message type: ${initialMessage!.data['type']}');
    print('Sender ID: ${initialMessage!.data['sender_id']}');

    final payloadString = jsonEncode(initialMessage!.data);
    final lastHandled = prefs.getString(
      _lastHandledNotificationLaunchPayloadKey,
    );
    if (lastHandled != payloadString) {
      // Сохраняем данные уведомления
      await prefs.setString(_notificationLaunchKey, payloadString);
      await prefs.setString(
        _lastHandledNotificationLaunchPayloadKey,
        payloadString,
      );
      print('Saved notification data to SharedPreferences');
    } else {
      print('InitialMessage payload already handled earlier, skipping');
    }
  } else {
    print('No initial message - app launched normally');
    // Очищаем сохраненные данные, если приложение запущено нормально
    await prefs.remove(_notificationLaunchKey);
  }

  // Initialize local notifications
  const AndroidInitializationSettings initializationSettingsAndroid =
      AndroidInitializationSettings('@mipmap/ic_launcher');
  final InitializationSettings initializationSettings = InitializationSettings(
    android: initializationSettingsAndroid,
  );
  await flutterLocalNotificationsPlugin.initialize(
    initializationSettings,
    onDidReceiveNotificationResponse: _onSelectNotification,
  );

  // Если приложение было запущено из локального уведомления, сохраним payload
  final notificationAppLaunchDetails = await flutterLocalNotificationsPlugin
      .getNotificationAppLaunchDetails();
  if (notificationAppLaunchDetails?.didNotificationLaunchApp ?? false) {
    final payload = notificationAppLaunchDetails?.notificationResponse?.payload;
    print('App launched from local notification, payload: $payload');
    if (payload != null && payload.isNotEmpty) {
      try {
        final lastHandled = prefs.getString(
          _lastHandledNotificationLaunchPayloadKey,
        );
        if (lastHandled != payload) {
          final data = jsonDecode(payload);
          await prefs.setString(_notificationLaunchKey, jsonEncode(data));
          await prefs.setString(
            _lastHandledNotificationLaunchPayloadKey,
            payload,
          );
          print('Saved local notification launch payload to SharedPreferences');
        } else {
          print('Local notification payload already handled earlier, skipping');
        }
      } catch (e) {
        print('Failed to save notification launch payload: $e');
      }
    }
  }

  // Create notification channel for Android 8+
  const AndroidNotificationChannel channel = AndroidNotificationChannel(
    'chat_id', // id
    'Messages', // title
    description: 'Chat messages notifications', // description
    importance: Importance.high,
  );

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

  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);

  runApp(
    MultiProvider(
      providers: [
        Provider(create: (_) => CryptoService()),
        Provider(create: (_) => SocketService()),
        ChangeNotifierProvider(create: (_) => AuthProvider()),
        ChangeNotifierProvider(create: (_) => ThemeProvider()),
        Provider(create: (_) => SocketService()),

        ChangeNotifierProvider(
          create: (context) => ContactProvider(context.read<CryptoService>()),
        ),
      ],
      child: const MyApp(),
    ),
  );
}

@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  print("Фоновый пуш получен: ${message.data}");
  if (message.data['type'] == 'enc_message') {
    try {
      // Initialize notifications for background
      const AndroidInitializationSettings initializationSettingsAndroid =
          AndroidInitializationSettings('@mipmap/ic_launcher');
      const InitializationSettings initializationSettings =
          InitializationSettings(android: initializationSettingsAndroid);
      await flutterLocalNotificationsPlugin.initialize(initializationSettings);

      // Create notification channel
      const AndroidNotificationChannel channel = AndroidNotificationChannel(
        'chat_id',
        'Messages',
        description: 'Chat messages notifications',
        importance: Importance.high,
      );

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

      // Try to decrypt
      String notificationText = 'New encrypted message';
      try {
        // 1. Инициализируем крипто-сервис
        final crypto = CryptoService();

        // 2. Достаем ключи (они должны быть в SecureStorage)
        final myPrivKey = await crypto.getPrivateKey();
        print('Private key retrieved: ${myPrivKey != null}');
        if (myPrivKey == null) {
          print('Private key not found, showing encrypted message');
          notificationText =
              'Encrypted message: ${message.data['content']?.substring(0, 50) ?? 'N/A'}...';
        } else {
          // 3. Расшифровываем
          final sharedSecret = await crypto.deriveSharedSecret(
            myPrivKey,
            message.data['public_key'],
          );
          final decryptedText = await crypto.decryptMessage(
            message.data['content'],
            sharedSecret,
          );
          notificationText = decryptedText;
        }
      } catch (e) {
        print('Decryption failed: $e');
        notificationText = 'Failed to decrypt: ${e.toString()}';
      }

      final senderId = int.tryParse(
        message.data['sender_id']?.toString() ?? '',
      );

      // 4. Показываем локальное уведомление
      final String groupKey = 'ru.chepuhagram.app.$senderId';

      await flutterLocalNotificationsPlugin.show(
        senderId!,
        '',
        '',
        NotificationDetails(
          android: AndroidNotificationDetails(
            'Messages',
            'Новые сообщения',
            groupKey: groupKey,
            setAsGroupSummary: true,
            importance: Importance.high,
            priority: Priority.high,
            groupAlertBehavior: GroupAlertBehavior.all,
          ),
        ),
      );
      await flutterLocalNotificationsPlugin.show(
        message.hashCode,
        message.data['username'] ?? 'Unknown',
        notificationText,
        NotificationDetails(
          android: AndroidNotificationDetails(
            'chat_id',
            'Messages',
            groupKey: groupKey,
            importance: Importance.high,
            priority: Priority.high,
            showWhen: true,
          ),
        ),
        payload: jsonEncode({
          'type': 'enc_message',
          'sender_id': message.data['sender_id'],
          'timestamp':
              message.data['timestamp'] ?? DateTime.now().toIso8601String(),
        }),
      );
      print('Notification shown successfully');
    } catch (e) {
      print('Error processing background message: $e');
    }
  } else {
    print('Message type is not enc_message: ${message.data['type']}');
  }
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    // Закрываем сокет, как только приложение сворачивается.
    if (state == AppLifecycleState.paused ||
        state == AppLifecycleState.inactive ||
        state == AppLifecycleState.detached) {
      try {
        context.read<AuthProvider>().closeRealtime();
      } catch (_) {}
      return;
    }

    // На возврате в приложение — пробуем переподключиться (если есть токен).
    if (state == AppLifecycleState.resumed) {
      try {
        context.read<AuthProvider>().initRealtime();
      } catch (_) {}
    }
  }

  @override
  Widget build(BuildContext context) {
    final themeProvider = context.watch<ThemeProvider>();
    return MaterialApp(
      title: 'Chepuhagram',
      debugShowCheckedModeBanner: false,
      themeAnimationDuration: const Duration(milliseconds: 300),
      themeAnimationCurve: Curves.easeInOut,
      theme: themeProvider.themeData,
      themeMode: themeProvider.themeMode,
      navigatorKey: navigatorKey,
      navigatorObservers: [routeObserver],

      // Начальный экран
      home: const SplashScreen(),
    );
  }
}
