import { Injectable } from '@angular/core';
import { Observable, map, of } from 'rxjs';
import { Papa } from 'ngx-papaparse';
import { ApiClientService } from '../../shared/services/api/api-client.service';
import { Vehicle } from './vehicle.interface';
import { PaginatedResponse } from '../../shared/interfaces/paginate.interface';
import { DomainService } from '../../shared/components/base-domain/base-domain.component';
import { VehicleLocationApiResponse } from '../../shared/components/vehicle-location-tracker/vehicle-location-tracker.component';

@Injectable({
    providedIn: 'root' 
})
export class VehiclesService implements DomainService<Vehicle> { 
    constructor(
        private apiClient: ApiClientService,
        private papa: Papa
    ) {
    }

    getVehicles(
        page = 1, 
        limit = 10, 
        filters?: {[key: string]: string}
    ): Observable<PaginatedResponse<Vehicle>> {
        
        let url = `vehicle?page=${page}&limit=${limit}`;
        
        if (filters) {
            const params = new URLSearchParams();
            
            for (const [key, value] of Object.entries(filters)) {
                if (value) {
                    params.append(key, value);
                }
            }
            
            url += `&${params.toString()}`;
        }
        
        return this.apiClient.get<PaginatedResponse<Vehicle>>(url);

    }
    getById(id: number): Observable<Vehicle> {
        return this.apiClient.get<Vehicle>(`vehicle/${id}`).pipe(
            map(response => { 
                const lastLocation = this.getVehicleLastLocationData(id)
                return {
                    ...response, 
                    locations: lastLocation 
                }
            })
        );
    }
    delete(id: string | number): Observable<void> {
        return this.apiClient.delete<void>(`vehicle/${id}`);
    }
    getEntities(page: number, pageSize: number, filters: any): Observable<{
        data: Vehicle[];
        totalCount: number;
        pageCount: number;
        currentPage: number;
    }> {
        return this.getVehicles(page, pageSize, filters).pipe(
            map(response => ({
                data: response.data,
                totalCount: response.totalCount,
                pageCount: response.pageCount,
                currentPage: response.currentPage
            }))
        );
    }
    create(data: any): Observable<Vehicle> {
        return this.apiClient.post<Vehicle>('vehicle', data);
    }
    update(id: any, data: any): Observable<Vehicle> {
        return this.apiClient.patch<Vehicle>(`vehicle/${id}`, data);
    }
    updateFromIntegration(vehicleId: number, integrationId: number, data:any): Observable<Vehicle> {
        return this.apiClient.post<Vehicle>(`vehicle/${vehicleId}/update-from-integration/${integrationId}`, data);
    }
    getVehicleLocationData(vehicleId: number, page: number = 1, limit: number = 30): Observable<PaginatedResponse<VehicleLocationApiResponse>> {
        return this.apiClient.get<PaginatedResponse<VehicleLocationApiResponse>>(`/vehicle-reading?vehicle_id=${vehicleId}&page=${page}&limit=${limit}`);
    }
    getVehicleLastLocationData(vehicleId: number): Observable<Vehicle> {
        return this.apiClient.get<Vehicle>(`/vehicle-reading/last?vehicle_id=${vehicleId}`);
    }
    // ========================================
    private addMockLocationData(vehicle: Vehicle): Vehicle {
        if (vehicle.last_latitude && vehicle.last_longitude) {
            return vehicle;
        }

        const locationMap: { [key: string]: { lat: number; lng: number; address: any } } = {
            'SERRA-ES': {
                lat: -20.1287,
                lng: -40.3084,
                address: {
                    street: 'Av. Central',
                    number: '1000',
                    neighborhood: 'Centro',
                    city: 'Serra',
                    uf: 'ES',
                    cep: '29160-001'
                }
            },
            'RIO BONITO-RJ': {
                lat: -22.7071,
                lng: -42.6273,
                address: {
                    street: 'Rua Principal',
                    number: '500',
                    neighborhood: 'Centro',
                    city: 'Rio Bonito',
                    uf: 'RJ',
                    cep: '28800-000'
                }
            },
            'CURITIBA-PR': {
                lat: -25.4284,
                lng: -49.2733,
                address: {
                    street: 'Av. Marechal Deodoro',
                    number: '2000',
                    neighborhood: 'Centro',
                    city: 'Curitiba',
                    uf: 'PR',
                    cep: '80020-320'
                }
            },
            'SAO JOSE DOS PINHAIS-PR': {
                lat: -25.5335,
                lng: -49.2063,
                address: {
                    street: 'Av. Rui Barbosa',
                    number: '1500',
                    neighborhood: 'Centro',
                    city: 'São José dos Pinhais',
                    uf: 'PR',
                    cep: '83005-410'
                }
            },
            'BELO HORIZONTE-MG': {
                lat: -19.9167,
                lng: -43.9345,
                address: {
                    street: 'Av. Afonso Pena',
                    number: '3000',
                    neighborhood: 'Centro',
                    city: 'Belo Horizonte',
                    uf: 'MG',
                    cep: '30112-000'
                }
            },
            'BARUERI-SP': {
                lat: -23.5106,
                lng: -46.8761,
                address: {
                    street: 'Av. Henriqueta Mendes Guerra',
                    number: '1000',
                    neighborhood: 'Vila Engenho Novo',
                    city: 'Barueri',
                    uf: 'SP',
                    cep: '06454-010'
                }
            },
            'SAO PAULO-SP': {
                lat: -23.5505,
                lng: -46.6333,
                address: {
                    street: 'Av. Paulista',
                    number: '1578',
                    neighborhood: 'Bela Vista',
                    city: 'São Paulo',
                    uf: 'SP',
                    cep: '01310-200'
                }
            },
            'SAO LEOPOLDO-RS': {
                lat: -29.7602,
                lng: -51.1479,
                address: {
                    street: 'Rua José do Patrocínio',
                    number: '800',
                    neighborhood: 'Centro',
                    city: 'São Leopoldo',
                    uf: 'RS',
                    cep: '93010-260'
                }
            },
            'VASSOURAS-RJ': {
                lat: -22.4025,
                lng: -43.6622,
                address: {
                    street: 'Rua Barão de Vassouras',
                    number: '200',
                    neighborhood: 'Centro',
                    city: 'Vassouras',
                    uf: 'RJ',
                    cep: '27700-000'
                }
            },
            'NITEROI-RJ': {
                lat: -22.8833,
                lng: -43.1036,
                address: {
                    street: 'Av. Ernani do Amaral Peixoto',
                    number: '900',
                    neighborhood: 'Centro',
                    city: 'Niterói',
                    uf: 'RJ',
                    cep: '24020-072'
                }
            },
            'MAGE-RJ': {
                lat: -22.6561,
                lng: -43.0450,
                address: {
                    street: 'Rua Dr. Sá Earp',
                    number: '300',
                    neighborhood: 'Centro',
                    city: 'Magé',
                    uf: 'RJ',
                    cep: '25900-000'
                }
            }
        };

        const cityKey = `${vehicle.registered_at_city}-${vehicle.registered_at_uf}`;
        const locationData = locationMap[cityKey];

        if (locationData) {
            const latVariation = (Math.random() - 0.5) * 0.01;
            const lngVariation = (Math.random() - 0.5) * 0.01;

            return {
                ...vehicle,
                last_latitude: locationData.lat + latVariation,
                last_longitude: locationData.lng + lngVariation,
                last_address_street: locationData.address.street,
                last_address_number: locationData.address.number,
                last_address_neighborhood: locationData.address.neighborhood,
                last_address_city: locationData.address.city,
                last_address_uf: locationData.address.uf,
                last_address_cep: locationData.address.cep,
                last_location_timestamp: new Date(Date.now() - Math.random() * 3600000).toISOString()
            };
        }

        const fallbackVariation = (Math.random() - 0.5) * 0.1;
        
        return {
            ...vehicle,
            last_latitude: -23.5505 + fallbackVariation,
            last_longitude: -46.6333 + fallbackVariation,
            last_address_street: 'Av. Paulista',
            last_address_number: '1000',
            last_address_neighborhood: 'Bela Vista',
            last_address_city: 'São Paulo',
            last_address_uf: 'SP',
            last_address_cep: '01310-100',
            last_location_timestamp: new Date(Date.now() - Math.random() * 3600000).toISOString()
        };
    }

} 