import { Injectable } from '@angular/core';
import { Observable, of, BehaviorSubject } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';

// Interfaces
import { 
  RouteStop, 
  RouteStopsResponse, 
  RouteStopsFilters
} from '../route-stops.interface';

// Services
import { ApiClientService } from '../../../shared/services/api/api-client.service';

/**
 * 📍 RouteStopsService - Gestão de Paradas de Rotas
 * 
 * Service simplificado para carregar paradas de rotas diretamente do arquivo JSON.
 * Seguindo o mesmo padrão usado no RoutesService.
 */
@Injectable({
  providedIn: 'root'
})
export class RouteStopsService {

  private isBackendAvailable$ = new BehaviorSubject<boolean>(false);
  private routeStopsDataCache: RouteStop[] = [];
  private dataLoaded = false;

  constructor(
    private apiClient: ApiClientService,
    private httpClient: HttpClient
  ) {
    console.log('🚀 [RouteStops] Service inicializado');
    this.isBackendAvailable$.next(false);
    this.loadRouteStopsFromFile();
  }

  get isBackendAvailable(): Observable<boolean> {
    return this.isBackendAvailable$.asObservable();
  }

  get isOnline(): boolean {
    return this.isBackendAvailable$.value;
  }

  get isUsingFallback(): boolean {
    return !this.isBackendAvailable$.value;
  }

  private loadRouteStopsFromFile(): Observable<RouteStop[]> {
    if (this.dataLoaded && this.routeStopsDataCache.length > 0) {
      console.log('📁 [RouteStops] Usando cache dos dados do arquivo JSON');
      return of(this.routeStopsDataCache);
    }

    console.log('📁 [RouteStops] Carregando dados do arquivo: /assets/data/route-stops-data.json');
    
    return this.httpClient.get<RouteStop[]>('/assets/data/route-stops-data.json').pipe(
      map((data: RouteStop[]) => {
        const processedData = data.map(stop => ({
          ...stop,
          scheduledTime: new Date(stop.scheduledTime),
          actualTime: stop.actualTime ? new Date(stop.actualTime) : undefined,
          createdAt: new Date(stop.createdAt),
          updatedAt: new Date(stop.updatedAt),
          fiscalDocument: stop.fiscalDocument ? {
            ...stop.fiscalDocument,
            issueDate: new Date(stop.fiscalDocument.issueDate),
            createdAt: new Date(stop.fiscalDocument.createdAt),
            updatedAt: new Date(stop.fiscalDocument.updatedAt)
          } : undefined
        }));

        this.routeStopsDataCache = processedData;
        this.dataLoaded = true;
        
        console.log(`✅ [RouteStops] ${processedData.length} paradas carregadas do arquivo JSON!`);
        return processedData;
      }),
      catchError(error => {
        console.error('❌ [RouteStops] Erro ao carregar arquivo route-stops-data.json:', error);
        return of([]);
      })
    );
  }

  getRouteStops(filters: RouteStopsFilters): Observable<RouteStopsResponse> {
    console.log(`🔍 [RouteStops] Buscando paradas - Filtros:`, filters);

    return this.loadRouteStopsFromFile().pipe(
      map(stops => this.processRouteStopsData(stops, filters))
    );
  }

  getRouteStopById(id: string): Observable<RouteStop> {
    console.log(`🆔 [RouteStops] Buscando parada por ID: ${id}`);
    
    return this.loadRouteStopsFromFile().pipe(
      map(stops => {
        const stop = stops.find(s => s.id === id);
        if (!stop) {
          throw new Error(`Parada ${id} não encontrada`);
        }
        return stop;
      })
    );
  }

  createRouteStop(stopData: Partial<RouteStop>): Observable<RouteStop> {
    console.log('✅ [RouteStops] Simulando criação de parada:', stopData);
    
    const newStop: RouteStop = {
      id: `stop_${Date.now()}`,
      routeId: stopData.routeId || '',
      sequence: stopData.sequence || 1,
      type: stopData.type || 'delivery',
      location: stopData.location || {
        address: '',
        coordinates: { lat: 0, lng: 0 }
      },
      scheduledTime: stopData.scheduledTime || new Date(),
      status: 'pending',
      createdAt: new Date(),
      updatedAt: new Date(),
      createdBy: 'user_mock',
      ...stopData
    } as RouteStop;
    
    return of(newStop);
  }

  updateRouteStop(id: string, stopData: Partial<RouteStop>): Observable<RouteStop> {
    console.log(`✏️ [RouteStops] Simulando atualização da parada ${id}:`, stopData);
    
    return this.getRouteStopById(id).pipe(
      map(existingStop => ({
        ...existingStop,
        ...stopData,
        updatedAt: new Date()
      }))
    );
  }

  deleteRouteStop(id: string): Observable<void> {
    console.log(`❌ [RouteStops] Simulando exclusão da parada ${id}`);
    return of(void 0);
  }

  getRouteStopsStats(routeId: string): Observable<any> {
    console.log(`📊 [RouteStops] Calculando estatísticas para rota ${routeId}`);
    
    return this.loadRouteStopsFromFile().pipe(
      map(allStops => {
        const stops = allStops.filter(stop => stop.routeId === routeId);
        
        const stats = {
          totalStops: stops.length,
          completedStops: stops.filter(s => s.status === 'completed').length,
          pendingStops: stops.filter(s => s.status === 'pending').length,
          inTransitStops: stops.filter(s => s.status === 'skipped').length,
          failedStops: stops.filter(s => s.status === 'failed').length,
          completionRate: stops.length > 0 ? 
            (stops.filter(s => s.status === 'completed').length / stops.length) * 100 : 0,
          withDocuments: stops.filter(s => s.fiscalDocument).length,
          byType: {
            pickup: stops.filter(s => s.type === 'pickup').length,
            delivery: stops.filter(s => s.type === 'delivery').length,
            fuel: stops.filter(s => s.type === 'fuel').length,
            rest: stops.filter(s => s.type === 'rest').length
          },
          source: 'fallback',
          generatedAt: new Date().toISOString()
        };
        
        console.log(`📊 [RouteStops] Estatísticas da rota ${routeId}:`, stats);
        return stats;
      })
    );
  }

  private processRouteStopsData(
    stops: RouteStop[], 
    filters: RouteStopsFilters
  ): RouteStopsResponse {
    
    let filteredStops = [...stops];

    if (filters.routeId) {
      console.log(`🔍 [RouteStops] Filtrando por routeId: ${filters.routeId}`);
      filteredStops = filteredStops.filter(stop => stop.routeId === filters.routeId);
    }

    if (filters.type?.length) {
      filteredStops = filteredStops.filter(stop => filters.type!.includes(stop.type));
    }

    if (filters.status?.length) {
      filteredStops = filteredStops.filter(stop => filters.status!.includes(stop.status));
    }

    if (filters.city) {
      filteredStops = filteredStops.filter(stop => 
        stop.location.city?.toLowerCase().includes(filters.city!.toLowerCase())
      );
    }

    if (filters.state) {
      filteredStops = filteredStops.filter(stop => 
        stop.location.state?.toLowerCase().includes(filters.state!.toLowerCase())
      );
    }

    if (filters.hasDocument !== undefined) {
      filteredStops = filteredStops.filter(stop => 
        filters.hasDocument ? !!stop.fiscalDocument : !stop.fiscalDocument
      );
    }

    if (filters.documentType?.length) {
      filteredStops = filteredStops.filter(stop => 
        stop.fiscalDocument && filters.documentType!.includes(stop.fiscalDocument.documentType)
      );
    }

    filteredStops.sort((a, b) => {
      if (a.routeId !== b.routeId) {
        return a.routeId.localeCompare(b.routeId);
      }
      return a.sequence - b.sequence;
    });

    const page = filters.page || 1;
    const limit = filters.limit || 10;
    const startIndex = (page - 1) * limit;
    const endIndex = startIndex + limit;
    const paginatedStops = filteredStops.slice(startIndex, endIndex);

    const totalPages = Math.ceil(filteredStops.length / limit);

    console.log(`📊 [RouteStops] Resultado: ${paginatedStops.length}/${filteredStops.length} paradas (página ${page}/${totalPages})`);

    return {
      data: paginatedStops,
      pagination: {
        total: filteredStops.length,
        page: page,
        limit: limit,
        totalPages: totalPages
      },
      source: 'fallback',
      timestamp: new Date().toISOString()
    };
  }

  forceReloadFromFile(): void {
    console.log('🔄 [RouteStops] Forçando recarga dos dados do arquivo...');
    this.routeStopsDataCache = [];
    this.dataLoaded = false;
    
    this.loadRouteStopsFromFile().subscribe(stops => {
      console.log(`✅ [RouteStops] ${stops.length} paradas recarregadas do arquivo!`);
    });
  }

  clearCache(): void {
    this.routeStopsDataCache = [];
    this.dataLoaded = false;
    console.log('🧹 [RouteStops] Cache limpo');
  }
}
