import AsyncStorage from '@react-native-async-storage/async-storage';
import * as Location from 'expo-location';
import { Platform } from 'react-native';
import { API_BASE_URL, AUTH_TOKEN_KEY, USER_DATA_KEY } from '@env';

interface TrackingData {
  driverId: number;
  outId: number;
  lat: number;
  lng: number;
}

class TrackingService {
  private isTracking = false;
  private locationSubscription: Location.LocationSubscription | null = null;
  private trackingInterval: NodeJS.Timeout | null = null;
  private currentOutId: number | null = null;

  /**
   * Inicia o tracking em background
   */
  async startTracking(outId: number): Promise<void> {
    try {
      console.log('=== DEBUG: INICIANDO TRACKING ===');
      console.log('OutId recebido:', outId);
      
      if (this.isTracking) {
        console.log('⚠️ Tracking já está ativo, parando antes de reiniciar');
        await this.stopTracking();
      }

      // Verificar permissões de localização
      console.log('=== DEBUG: VERIFICANDO PERMISSÕES ===');
      const { status } = await Location.requestForegroundPermissionsAsync();
      console.log('Status da permissão:', status);

      if (status !== 'granted') {
        console.error('❌ Permissão de localização negada');
        throw new Error('Permissão de localização é necessária para o tracking');
      }

      // Verificar se o serviço de localização está ativo
      const isLocationEnabled = await Location.hasServicesEnabledAsync();
      console.log('Serviço de localização ativo:', isLocationEnabled);

      if (!isLocationEnabled) {
        console.error('❌ Serviço de localização desativado');
        throw new Error('Serviço de localização deve estar ativo');
      }

      this.currentOutId = outId;
      this.isTracking = true;

      console.log('=== DEBUG: CONFIGURANDO TRACKING ===');
      
      // Configurar opções de localização
      const locationOptions: Location.LocationOptions = {
        accuracy: Location.Accuracy.High,
        timeInterval: 10000, // 10 segundos
        distanceInterval: 10, // 10 metros
      };

      console.log('Opções de localização configuradas:', locationOptions);

      // Iniciar subscription de localização
      console.log('=== DEBUG: INICIANDO SUBSCRIPTION ===');
      this.locationSubscription = await Location.watchPositionAsync(
        locationOptions,
        this.handleLocationUpdate.bind(this)
      );

      console.log('✅ Tracking iniciado com sucesso');
      console.log('Subscription criado:', this.locationSubscription ? 'Sim' : 'Não');

    } catch (error) {
      console.error('=== DEBUG: ERRO AO INICIAR TRACKING ===');
      console.error('Erro completo:', error);
      console.error('Tipo do erro:', typeof error);
      console.error('Mensagem:', error instanceof Error ? error.message : 'Erro desconhecido');
      throw error;
    }
  }

  /**
   * Para o tracking
   */
  async stopTracking(): Promise<void> {
    try {
      console.log('=== DEBUG: PARANDO TRACKING ===');
      
      if (this.locationSubscription) {
        console.log('Removendo subscription de localização');
        this.locationSubscription.remove();
        this.locationSubscription = null;
      }

      if (this.trackingInterval) {
        console.log('Limpando intervalo de tracking');
        clearInterval(this.trackingInterval);
        this.trackingInterval = null;
      }

      this.isTracking = false;
      this.currentOutId = null;

      console.log('✅ Tracking parado com sucesso');
    } catch (error) {
      console.error('=== DEBUG: ERRO AO PARAR TRACKING ===');
      console.error('Erro:', error);
    }
  }

  /**
   * Manipula atualizações de localização
   */
  private async handleLocationUpdate(location: Location.LocationObject): Promise<void> {
    try {
      console.log('=== DEBUG: ATUALIZAÇÃO DE LOCALIZAÇÃO ===');
      console.log('Timestamp:', new Date(location.timestamp).toISOString());
      console.log('Coordenadas:', {
        latitude: location.coords.latitude,
        longitude: location.coords.longitude,
        accuracy: location.coords.accuracy,
        altitude: location.coords.altitude,
        heading: location.coords.heading,
        speed: location.coords.speed
      });

      if (!this.isTracking || !this.currentOutId) {
        console.log('⚠️ Tracking não está ativo ou outId não definido');
        return;
      }

      // Obter dados do usuário
      let userData = await this.getUserData();
      if (!userData) {
        console.log('⚠️ Dados do usuário não encontrados, aguardando 2 segundos e tentando novamente...');
        await new Promise(resolve => setTimeout(resolve, 2000));
        userData = await this.getUserData();
        
        if (!userData) {
          console.error('❌ Dados do usuário ainda não encontrados após retry');
          return;
        }
      }

      console.log('Dados do usuário:', userData);

      // Preparar payload
      const trackingData: TrackingData = {
        driverId: userData.id,
        outId: this.currentOutId,
        lat: location.coords.latitude,
        lng: location.coords.longitude
      };

      console.log('=== DEBUG: PAYLOAD DE TRACKING ===');
      console.log('Payload:', JSON.stringify(trackingData, null, 2));

      // Enviar para API
      await this.sendTrackingData(trackingData);

    } catch (error) {
      console.error('=== DEBUG: ERRO NA ATUALIZAÇÃO DE LOCALIZAÇÃO ===');
      console.error('Erro:', error);
    }
  }

  /**
   * Envia dados de tracking para a API
   */
  private async sendTrackingData(trackingData: TrackingData): Promise<void> {
    try {
      console.log('=== DEBUG: ENVIANDO DADOS DE TRACKING ===');
      
      const token = await this.getAuthToken();
      if (!token) {
        console.error('❌ Token de autenticação não encontrado');
        return;
      }

      console.log('Token obtido:', token ? 'Token existe' : 'Token não encontrado');
      console.log('API_BASE_URL:', API_BASE_URL);

      const endpoint = `${API_BASE_URL}/v1/driver/tracking/driver`;
      
      console.log('Endpoint:', endpoint);

      const headers = new Headers();
      headers.append('Authorization', `Bearer ${token}`);
      headers.append('Content-Type', 'application/json');

      console.log('Headers configurados:', Object.fromEntries(headers.entries()));

      const requestBody = JSON.stringify(trackingData);
      console.log('Body da requisição:', requestBody);

      console.log('=== DEBUG: FAZENDO REQUISIÇÃO ===');
      const response = await fetch(endpoint, {
        method: 'POST',
        headers,
        body: requestBody,
      });

      console.log('Status da resposta:', response.status);
      console.log('Headers da resposta:', Object.fromEntries(response.headers.entries()));

      const responseText = await response.text();
      console.log('Resposta bruta:', responseText);

      if (!response.ok) {
        console.error('=== DEBUG: ERRO NA RESPOSTA ===');
        console.error('Status:', response.status);
        console.error('Resposta:', responseText);
        throw new Error(`Erro ${response.status}: ${responseText}`);
      }

      let result;
      try {
        result = JSON.parse(responseText);
        console.log('Resposta parseada:', JSON.stringify(result, null, 2));
      } catch (parseError) {
        console.error('Erro ao parsear resposta:', parseError);
        return;
      }

      console.log('✅ Tracking enviado com sucesso');
      console.log('Resultado:', result);

    } catch (error) {
      console.error('=== DEBUG: ERRO AO ENVIAR TRACKING ===');
      console.error('Erro completo:', error);
      console.error('Tipo do erro:', typeof error);
      console.error('Mensagem:', error instanceof Error ? error.message : 'Erro desconhecido');
    }
  }

  /**
   * Obtém token de autenticação
   */
  private async getAuthToken(): Promise<string | null> {
    try {
      const token = await AsyncStorage.getItem(AUTH_TOKEN_KEY);
      console.log('Token carregado:', token ? 'Token existe' : 'Token não encontrado');
      return token;
    } catch (error) {
      console.error('Erro ao carregar token:', error);
      return null;
    }
  }

  /**
   * Obtém dados do usuário
   */
  private async getUserData(): Promise<any | null> {
    try {
      console.log('=== DEBUG: CARREGANDO DADOS DO USUÁRIO ===');
      const userDataString = await AsyncStorage.getItem(USER_DATA_KEY);
      console.log('String dos dados do usuário:', userDataString);
      
      if (!userDataString) {
        console.error('❌ Dados do usuário não encontrados no AsyncStorage');
        console.log('Chave usada:', USER_DATA_KEY);
        
        // Listar todas as chaves do AsyncStorage para debug
        const keys = await AsyncStorage.getAllKeys();
        console.log('Todas as chaves no AsyncStorage:', keys);
        
        return null;
      }

      const userData = JSON.parse(userDataString);
      console.log('✅ Dados do usuário carregados com sucesso:', userData);
      return userData;
    } catch (error) {
      console.error('❌ Erro ao carregar dados do usuário:', error);
      return null;
    }
  }

  /**
   * Verifica se o tracking está ativo
   */
  isTrackingActive(): boolean {
    return this.isTracking;
  }

  /**
   * Obtém o outId atual
   */
  getCurrentOutId(): number | null {
    return this.currentOutId;
  }
}

export const trackingService = new TrackingService(); 