import json
import pandas as pd
from vincenty import vincenty
import sys
import os

# Ensure src module is visible if run standalone
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))

from src.fleet_assignment.config import (
    CSV_FILEPATH, JSON_AEROPORTOS, JSON_EMISSORES, AIRCRAFT_CONFIG
)

def load_data():
    """Reads raw CSV and JSON to build the baseline demand and fleet dataframes."""
    df = pd.read_csv(CSV_FILEPATH, low_memory=False)
    df_airports = pd.read_json(JSON_AEROPORTOS, orient='index')
    
    # Basic Cleaning
    df.replace('NIL', 0, inplace=True)
    df = df[(df['Localidade Decolagem'] != 0) & (df['Localidade Pouso'] != 0)]
    df = df[df['Modelo'].isin(AIRCRAFT_CONFIG.keys())]
    
    df['PAX'] = pd.to_numeric(df['PAX']).fillna(0)
    df['Dep TimeStamp'] = pd.to_datetime(df['Data de Decolagem'].astype(str) + ' ' + df['Hora de Decolagem'].astype(str), format='mixed', dayfirst=True, errors='coerce')
    df['Data Apenas'] = df['Dep TimeStamp'].dt.date
    df['Combustível'] = pd.to_numeric(df['Combustível'], errors='coerce').fillna(0)
    
    # Merge Coordinates
    df = df.merge(df_airports[['lat', 'lon']], left_on='Localidade Decolagem', right_index=True, how='left')
    df.rename(columns={'lat': 'lat_dep', 'lon': 'lon_dep'}, inplace=True)
    df = df.merge(df_airports[['lat', 'lon']], left_on='Localidade Pouso', right_index=True, how='left')
    df.rename(columns={'lat': 'lat_arr', 'lon': 'lon_arr'}, inplace=True)
    
    # Distance & Time Computations
    def calc_dist(row):
        if pd.isna(row['lat_dep']) or pd.isna(row['lat_arr']): return 0.0
        return vincenty((row['lat_dep'], row['lon_dep']), (row['lat_arr'], row['lon_arr']))
        
    df['Distancia'] = df.apply(calc_dist, axis=1)
    df['Tempo de Voo'] = pd.to_timedelta(df['Tempo de Voo'].astype(str), errors='coerce')
    df['Tempo de Voo (h)'] = df['Tempo de Voo'].dt.total_seconds() / 3600.0

    # Build Fleet Specifications
    df_fleet = df.groupby(['Modelo', 'Emissor']).agg({
        'Combustível': 'sum',
        'Distancia': 'sum',
        'Tempo de Voo (h)': 'sum',
        'Matrícula': 'nunique'
    })
    df_fleet.rename(columns={'Matrícula': 'Tamanho da Frota'}, inplace=True)
    
    df_fleet['Consumo (km/l)'] = (df_fleet['Distancia'] / df_fleet['Combustível']).replace([float('inf'), -float('inf')], 0).fillna(0)
    df_fleet['Velocidade Média (km/h)'] = (df_fleet['Distancia'] / df_fleet['Tempo de Voo (h)']).replace([float('inf'), -float('inf')], 0).fillna(0)
    
    models = df_fleet.index.get_level_values('Modelo')
    df_fleet['Capacidade'] = models.map(lambda m: AIRCRAFT_CONFIG[m]['cap'])
    df_fleet['Alcance'] = models.map(lambda m: AIRCRAFT_CONFIG[m]['range'])
    df_fleet['Diaria_Litros'] = models.map(lambda m: AIRCRAFT_CONFIG[m]['daily_fuel'])

    # Build Demands
    df_valid = df.dropna(subset=['Data Apenas']).copy()
    df_valid = df_valid[(df_valid['Localidade Decolagem'] != '0') & (df_valid['Localidade Pouso'] != '0')]
    demands_grouped = df_valid.groupby(['Data Apenas', 'Localidade Decolagem', 'Localidade Pouso'])['PAX'].sum().reset_index()
    demands = demands_grouped[demands_grouped['PAX'] > 0].copy()

    # Load External Lookups
    with open(JSON_EMISSORES, 'r') as f:
        emissores_data = json.load(f)[0]
    
    with open(JSON_AEROPORTOS, 'r') as f:
        airports_geo = json.load(f)
        
    # Validation Lists
    valid_icaos = df_airports.index.intersection(list(set(demands['Localidade Decolagem'].unique().tolist() + demands['Localidade Pouso'].unique().tolist() + list(emissores_data.values())))).tolist()
    
    return demands, df_fleet.reset_index(), valid_icaos, airports_geo
