import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
import { offlineSyncService, OfflineDelivery, SyncResult, SyncStats } from '../services/offlineSyncService';
import NetInfo from '@react-native-community/netinfo';
import { useAuth } from './AuthContext';

interface OfflineModeContextData {
  // Estados
  isInitialDataLoaded: boolean;
  isOfflineMode: boolean;
  syncStats: SyncStats | null;
  isLoading: boolean;
  error: string | null;
  forceInitialLoad: boolean; // NOVO: força sempre mostrar tela de carga
  
  // Métodos de carga inicial
  loadInitialData: () => Promise<void>;
  resetOfflineMode: () => Promise<void>;
  
  // Métodos de entrega offline
  completeDeliveryOffline: (deliveryData: {
    deliveryId: string;
    status: string;
    photos?: string[];
    signature?: string;
    notes?: string;
    completedBy: string;
  }) => Promise<void>;
  
  // Métodos de sincronização
  syncSpecificDeliveries: (deliveryIds: string[]) => Promise<SyncResult>;
  syncAllPendingDeliveries: () => Promise<SyncResult>;
  
  // Métodos utilitários
  refreshSyncStats: () => Promise<void>;
  checkConnectivity: () => Promise<boolean>;
  
  // Callback para notificar mudanças nas entregas
  onDeliveryStatusChanged?: () => void;
  registerDeliveryStatusCallback: (callback: () => void) => void;
}

const OfflineModeContext = createContext<OfflineModeContextData>({} as OfflineModeContextData);

export const useOfflineMode = () => {
  const context = useContext(OfflineModeContext);
  if (!context) {
    throw new Error('useOfflineMode deve ser usado dentro de um OfflineModeProvider');
  }
  return context;
};

export const OfflineModeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [isInitialDataLoaded, setIsInitialDataLoaded] = useState(false);
  const [isOfflineMode, setIsOfflineMode] = useState(false);
  const [syncStats, setSyncStats] = useState<SyncStats | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [forceInitialLoad, setForceInitialLoad] = useState(true); // SEMPRE true inicialmente
  const [onDeliveryStatusChanged, setOnDeliveryStatusChanged] = useState<(() => void) | undefined>(undefined);
  
  // Hook para monitorar estado de autenticação
  const { user } = useAuth();

  // CRÍTICO: Monitorar mudanças no estado de autenticação
  useEffect(() => {
    if (!user) {
      // Usuário fez logout - RESETAR TUDO
      setIsInitialDataLoaded(false);
      setForceInitialLoad(true);
      setSyncStats(null);
      setError(null);
    }
  }, [user]);

  // Verificar status inicial - SEMPRE FORÇAR CARGA INICIAL
  useEffect(() => {
    // SEMPRE forçar tela de carga inicial
    setIsInitialDataLoaded(false);
    setForceInitialLoad(true);
    
    // Limpar dados antigos do AsyncStorage
    const clearOldData = async () => {
      try {
        const { clearOldAsyncStorageData } = await import('../services/database');
        await clearOldAsyncStorageData();
      } catch (error) {
        // Silently fail
      }
    };
    
    clearOldData();
    checkInitialStatus();
    setupNetworkListener();
  }, []);

  const checkInitialStatus = async () => {
    try {
      // REGRA CRÍTICA: SEMPRE mostrar tela de carga inicial após login
      // Os dados são específicos do usuário e devem ser recarregados
      setIsInitialDataLoaded(false);
      setForceInitialLoad(true);
      
    } catch (error) {
      setError('Erro ao verificar status inicial');
      // Mesmo com erro, garantir que a tela de carga seja mostrada
      setIsInitialDataLoaded(false);
      setForceInitialLoad(true);
    }
  };

  const setupNetworkListener = () => {
    const unsubscribe = NetInfo.addEventListener(state => {
      // Verificar se state existe e tem a propriedade isConnected
      if (state && typeof state.isConnected !== 'undefined') {
        const isOnline = state.isConnected;
        setIsOfflineMode(!isOnline);
        
        if (isOnline && isInitialDataLoaded) {
          // Quando voltar online, atualizar estatísticas
          refreshSyncStats();
          
          // Processar uploads de fotos pendentes (sem await)
          import('../services/photoUploadService').then(({ photoUploadService }) => {
            photoUploadService.checkConnectivityAndProcessQueue().catch(() => {
              // Silently fail
            });
          }).catch(() => {
            // Silently fail
          });
        }
      } else {
        setIsOfflineMode(true); // Assumir offline se não conseguir determinar
      }
    });

    return unsubscribe;
  };

  const loadInitialData = async () => {
    setIsLoading(true);
    setError(null);

    try {
      
      const result = await offlineSyncService.loadInitialData();
      
      // Marcar como carregado APENAS após sucesso completo
      setIsInitialDataLoaded(true);
      setForceInitialLoad(false); // Desativar força após carregar com sucesso
      await refreshSyncStats();
      

    } catch (error) {
      // console.error('❌ Erro na carga de dados iniciais:', error);
      setError(error.message);
      // NÃO marcar como carregado se houve erro
      setIsInitialDataLoaded(false);
      setForceInitialLoad(true); // Manter força para tentar novamente
      throw error;
    } finally {
      setIsLoading(false);
    }
  };

  const resetOfflineMode = async () => {
    try {
      // console.log('=== 🔄 RESETANDO MODO OFFLINE - LIMPEZA COMPLETA ===');
      // console.log('⚠️ ATENÇÃO: Esta operação limpa TODOS os dados locais');
      
      // Resetar estados IMEDIATAMENTE
      // console.log('📝 Resetando estados do contexto...');
      setIsInitialDataLoaded(false);
      setForceInitialLoad(true); // Reativar força para próximo login
      setIsOfflineMode(false);
      setSyncStats(null);
      setIsLoading(false);
      setError(null);
      // console.log('✅ Estados do contexto resetados');
      
      // Resetar dados no banco usando o serviço offline
      // console.log('🗑️ Iniciando limpeza completa do banco de dados...');
      await offlineSyncService.resetInitialData();
      // console.log('✅ Limpeza completa do banco concluída');
      
      // console.log('=== ✅ MODO OFFLINE COMPLETAMENTE RESETADO ===');
      // console.log('🎯 Próximo login irá SEMPRE baixar dados frescos da API');
      // console.log('📊 Status final:');
      // console.log('  - isInitialDataLoaded: false');
      // console.log('  - forceInitialLoad: true');
      
    } catch (error) {
      // console.error('❌ ERRO CRÍTICO ao resetar modo offline:', error);
      // Mesmo com erro, garantir que o estado seja resetado
      setIsInitialDataLoaded(false);
      setForceInitialLoad(true);
      // console.log('🔄 Estados resetados mesmo com erro');
      throw error;
    }
  };

  const completeDeliveryOffline = async (deliveryData: {
    deliveryId: string;
    status: string;
    photos?: string[];
    signature?: string;
    notes?: string;
    completedBy: string;
  }) => {
    setIsLoading(true);
    setError(null);

    try {
      
      await offlineSyncService.completeDeliveryOffline(deliveryData);
      
      // Atualizar estatísticas
      await refreshSyncStats();
      
      // Notificar mudança no status da entrega
      if (onDeliveryStatusChanged) {
        onDeliveryStatusChanged();
      }

    } catch (error: any) {
      setError(error.message);
      throw error;
    } finally {
      setIsLoading(false);
    }
  };

  const syncSpecificDeliveries = async (deliveryIds: string[]): Promise<SyncResult> => {
    setIsLoading(true);
    setError(null);

    try {
      
      const result = await offlineSyncService.syncSpecificDeliveries(deliveryIds);
      
      // Atualizar estatísticas
      await refreshSyncStats();
      
      return result;

    } catch (error: any) {
      setError(error.message);
      throw error;
    } finally {
      setIsLoading(false);
    }
  };

  const syncAllPendingDeliveries = async (): Promise<SyncResult> => {
    setIsLoading(true);
    setError(null);

    try {
      
      const result = await offlineSyncService.syncAllPendingDeliveries();
      
      // Atualizar estatísticas
      await refreshSyncStats();
      
      return result;

    } catch (error: any) {
      setError(error.message);
      throw error;
    } finally {
      setIsLoading(false);
    }
  };

  const refreshSyncStats = async () => {
    try {
      const stats = await offlineSyncService.getSyncStats();
      setSyncStats(stats);
    } catch (error) {
      // Ignorar erro ao atualizar estatísticas
    }
  };

  const checkConnectivity = async (): Promise<boolean> => {
    try {
      return await offlineSyncService.checkConnectivity();
    } catch (error) {
      return false;
    }
  };

  // Função para registrar callback de mudança de status
  const registerDeliveryStatusCallback = useCallback((callback: () => void) => {
    setOnDeliveryStatusChanged(() => callback);
  }, []);

  return (
    <OfflineModeContext.Provider
      value={{
        isInitialDataLoaded,
        isOfflineMode,
        syncStats,
        isLoading,
        error,
        forceInitialLoad,
        loadInitialData,
        resetOfflineMode,
        completeDeliveryOffline,
        syncSpecificDeliveries,
        syncAllPendingDeliveries,
        refreshSyncStats,
        checkConnectivity,
        onDeliveryStatusChanged,
        registerDeliveryStatusCallback,
      }}
    >
      {children}
    </OfflineModeContext.Provider>
  );
};
