import { useState, useEffect, useRef } from 'react';
import NetInfo, { NetInfoState, NetInfoSubscription } from '@react-native-community/netinfo';

export interface MobileSignalInfo {
  isConnected: boolean;
  connectionType: 'wifi' | 'cellular' | 'none' | 'unknown';
  isMobile: boolean;
  signalStrength: number; // 0-100%
  shouldUseOffline: boolean;
  carrier?: string;
  details?: {
    cellularGeneration?: '2g' | '3g' | '4g' | '5g';
    isConnectionExpensive?: boolean;
  };
}

export const useMobileSignal = () => {
  const [signalInfo, setSignalInfo] = useState<MobileSignalInfo>({
    isConnected: false,
    connectionType: 'none',
    isMobile: false,
    signalStrength: 0,
    shouldUseOffline: false,
  });

  const netInfoSubscription = useRef<NetInfoSubscription | null>(null);

  // Função para estimar a intensidade do sinal baseada no tipo de conexão
  const estimateSignalStrength = (netInfo: NetInfoState): number => {
    if (!netInfo || !netInfo.isConnected || !netInfo.details) {
      return 0;
    }

    // Verificar se netInfo.type existe
    if (typeof netInfo.type === 'undefined') {
      console.warn('netInfo.type é undefined:', netInfo);
      return 0;
    }

    // Para conexões WiFi, usar a força do sinal se disponível
    if (netInfo.type === 'wifi' && netInfo.details.strength) {
      // Garantir que o valor esteja entre 0 e 100
      const strength = Math.round(netInfo.details.strength * 100);
      return Math.max(0, Math.min(100, strength));
    }

    // Para conexões celulares, estimar baseado na geração da rede
    if (netInfo.type === 'cellular' && netInfo.details.cellularGeneration) {
      let strength: number;
      switch (netInfo.details.cellularGeneration) {
        case '5g':
          strength = 90; // 5G geralmente tem sinal forte
          break;
        case '4g':
          strength = 75; // 4G tem sinal bom
          break;
        case '3g':
          strength = 50; // 3G tem sinal médio
          break;
        case '2g':
          strength = 25; // 2G tem sinal fraco
          break;
        default:
          strength = 60; // Padrão para conexões celulares
          break;
      }
      return Math.max(0, Math.min(100, strength));
    }

    // Para conexões celulares sem informação de geração
    if (netInfo.type === 'cellular') {
      return Math.max(0, Math.min(100, 60)); // Valor padrão para conexões celulares
    }

    // Para WiFi sem informação de força
    if (netInfo.type === 'wifi') {
      return Math.max(0, Math.min(100, 80)); // Valor padrão para WiFi
    }

    return 0;
  };

  // Função para determinar se deve usar modo offline
  const shouldUseOfflineMode = (strength: number, connectionType: string): boolean => {
    // Usar offline se:
    // 1. Sinal celular abaixo de 30%
    // 2. Sem conexão
    // 3. Conexão muito instável
    return strength < 30 || connectionType === 'none';
  };

  // Função para obter informações detalhadas da conexão
  const getConnectionDetails = (netInfo: NetInfoState) => {
    const details: any = {};

    if (netInfo.type === 'cellular' && netInfo.details) {
      details.cellularGeneration = netInfo.details.cellularGeneration;
      details.isConnectionExpensive = netInfo.details.isConnectionExpensive;
    }

    return details;
  };

  // Função para obter o nome da operadora (se disponível)
  const getCarrierName = (netInfo: NetInfoState): string | undefined => {
    if (netInfo.type === 'cellular' && netInfo.details) {
      // Em alguns dispositivos, podemos obter o nome da operadora
      // Por enquanto, retornamos undefined
      return undefined;
    }
    return undefined;
  };

  // Função para atualizar as informações de sinal
  const updateSignalInfo = (netInfo: NetInfoState) => {
    // Verificar se netInfo e netInfo.type existem
    if (!netInfo || typeof netInfo.type === 'undefined') {
      console.warn('NetInfo ou netInfo.type é undefined:', netInfo);
      return;
    }

    const signalStrength = estimateSignalStrength(netInfo);
    const shouldUseOffline = shouldUseOfflineMode(signalStrength, netInfo.type || 'none');
    const details = getConnectionDetails(netInfo);
    const carrier = getCarrierName(netInfo);

    const newSignalInfo: MobileSignalInfo = {
      isConnected: netInfo.isConnected || false,
      connectionType: (netInfo.type as any) || 'none',
      isMobile: netInfo.type === 'cellular',
      signalStrength,
      shouldUseOffline,
      carrier,
      details,
    };

    setSignalInfo(newSignalInfo);
  };

  // Função para verificar a conexão manualmente
  const checkConnection = async () => {
    try {
      const netInfo = await NetInfo.fetch();
      updateSignalInfo(netInfo);
    } catch (error) {
      // Silently fail
    }
  };

  useEffect(() => {
    // Verificar conexão inicial
    checkConnection();

    // Configurar listener para mudanças de conexão
    netInfoSubscription.current = NetInfo.addEventListener(updateSignalInfo);

    // Limpeza ao desmontar
    return () => {
      if (netInfoSubscription.current) {
        netInfoSubscription.current();
      }
    };
  }, []);

  return {
    signalInfo,
    checkConnection,
  };
}; 