import 'dart:async';
import 'dart:io';
import 'dart:isolate';
import 'dart:convert';

import 'package:country_codes/country_codes.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:http/http.dart' as http;
import 'package:intl/date_symbol_data_local.dart';
import 'package:search_engine/database.dart';
import 'package:search_engine/widgets/navigation_bar.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:search_engine/services/config_service.dart';
import 'package:search_engine/controllers/notification_controller.dart';
import 'package:search_engine/services/mimir_service.dart';
import 'package:search_engine/services/live_activities_service.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';

class LandingPage extends StatefulWidget {
  final bool? changeLocale;

  const LandingPage({super.key, this.changeLocale});

  @override
  // ignore: library_private_types_in_public_api
  _LandingPageState createState() => _LandingPageState();
}

class _LandingPageState extends State<LandingPage> {
  double _updateProgress = 0.0;
  late Future<AppDatabase> _databaseFuture;
  String _updateInfo = 'downloading_data'.tr();
  final _baseUrl = dotenv.env['BASE_URL'];
  final _token = dotenv.env['TOKEN'];
  final _version = dotenv.env['VERSION'] ?? '1.0';
  // Tamaño del lote para inserción en la base de datos
  static const int _batchSize = 50;
  final _mimirService = MimirService();
  final _liveActivitiesService = LiveActivitiesService();
  String? _syncActivityId;

  @override
  void initState() {
    super.initState();
    _databaseFuture = Future.value(AppDatabase());
    _mimirService.initialize();
    // Initialize Live Activities first, then continue with fetchData
    _initLiveActivities().then((_) {
      fetchData();
    });

    // Initialize notifications
    NotificationController.initialize().then((_) {
      NotificationController.requestPermissions();
    });
  }

  @override
  void dispose() {
    _databaseFuture.then((database) => database.close());
    if (_syncActivityId != null) {
      _liveActivitiesService.endSearchActivity(_syncActivityId!);
    }
    super.dispose();
  }

  void _goHome() {
    if (mounted) {
      Navigator.of(context).pushReplacement(
          MaterialPageRoute(builder: (context) => const GlobalNavigator()));
    }
  }

  Future<void> fetchData() async {
    if (kDebugMode) print('🔄 Iniciando fetchData');

    final database = AppDatabase();
    try {
      // Check if SharedPreferences is working correctly
      if (kDebugMode) {
        try {
          final prefs = await SharedPreferences.getInstance();
          final prefsKeys = prefs.getKeys();
          print('🔑 SharedPreferences available keys: $prefsKeys');
        } catch (e) {
          print('⚠️ Cannot access SharedPreferences: $e');
        }
      }

      final locale = await getLocale();
      if (kDebugMode) print('🌍 Locale obtenido: $locale');

      var date = await getDate();
      if (kDebugMode) {
        print('📅 Fecha última sincronización: $date');
        try {
          final parsedDate = DateTime.parse(date);
          final now = DateTime.now();
          if (parsedDate.isAfter(now)) {
            print('⚠️ WARNING: Last sync date is in the future!');
            print('📅 Future date: $parsedDate, Current date: $now');
          }
        } catch (e) {
          print('⚠️ Error parsing date: $e');
        }
      }

      setState(() {
        _updateInfo = 'connecting_to_server'.tr();
        _updateProgress = 0.0;
      });

      // Create search activity only if on iOS and LiveActivities were initialized properly
      if (Platform.isIOS) {
        _syncActivityId = await _createLiveActivity(
          'sync_title'.tr(),
          'sync_in_progress'.tr(),
          '0',
        );
      }

      // Verificar conectividad de forma más rápida
      bool isConnected = false;
      try {
        final testUrl = Uri.parse('$_baseUrl/server/ping?access_token=$_token');
        final testResponse = await http.get(testUrl).timeout(
          const Duration(seconds: 3),
          onTimeout: () {
            throw TimeoutException('No se pudo conectar al servidor');
          },
        );
        isConnected = testResponse.statusCode == 200;
      } catch (e) {
        if (kDebugMode) print('❌ Error de conectividad: $e');
      }

      if (!isConnected) {
        setState(() {
          _updateInfo = 'server_unreachable'.tr();
        });
        await Future.delayed(const Duration(seconds: 1));
        database.close();
        if (_syncActivityId != null) {
          await _liveActivitiesService.endSearchActivity(_syncActivityId!);
        }
        _goHome();
        return;
      }

      // Try to get the most recent item date from server to compare
      final serverLatestDate = await _getServerLatestDate(locale);
      if (kDebugMode) {
        print('📅 Server latest date: $serverLatestDate');

        // Parse dates for comparison
        DateTime? localDate;
        DateTime? serverDate;
        try {
          localDate = DateTime.parse(date);
          if (serverLatestDate != null) {
            serverDate = DateTime.parse(serverLatestDate);
          }
        } catch (e) {
          print('⚠️ Date parsing error: $e');
        }

        // Compare dates if both are valid
        if (localDate != null && serverDate != null) {
          final difference = serverDate.difference(localDate).inDays;
          print('📊 Days difference between local and server: $difference');
          if (difference <= 0) {
            print('✅ Local date is up-to-date or ahead of server');
          } else {
            print('⚠️ Server has $difference days of newer data');
          }
        }
      }

      // Obtener el total de elementos de forma más eficiente
      final totalItems = await _getTotalItemsCount(locale, date);
      if (totalItems == 0) {
        if (kDebugMode) print('ℹ️ No hay elementos nuevos');
        setState(() {
          _updateInfo = 'no_new_data'.tr();
        });
        await Future.delayed(const Duration(seconds: 1));
        database.close();
        if (_syncActivityId != null) {
          await _liveActivitiesService.endSearchActivity(_syncActivityId!);
        }
        _goHome();
        return;
      }

      if (_syncActivityId != null &&
          Platform.isIOS &&
          _liveActivitiesService.isSupported) {
        try {
          await _liveActivitiesService.updateSearchActivity(
            activityId: _syncActivityId!,
            title: 'sync_title'.tr(),
            query: 'processing_data'.tr(),
            count: totalItems.toString(),
          );
        } catch (e) {
          if (kDebugMode) {
            print('Error updating Live Activity: $e');
          }
        }
      }

      // Inicializar contadores
      int processedItems = 0;
      int currentPage = 1;
      bool hasMoreData = true;
      final int pageSize = 50;
      DateTime? lastProcessedDate;
      // Variable para almacenar la fecha más reciente global
      DateTime? mostRecentDateGlobal;

      setState(() {
        _updateInfo = 'processing_data'.tr();
      });

      while (hasMoreData) {
        try {
          if (kDebugMode) print('📑 Procesando página $currentPage');

          // Ensure the date is properly formatted and encoded for URL
          final encodedDate = Uri.encodeComponent(date);
          if (kDebugMode) print('🔗 URL date parameter: $encodedDate');

          final url = Uri.parse(
              '$_baseUrl/items/activities_translations?sort=-activities_id.date&fields=*,activities_id.*,interventions.text&filter[languages_code][_eq]=$locale&filter[_or][0][activities_id][date_updated][_gt]=$encodedDate&filter[_or][1][activities_id][date_created][_gt]=$encodedDate&limit=$pageSize&page=$currentPage&access_token=$_token');

          final response =
              await http.get(url).timeout(const Duration(seconds: 10));
          if (response.statusCode != 200) {
            throw HttpException(
                'Error en página $currentPage: ${response.statusCode}');
          }

          final jsonResponse = jsonDecode(utf8.decode(response.bodyBytes));
          final List<dynamic> data = jsonResponse['data'] ?? [];

          if (data.isEmpty) {
            hasMoreData = false;
            continue;
          }

          // Procesar datos en un isolate
          final processedData = await compute(
            _processBatchItemsIsolate,
            data,
          );

          final List<Draft> batchMessages = processedData['messages'];
          final List<Map<String, String>> mimirDocuments =
              processedData['mimirDocuments'];

          // Guardar solo la información general en la base de datos
          if (batchMessages.isNotEmpty) {
            try {
              await database.addMessages(batchMessages);
              processedItems += batchMessages.length;

              // Guardar documentos en Mimir
              if (mimirDocuments.isNotEmpty) {
                await _mimirService.addDocuments(mimirDocuments);
              }

              // Actualizar la fecha del último registro procesado
              final firstItemDate = batchMessages.first.date;
              if (firstItemDate != null) {
                // Usar directamente la fecha del primer elemento procesado (el más reciente)
                lastProcessedDate = firstItemDate;

                // Actualizar la fecha global más reciente si es necesario
                if (mostRecentDateGlobal == null ||
                    firstItemDate.isAfter(mostRecentDateGlobal!)) {
                  mostRecentDateGlobal = firstItemDate;
                  if (kDebugMode) {
                    print(
                        '📅 Nueva fecha global más reciente: ${DateFormat('yyyy-MM-ddTHH:mm:ss').format(mostRecentDateGlobal!)}');
                  }
                }

                if (kDebugMode) {
                  print(
                      '📅 Fecha del elemento más reciente procesado: ${DateFormat('yyyy-MM-ddTHH:mm:ss').format(lastProcessedDate)}');
                }
                // Guardar fecha cada 5 lotes o al final
                if (currentPage % 5 == 0 || !hasMoreData) {
                  // Guardar la fecha más reciente global, no la del último lote procesado
                  await setDate(mostRecentDateGlobal ?? lastProcessedDate);
                }
              }

              setState(() {
                _updateProgress = processedItems / totalItems;
                _updateInfo = 'processed_items'
                    .tr(args: ['$processedItems', '$totalItems']);
              });

              if (_syncActivityId != null &&
                  Platform.isIOS &&
                  _liveActivitiesService.isSupported) {
                try {
                  await _liveActivitiesService.updateSearchActivity(
                    activityId: _syncActivityId!,
                    title: 'sync_title'.tr(),
                    query: 'processed_items'
                        .tr(args: ['$processedItems', '$totalItems']),
                    count: processedItems.toString(),
                  );
                } catch (e) {
                  if (kDebugMode) {
                    print('Error updating Live Activity: $e');
                  }
                }
              }
            } catch (e) {
              if (kDebugMode) print('❌ Error guardando lote: $e');
              // Guardar fecha en caso de error
              if (mostRecentDateGlobal != null) {
                await setDate(mostRecentDateGlobal);
              } else if (lastProcessedDate != null) {
                await setDate(lastProcessedDate);
              }
              continue;
            }
          }

          currentPage++;
        } catch (e) {
          if (kDebugMode) print('❌ Error procesando página $currentPage: $e');
          // Guardar fecha en caso de error
          if (mostRecentDateGlobal != null) {
            await setDate(mostRecentDateGlobal);
          } else if (lastProcessedDate != null) {
            await setDate(lastProcessedDate);
          }
          currentPage++;
          if (currentPage > (totalItems / pageSize) + 2) {
            hasMoreData = false;
          }
        }
      }

      if (processedItems > 0) {
        // Asegurarnos de que estamos guardando la fecha más reciente global
        final DateTime finalDate =
            mostRecentDateGlobal ?? lastProcessedDate ?? DateTime.now();
        final String formattedFinalDate =
            DateFormat('yyyy-MM-ddTHH:mm:ss').format(finalDate);

        if (kDebugMode) {
          print(
              '📅 Fecha final de procesamiento (más reciente global): $formattedFinalDate');
        }

        // Call the new function to finalize the sync process
        await _finalizeSyncProcess(
            processedItems, totalItems, mostRecentDateGlobal);
      }

      if (_syncActivityId != null &&
          Platform.isIOS &&
          _liveActivitiesService.isSupported) {
        try {
          await _liveActivitiesService.endSearchActivity(_syncActivityId!);
          _syncActivityId = null;
        } catch (e) {
          if (kDebugMode) {
            print('Error ending Live Activity: $e');
          }
        }
      }

      database.close();
      _goHome();
    } catch (e) {
      if (kDebugMode) print('❌ Error general: $e');
      setState(() {
        _updateInfo = 'sync_error'.tr();
      });

      if (_syncActivityId != null &&
          Platform.isIOS &&
          _liveActivitiesService.isSupported) {
        try {
          await _liveActivitiesService.updateSearchActivity(
            activityId: _syncActivityId!,
            title: 'sync_error'.tr(),
            query: e.toString(),
            count: '0',
          );
          await _liveActivitiesService.endSearchActivity(_syncActivityId!);
          _syncActivityId = null;
        } catch (e) {
          if (kDebugMode) {
            print('Error updating Live Activity: $e');
          }
        }
      }

      await Future.delayed(const Duration(seconds: 2));
      _goHome();
    }
  }

  // Método para obtener el total de elementos optimizado
  Future<int> _getTotalItemsCount(String locale, String date) async {
    try {
      final countUrl = Uri.parse(
          '$_baseUrl/items/activities_translations?filter[languages_code][_eq]=$locale&filter[_or][0][activities_id][date_updated][_gt]=$date&filter[_or][1][activities_id][date_created][_gt]=$date&aggregate[count]=*&access_token=$_token');

      final countResponse = await http.get(countUrl).timeout(
            const Duration(seconds: 5),
          );

      if (countResponse.statusCode == 200) {
        final countJson = jsonDecode(utf8.decode(countResponse.bodyBytes));
        if (countJson['data'] != null &&
            countJson['data'] is List &&
            countJson['data'].isNotEmpty) {
          final totalItems = countJson['data'][0]['count'] ?? 0;
          if (kDebugMode) print('📈 Total de elementos: $totalItems');
          return totalItems;
        }
      }
    } catch (e) {
      if (kDebugMode) print('⚠️ Error obteniendo total de elementos: $e');
    }
    return 0;
  }

  // Función estática para procesar lotes de elementos en un isolate
  static Future<Map<String, dynamic>> _processBatchItemsIsolate(
      List<dynamic> data) async {
    final List<Draft> batchMessages = [];
    final List<Map<String, String>> mimirDocuments = [];

    for (final item in data) {
      try {
        final draft = _processDraftItemIsolate(item);
        if (draft != null) {
          // Guardar solo la información general en la base de datos
          batchMessages.add(draft);

          // Guardar el contenido completo en Mimir
          if (draft.body != null && draft.body!.isNotEmpty) {
            mimirDocuments.add({
              'id': draft.id,
              'languages_code': draft.languagesCode,
              'content': draft.body!,
            });
          }
        }
      } catch (e) {
        if (kDebugMode) print('⚠️ Error procesando item en isolate: $e');
        continue;
      }
    }

    return {
      'messages': batchMessages,
      'mimirDocuments': mimirDocuments,
    };
  }

  // Versión estática del método _processDraftItem para usar en isolates
  static Draft? _processDraftItemIsolate(Map<String, dynamic> item) {
    final String id = _safeStringStatic(item['activities_id']?['id']);
    if (id.isEmpty) return null;

    // Manejar el caso cuando interventions está vacío
    String body = '';
    if (item['interventions'] != null &&
        item['interventions'] is List &&
        (item['interventions'] as List).isNotEmpty) {
      body = _safeStringStatic(item['interventions'][0]['text']);
    }

    return Draft(
        id: id,
        title: _safeStringStatic(item['title']),
        pdf: _safeStringStatic(item['pdf']),
        date: _parseDate(item['activities_id']?['date']),
        body: body,
        activity: item['activities_id']?['activity'] is int
            ? item['activities_id']['activity']
            : 1,
        country: _safeStringStatic(item['activities_id']?['country']),
        city: _safeStringStatic(item['activities_id']?['city']),
        thumbnail: _safeStringStatic(item['activities_id']?['thumbnail']),
        draft: item['activities_id']?['draft'] == true ? 1 : 0,
        locale: _safeStringStatic(item['languages_code']),
        languagesCode: _safeStringStatic(item['languages_code']));
  }

  // Versión estática de _safeString para usar en isolates
  static String _safeStringStatic(dynamic value) {
    if (value == null) return '';
    return value.toString();
  }

  // Versión estática del método _parseDate para usar en isolates
  static DateTime _parseDate(String? dateStr) {
    if (dateStr == null) return DateTime.now();
    try {
      return DateTime.parse(dateStr);
    } catch (e) {
      return DateTime.now();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Container(
            decoration: const BoxDecoration(
                gradient: LinearGradient(
                    colors: [Color(0xFFffffff), Color(0xFFe3ead6)],
                    begin: Alignment.topRight,
                    end: Alignment.bottomLeft)),
            child: SafeArea(
                child: Padding(
                    padding: const EdgeInsets.all(32),
                    child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Expanded(
                              child: Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: [
                                _buildTitle(),
                                _buildVersion(),
                                const SizedBox(height: 20),

                                // Mostrar información de actualización
                                AnimatedOpacity(
                                  opacity: _updateInfo.isNotEmpty ? 1.0 : 0.0,
                                  duration: const Duration(milliseconds: 300),
                                  child: Text(
                                    _updateInfo,
                                    style: const TextStyle(
                                      fontSize: 16,
                                      fontWeight: FontWeight.w500,
                                    ),
                                  ),
                                ),

                                const SizedBox(height: 8),

                                // Mostrar progreso según el estado
                                if (_updateProgress > 0 && _updateProgress < 1)
                                  // Barra de progreso determinado (cuando hay algo que procesar)
                                  Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,
                                    children: [
                                      Text(
                                        '${(_updateProgress * 100).floor()}%',
                                        style: const TextStyle(
                                          fontSize: 14,
                                          fontWeight: FontWeight.bold,
                                          color: Color(0XFF6b8e23),
                                        ),
                                      ),
                                      const SizedBox(height: 4),
                                      TweenAnimationBuilder(
                                        tween: Tween<double>(
                                            begin: 0, end: _updateProgress),
                                        duration:
                                            const Duration(milliseconds: 500),
                                        curve: Curves.easeInOut,
                                        builder: (context, value, child) {
                                          return ClipRRect(
                                            borderRadius:
                                                BorderRadius.circular(10),
                                            child: LinearProgressIndicator(
                                              value: value,
                                              color: const Color(0XFF6b8e23),
                                              backgroundColor:
                                                  const Color(0xFFe5ebd8),
                                              minHeight: 4,
                                            ),
                                          );
                                        },
                                      ),
                                    ],
                                  )
                                else if (_updateProgress == 0 &&
                                    _updateInfo.isNotEmpty)
                                  // Indicador de progreso indeterminado (durante verificaciones)
                                  ClipRRect(
                                    borderRadius: BorderRadius.circular(56),
                                    child: const LinearProgressIndicator(
                                      value: null, // Modo indeterminado
                                      color: Color(0XFF6b8e23),
                                      backgroundColor: Color(0xFFe5ebd8),
                                      minHeight: 4,
                                    ),
                                  ),
                              ])),

                          // Logo con animación sutil
                          AnimatedContainer(
                            duration: const Duration(milliseconds: 500),
                            curve: Curves.easeInOut,
                            padding: const EdgeInsets.all(24),
                            child: Center(
                              child: _buildLogo(),
                            ),
                          )
                        ])))));
  }

  Widget _buildTitle() {
    return Text('title'.tr(),
        style: const TextStyle(
            fontSize: 48,
            fontWeight: FontWeight.bold,
            color: Color(0xFF333333),
            height: 1));
  }

  Widget _buildVersion() {
    return Text('${'version'.tr()} $_version',
        style: const TextStyle(
            fontSize: 20,
            color: Color(0xFF666666),
            fontWeight: FontWeight.w300,
            letterSpacing: 0.5));
  }

  Widget _buildLogo() {
    return SvgPicture.asset('assets/svg/logo.svg',
        height: MediaQuery.of(context).size.height * 0.12,
        width: MediaQuery.of(context).size.width * 0.3,
        semanticsLabel: 'Logo LGCC');
  }

  Future<void> _showSyncNotification(String message) async {
    await NotificationController.showNotification(
      title: 'Data Sync',
      body: message,
      payload: 'sync_status',
    );
  }

  // Método para sincronizar Mimir con la base de datos en un Isolate
  Future<void> _syncMimirWithDatabase(String locale) async {
    final token = RootIsolateToken.instance;
    if (token == null) {
      throw Exception('RootIsolateToken is not initialized');
    }

    setState(() {
      _updateInfo = 'syncing_search_index'.tr();
      _updateProgress = 0.0;
    });

    // Ejecutar la sincronización en un Isolate
    final syncResult = await compute(
      _syncMimirWithDatabaseIsolate,
      [locale, token],
    );

    // Actualizar la UI con el progreso
    if (syncResult['success']) {
      setState(() {
        _updateProgress = 1.0;
        _updateInfo = 'search_index_updated'.tr();
      });
      await Future.delayed(const Duration(milliseconds: 500));
    } else {
      if (kDebugMode) {
        print('❌ Error en sincronización: ${syncResult['error']}');
      }
    }
  }

  // Función estática para ejecutar en un Isolate - Verificar estadísticas de DB y Mimir
  static Future<Map<String, dynamic>> _checkDatabaseStatsIsolate(
      List<dynamic> params) async {
    final locale = params[0] as String;
    final token = params[1] as RootIsolateToken;
    BackgroundIsolateBinaryMessenger.ensureInitialized(token);

    final database = AppDatabase();
    final mimirService = MimirService();

    try {
      final mimirCount = await mimirService.getDocumentCount();
      final dbMessages = await database.getAllMessages(locale);

      return {
        'mimirCount': mimirCount,
        'dbCount': dbMessages.length,
      };
    } catch (e) {
      if (kDebugMode) {
        print('Error en _checkDatabaseStatsIsolate: $e');
      }
      return {
        'mimirCount': 0,
        'dbCount': 0,
        'error': e.toString(),
      };
    } finally {
      database.close();
    }
  }

  // Función estática para ejecutar en un Isolate - Sincronizar Mimir con la base de datos
  static Future<Map<String, dynamic>> _syncMimirWithDatabaseIsolate(
      List<dynamic> params) async {
    final locale = params[0] as String;
    final token = params[1] as RootIsolateToken;
    BackgroundIsolateBinaryMessenger.ensureInitialized(token);

    final database = AppDatabase();
    final mimirService = MimirService();

    try {
      // Obtener todos los documentos de Mimir
      final mimirDocuments = await mimirService.getAllDocuments();
      final mimirCount = mimirDocuments.length;

      // Crear un conjunto de IDs de documentos que ya están en Mimir
      final mimirIds =
          Set<String>.from(mimirDocuments.map((doc) => doc['id'] as String));

      // Obtener todos los mensajes de la base de datos
      final messages = await database.getAllMessages(locale);
      final dbCount = messages.length;

      if (kDebugMode) {
        print('📊 Documentos en Mimir: $mimirCount');
        print('📊 Documentos en Base de Datos: $dbCount');
      }

      // Encontrar documentos que necesitan ser añadidos (en DB pero no en Mimir)
      final documentsToAdd = messages.where((draft) {
        return !mimirIds.contains(draft.id) &&
            draft.body != null &&
            draft.body!.isNotEmpty;
      }).toList();

      if (documentsToAdd.isNotEmpty) {
        if (kDebugMode) {
          print('🔄 Documentos a agregar a Mimir: ${documentsToAdd.length}');
        }

        // Preparar documentos para Mimir
        final documents = documentsToAdd.map((draft) {
          return {
            'id': draft.id,
            'languages_code': draft.languagesCode,
            'content': draft.body!,
          };
        }).toList();

        if (kDebugMode) {
          print('📝 Documentos válidos para indexar: ${documents.length}');
        }

        // Añadir documentos a Mimir en lotes
        const batchSize = 50;
        for (var i = 0; i < documents.length; i += batchSize) {
          final end = (i + batchSize < documents.length)
              ? i + batchSize
              : documents.length;
          final batch = documents.sublist(i, end);
          await mimirService.addDocuments(batch);

          if (kDebugMode) {
            print(
                '✓ Progreso de indexación: ${i + batch.length}/${documents.length}');
          }
        }

        if (kDebugMode) {
          final finalCount = await mimirService.getDocumentCount();
          print('✅ Indexación completada. Documentos en Mimir: $finalCount');
        }
      } else {
        if (kDebugMode) {
          print('✅ Mimir y Base de Datos están sincronizados');
        }
      }

      return {'success': true};
    } catch (e) {
      if (kDebugMode) {
        print('Error en _syncMimirWithDatabaseIsolate: $e');
      }
      return {
        'success': false,
        'error': e.toString(),
      };
    } finally {
      database.close();
    }
  }

  Future<String> getDate() async {
    final locale = await ConfigService.getLocale();
    try {
      // Get the stored date from ConfigService
      final storedDateStr = await ConfigService.getLastDate(locale);

      if (kDebugMode) {
        print('📅 Raw stored date: $storedDateStr');
      }

      // Default to a very old date if stored date is empty or "0"
      if (storedDateStr == '0' || storedDateStr.isEmpty) {
        const defaultDate = '2000-01-01T00:00:00';
        if (kDebugMode) {
          print('📅 Using default old date: $defaultDate');
        }
        return defaultDate;
      }

      // Check if the stored date is valid
      try {
        final storedDate = DateTime.parse(storedDateStr);
        final now = DateTime.now();

        // If the stored date is in the future, return yesterday's date instead
        if (storedDate.isAfter(now)) {
          final yesterday = now.subtract(const Duration(days: 1));
          final yesterdayStr =
              DateFormat('yyyy-MM-ddTHH:mm:ss').format(yesterday);

          if (kDebugMode) {
            print('⚠️ WARNING: Stored date ($storedDateStr) is in the future!');
            print('📅 Using yesterday\'s date instead: $yesterdayStr');
          }

          // Save the corrected date for future use
          await ConfigService.setLastDate(locale, yesterdayStr);
          return yesterdayStr;
        }

        // Date is valid and not in the future
        if (kDebugMode) {
          print('📅 Using stored date: $storedDateStr');
        }
        return storedDateStr;
      } catch (e) {
        // Invalid date format, use a very old date
        const defaultDate = '2000-01-01T00:00:00';
        if (kDebugMode) {
          print('⚠️ Error parsing date "$storedDateStr": $e');
          print('📅 Using default old date: $defaultDate');
        }
        return defaultDate;
      }
    } catch (e) {
      // Error retrieving date from ConfigService, use a very old date
      const defaultDate = '2000-01-01T00:00:00';
      if (kDebugMode) {
        print('❌ Error retrieving date: $e');
        print('📅 Using default old date: $defaultDate');
      }
      return defaultDate;
    }
  }

  Future<String> setDate([DateTime? specificDate]) async {
    // Get the current date
    final DateTime now = DateTime.now();

    // Decide which date to use:
    // 1. If specificDate is provided and not in the future, use it
    // 2. Otherwise, use the current date
    DateTime dateToUse = now;

    if (specificDate != null) {
      if (specificDate.isAfter(now)) {
        if (kDebugMode) {
          print(
              '⚠️ WARNING: Specified date (${specificDate.toIso8601String()}) is in the future!');
          print('📅 Using current date instead: ${now.toIso8601String()}');
        }
      } else {
        dateToUse = specificDate;
      }
    }

    // Format the date
    final String formattedDate =
        DateFormat('yyyy-MM-ddTHH:mm:ss').format(dateToUse);

    try {
      // Save the date
      final locale = await ConfigService.getLocale();
      await ConfigService.setLastDate(locale, formattedDate);

      if (kDebugMode) {
        print('💾 Saved date: $formattedDate for locale: $locale');
      }

      // Verify the saved date
      final savedDate = await ConfigService.getLastDate(locale);
      if (kDebugMode) {
        if (savedDate != formattedDate) {
          print(
              '⚠️ WARNING: Verification failed - expected: $formattedDate, got: $savedDate');
        } else {
          print('✅ Date verification successful: $savedDate');
        }
      }

      return formattedDate;
    } catch (e) {
      if (kDebugMode) {
        print('❌ Error saving date: $e');
      }
      return formattedDate;
    }
  }

  Future<String> getLocale() async {
    final locale = await ConfigService.getLocale();
    initializeDateFormatting(locale);
    return locale;
  }

  // Helper method to get the latest date from server
  Future<String?> _getServerLatestDate(String locale) async {
    try {
      final url = Uri.parse(
          '$_baseUrl/items/activities_translations?sort=-activities_id.date&fields=activities_id.date&filter[languages_code][_eq]=$locale&limit=1&access_token=$_token');

      final response = await http.get(url).timeout(const Duration(seconds: 5));

      if (response.statusCode == 200) {
        final jsonResponse = jsonDecode(utf8.decode(response.bodyBytes));
        final List<dynamic> data = jsonResponse['data'] ?? [];

        if (data.isNotEmpty && data[0]['activities_id'] != null) {
          return data[0]['activities_id']['date'];
        }
      }
    } catch (e) {
      if (kDebugMode) {
        print('❌ Error getting server latest date: $e');
      }
    }
    return null;
  }

  Future<void> _initLiveActivities() async {
    if (Platform.isIOS) {
      if (kDebugMode) {
        print("🔄 Initializing Live Activities service");
      }

      // If not on iOS, don't initialize LiveActivities
      // Initialize LiveActivities with the app group
      const String appGroupId = 'group.com.carpa.searchEngine.widget';
      const String urlScheme = 'searchengine://livesearch';

      if (kDebugMode) {
        print("📱 Using app group: $appGroupId");
        print("🔗 Using URL scheme: $urlScheme");
      }

      // Initialize Live Activities
      final bool isInitialized = await _liveActivitiesService.init(
        appGroupId: appGroupId,
        urlScheme: urlScheme,
      );

      // Check if the initialization was successful
      if (kDebugMode) {
        print("LiveActivities initialized: $isInitialized");
        print(
            "LiveActivities supported: ${_liveActivitiesService.isSupported}");
        print(
            "LiveActivities appGroupId: ${_liveActivitiesService.appGroupId}");
      }

      // Request permissions for notifications to ensure we can show Live Activities
      NotificationController.requestPermissions();
    }
  }

  Future<void> _finalizeSyncProcess(int processedItems, int totalItems,
      DateTime? mostRecentDateGlobal) async {
    if (processedItems > 0) {
      // Always use the current date for the final update
      final DateTime currentDate = DateTime.now();
      final String formattedCurrentDate =
          DateFormat('yyyy-MM-ddTHH:mm:ss').format(currentDate);

      if (kDebugMode) {
        print('📅 Using current date for final update: $formattedCurrentDate');
        if (mostRecentDateGlobal != null) {
          print(
              '📅 Most recent item date was: ${DateFormat('yyyy-MM-ddTHH:mm:ss').format(mostRecentDateGlobal)}');
        }
      }

      // Save the current date
      await setDate(currentDate);

      // Verify that the date was saved correctly
      final savedDate = await getDate();
      if (kDebugMode) {
        print('🔍 Verification - Current saved date: $savedDate');
        try {
          final savedDateTime = DateTime.parse(savedDate);
          final difference =
              currentDate.difference(savedDateTime).inSeconds.abs();

          if (difference > 5) {
            print(
                '⚠️ WARNING: Saved date differs from expected by $difference seconds');
            print('⚠️ Expected: $formattedCurrentDate, Got: $savedDate');
          } else {
            print('✅ Date verification successful');
          }
        } catch (e) {
          print('❌ Date verification error: $e');
        }
      }

      setState(() {
        _updateProgress = 1.0;
        _updateInfo = 'sync_complete'.tr();
      });

      if (kDebugMode) {
        print('✅ Sync completed');
        print('📊 Total documents processed: $processedItems');
      }

      // Update Live Activity to show the completion
      if (_syncActivityId != null &&
          Platform.isIOS &&
          _liveActivitiesService.isSupported) {
        try {
          // First update with sync complete message
          await _liveActivitiesService.updateSearchActivity(
            activityId: _syncActivityId!,
            title: 'sync_complete'.tr(),
            query:
                'processed_items'.tr(args: ['$processedItems', '$totalItems']),
            count: processedItems.toString(),
          );

          // Wait a moment for the update to be visible
          await Future.delayed(const Duration(seconds: 2));

          // Then end the activity
          await _liveActivitiesService.endSearchActivity(_syncActivityId!);
          _syncActivityId = null;
        } catch (e) {
          if (kDebugMode) {
            print('Error finalizing Live Activity: $e');
          }
        }
      }

      await Future.delayed(const Duration(seconds: 1));
      await _showSyncNotification(
          'processed_items'.tr(args: ['$processedItems', '$totalItems']));
    }
  }

  // Create a Live Activity with proper delay and verification
  Future<String?> _createLiveActivity(
      String title, String query, String count) async {
    if (!Platform.isIOS) return null;

    try {
      // Small delay to ensure everything is properly initialized
      await Future.delayed(const Duration(milliseconds: 500));

      // Verify the service is ready
      if (!_liveActivitiesService.isInitialized ||
          !_liveActivitiesService.isSupported) {
        if (kDebugMode) {
          print(
              'Live Activities service not ready: initialized=${_liveActivitiesService.isInitialized}, supported=${_liveActivitiesService.isSupported}');
        }
        return null;
      }

      // Verify the appGroupId is set
      if (_liveActivitiesService.appGroupId == null) {
        if (kDebugMode) {
          print('AppGroupId is null, reinitializing Live Activities...');
        }

        // Try to reinitialize
        await _liveActivitiesService.init(
            appGroupId: 'group.com.carpa.searchEngine.widget',
            urlScheme: 'lgcc');

        // Small delay after reinitialization
        await Future.delayed(const Duration(milliseconds: 300));
      }

      // Create the activity
      final activityId = await _liveActivitiesService.createSearchActivity(
        title: title,
        query: query,
        count: count,
      );

      if (kDebugMode) {
        print('Created Live Activity with ID: $activityId');
      }

      return activityId;
    } catch (e) {
      if (kDebugMode) {
        print('Error creating Live Activity: $e');
      }
      return null;
    }
  }

  // Helper method to update Live Activity safely
  Future<bool> _updateLiveActivity(
      String? activityId, String title, String query, String count) async {
    if (activityId == null || !Platform.isIOS) return false;

    try {
      // Verify the service is ready
      if (!_liveActivitiesService.isInitialized ||
          !_liveActivitiesService.isSupported) {
        if (kDebugMode) {
          print('Live Activities service not ready for update');
        }
        return false;
      }

      // Perform the update
      final success = await _liveActivitiesService.updateSearchActivity(
        activityId: activityId,
        title: title,
        query: query,
        count: count,
      );

      if (kDebugMode) {
        print('Updated Live Activity $activityId: $success');
      }

      return success;
    } catch (e) {
      if (kDebugMode) {
        print('Error updating Live Activity: $e');
      }
      return false;
    }
  }

  // Helper method to end Live Activity safely
  Future<bool> _endLiveActivity(String? activityId) async {
    if (activityId == null || !Platform.isIOS) return false;

    try {
      // Verify the service is ready
      if (!_liveActivitiesService.isInitialized ||
          !_liveActivitiesService.isSupported) {
        if (kDebugMode) {
          print('Live Activities service not ready for ending activity');
        }
        return false;
      }

      // End the activity
      final success =
          await _liveActivitiesService.endSearchActivity(activityId);

      if (kDebugMode) {
        print('Ended Live Activity $activityId: $success');
      }

      // Clear the activity ID
      if (activityId == _syncActivityId) {
        _syncActivityId = null;
      }

      return success;
    } catch (e) {
      if (kDebugMode) {
        print('Error ending Live Activity: $e');
      }
      return false;
    }
  }
}
