import 'dart:async';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../logic/auth_provider.dart';
import '../../logic/contact_provider.dart';
import 'login_screen.dart';
import 'contacts_screen.dart';
import 'account_setup_screen.dart';
import 'key_recovery_screen.dart';
import 'chat_screen.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:chepuhagram/main.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
import 'package:chepuhagram/domain/services/crypto_service.dart';
import 'package:cryptography/cryptography.dart';
import 'package:flutter/foundation.dart';

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

  @override
  State<SplashScreen> createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  int? _targetChatId;
  String? connectError;

  // Ключ для SharedPreferences
  static const String _notificationLaunchKey = 'notification_launch_data';
  static const String _contactPublicKey = 'contact_public_key_';
  static const String _contactSharedKey = 'contact_shared_key_';

  @override
  void initState() {
    super.initState();
    print('SplashScreen initState');
    _setupNotificationHandler();
    _initializeApp();
  }

  void _setupNotificationHandler() {
    print('Setting up notification handler');
    // Обработка открытия приложения из уведомления
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      print('App opened from notification: ${message.data}');
      if (message.data['type'] == 'enc_message') {
        final senderId = int.tryParse(
          message.data['sender_id']?.toString() ?? '',
        );
        if (senderId != null) {
          setState(() {
            _targetChatId = senderId;
          });
          print('Set target chat from opened app: $senderId');
        }
      }
    });
  }

  Future<void> _initializeApp() async {
    // 1. Искусственная задержка в 2 секунды для демонстрации splash
    await Future.delayed(const Duration(seconds: 2));

    if (!mounted) return;

    // 2. Пытаемся выполнить автологин
    final authProvider = context.read<AuthProvider>();
    final isLoggedIn = await authProvider.tryAutoLogin();

    if (!mounted) return;
    bool connected = false;
    int connectAttempt = 0;
    // 3. Навигация в зависимости от результата и статуса аккаунта
    if (isLoggedIn) {
      while (!connected) {
        try {
          await authProvider.initRealtime();
          connected = true;
        } catch (e) {
          connectAttempt++;
          if (e.toString().contains('timeout')) {
            setState(() {
              connectError =
                  'Превышено время ожидания.\n Проверьте интернет соеденение.\n Попытка соеденения: $connectAttempt';
            });
          } else if (e.toString().contains('Failed host lookup')) {
            setState(() {
              connectError =
                  'Сервер недоступен. Проверьте интернет соеденение.\n Попытка соеденения: $connectAttempt';
            });
          } else {
            setState(() {
              connectError = e.toString().replaceAll('Exception: ', '');
            });
          }

          await Future.delayed(Duration(seconds: 2));
        }
      }
      await authProvider.refreshMe();

      // Определяем путь пользователя
      if (authProvider.needsSetup) {
        // Путь А: Первичная настройка
        Navigator.pushReplacement(
          context,
          MaterialPageRoute(builder: (_) => const AccountSetupScreen()),
        );
      } else if (authProvider.needsKeyRecovery) {
        // Путь В: Восстановление ключей
        Navigator.pushReplacement(
          context,
          MaterialPageRoute(builder: (_) => const KeyRecoveryScreen()),
        );
      } else {
        // Путь Б: Нормальный вход в контакты
        // Проверяем, было ли приложение запущено из уведомления
        int? targetChatId =
            _targetChatId; // Сначала проверяем из onMessageOpenedApp
        if (targetChatId == null) {
          final prefs = await SharedPreferences.getInstance();
          final savedData = prefs.getString(_notificationLaunchKey);

          try {
            final contactProvider = context.read<ContactProvider>();
            contactProvider.setCurrentUserId(authProvider.currentUserId);

            await contactProvider.loadContacts(enrichContacts: false);

            final myPrivKeyBase64 = await context
                .read<CryptoService>()
                .getPrivateKey();

            if (myPrivKeyBase64 != null) {
              final Map<int, String> keysToCompute = {};
              for (var c in contactProvider.contacts) {
                final savedKeyHex = prefs.getString(
                  '$_contactSharedKey${c.id}',
                );
                final savedPubKey = prefs.getString(
                  '$_contactPublicKey${c.id}',
                );
                if (savedKeyHex != null && savedPubKey == c.publicKey) {
                  final bytes = base64Decode(savedKeyHex);
                  contactProvider.setSharedKey(c.id, SecretKey(bytes));
                } else if (c.publicKey != null) {
                  keysToCompute[c.id] = c.publicKey!;
                }
              }
              print(
                'Contacts with keys for isolate: ${keysToCompute.keys.toList()}',
              );

              final String privKey = myPrivKeyBase64;
              final computedKeys = await compute(
                CryptoService.computeSharedKeysTask,
                {'keysMap': keysToCompute, 'privKey': privKey},
              );

              computedKeys.forEach((id, bytes) {
                contactProvider.setSharedKey(id, SecretKey(bytes));
                prefs.setString('$_contactSharedKey$id', base64Encode(bytes));
                prefs.setString('$_contactPublicKey$id', keysToCompute[id]!);
              });
            }
          } catch (e) {
            print("Ошибка при загрузке контактов или вычислении ключей: $e");
          }

          // Если не установлено, проверяем SharedPreferences

          if (savedData != null) {
            try {
              final data = jsonDecode(savedData) as Map<String, dynamic>;
              print('Found saved notification data: $data');
              final senderId = int.tryParse(
                data['sender_id']?.toString() ?? '',
              );
              final type = data['type']?.toString();

              // Поддерживаем старый payload (только sender_id) и новый (type+sender_id)
              if (senderId != null && (type == null || type == 'enc_message')) {
                targetChatId = senderId;
                print(
                  'App launched from saved notification, target chat: $targetChatId',
                );
              }

              // Очищаем сохраненные данные после использования
              await prefs.remove(_notificationLaunchKey);
            } catch (e) {
              print('Error parsing saved notification data: $e');
              await prefs.remove(_notificationLaunchKey);
            }
          }

          // Также проверяем initialMessage как fallback
          if (targetChatId == null) {
            print('Checking initialMessage: $initialMessage');
            if (initialMessage != null) {
              print('Initial message data: ${initialMessage!.data}');
              if (initialMessage!.data['type'] == 'enc_message') {
                targetChatId = int.tryParse(
                  initialMessage!.data['sender_id']?.toString() ?? '',
                );
                print('Set target chat from initialMessage: $targetChatId');
              } else {
                print(
                  'Initial message type is not enc_message: ${initialMessage!.data['type']}',
                );
              }
            } else {
              print('No initial message found');
            }
          }
        } else {
          print('Using targetChatId from onMessageOpenedApp: $targetChatId');
        }

        if (targetChatId != null) {
          print(
            'Notification targetChatId resolved: $targetChatId, trying to open chat directly',
          );
          try {
            final contactProvider = context.read<ContactProvider>();
            contactProvider.setCurrentUserId(authProvider.currentUserId);
            await contactProvider.loadContacts(enrichContacts: false);

            final contact = contactProvider.contacts.firstWhere(
              (c) => c.id == targetChatId,
            );
            currentActiveChatContactId = targetChatId;
            print(
              'Directly navigating to ChatScreen for contact: ${contact.username}',
            );

            final prefs = await SharedPreferences.getInstance();
            await prefs.remove(_notificationLaunchKey);
            Navigator.pushReplacement(
              context,
              MaterialPageRoute(builder: (_) => ChatScreen(contact: contact)),
            );
            return;
          } catch (e) {
            print(
              'Failed to open chat directly, falling back to ContactsScreen: $e',
            );
          }
        }

        print('Navigating to ContactsScreen, targetChatId: $targetChatId');

        final prefs = await SharedPreferences.getInstance();
        await prefs.remove(_notificationLaunchKey);
        Navigator.pushReplacement(
          context,
          MaterialPageRoute(
            builder: (_) => ContactsScreen(targetChatId: targetChatId),
          ),
        );
      }
    } else {
      // Нет токена - переходим на экран входа
      Navigator.pushReplacement(
        context,
        MaterialPageRoute(builder: (_) => const LoginScreen()),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Theme.of(context).colorScheme.surface,
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Spacer(),
            Icon(
              Icons.messenger_outline,
              size: 80,
              color: Theme.of(context).colorScheme.primary,
            ),
            const SizedBox(height: 24),
            Text(
              "Chepuhagram",
              style: TextStyle(
                color: Theme.of(context).colorScheme.primary,
                fontSize: 32,
                fontWeight: FontWeight.bold,
                letterSpacing: 1.2,
              ),
            ),
            const SizedBox(height: 40),
            // Мягкий индикатор загрузки снизу
            CircularProgressIndicator(
              color: Theme.of(context).colorScheme.primary,
            ),
            const SizedBox(height: 40),
            Text(
              connectError ?? '',
              style: TextStyle(
                color: Theme.of(context).colorScheme.error,
                fontSize: 14,
              ),
              textAlign: TextAlign.center,
            ),
            const Spacer(),
            Text(
              'Made by ArturKarasevich',
              style: TextStyle(
                color: Theme.of(context).colorScheme.primary,
                fontSize: 12,
              ),
            ),
            const SizedBox(height: 80),
          ],
        ),
      ),
    );
  }
}
