from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path
from typing import Optional

import pandas as pd


@dataclass
class ExcelStore:
    path: Path

    sheet_salidas: str = "Salidas"
    sheet_llegadas: str = "Llegadas"

    def _read_sheet_if_exists(self, sheet_name: str) -> pd.DataFrame:
        if not self.path.exists():
            return pd.DataFrame()

        try:
            return pd.read_excel(self.path, sheet_name=sheet_name, engine="openpyxl")
        except ValueError:
            # La hoja no existe
            return pd.DataFrame()

    @staticmethod
    def _normalize_columns(df: pd.DataFrame) -> pd.DataFrame:
        # Limpieza ligera para evitar problemas de tipos
        if df is None or df.empty:
            return pd.DataFrame()

        df = df.copy()
        for col in df.columns:
            if df[col].dtype == "object":
                df[col] = df[col].astype(str).str.strip()
        return df

    @staticmethod
    def _dedupe_concat(old: pd.DataFrame, new: pd.DataFrame, key_cols: list[str]) -> pd.DataFrame:
        """
        Concatena y elimina duplicados por key_cols (mantiene el primero).
        """
        if old is None or old.empty:
            merged = new
        else:
            merged = pd.concat([old, new], ignore_index=True)

        if merged.empty:
            return merged

        # Eliminar duplicados
        merged = merged.drop_duplicates(subset=key_cols, keep="first").reset_index(drop=True)
        return merged

    def append_flights(
        self,
        salidas: pd.DataFrame,
        llegadas: pd.DataFrame,
        dedupe: bool = True,
    ) -> None:
        salidas = self._normalize_columns(salidas)
        llegadas = self._normalize_columns(llegadas)

        old_sal = self._normalize_columns(self._read_sheet_if_exists(self.sheet_salidas))
        old_lleg = self._normalize_columns(self._read_sheet_if_exists(self.sheet_llegadas))

        # Claves de deduplicación (histórico)
        # Ajusta si quieres mayor/menor agresividad.
        sal_key = ["Fecha", "Hora", "NoVuelo", "Destino", "Terminal", "Estatus", "Aerolinea"]
        lleg_key = ["Fecha", "Hora", "NoVuelo", "Origen", "Terminal", "Estatus", "Aerolinea"]

        if dedupe:
            final_sal = self._dedupe_concat(old_sal, salidas, sal_key)
            final_lleg = self._dedupe_concat(old_lleg, llegadas, lleg_key)
        else:
            final_sal = pd.concat([old_sal, salidas], ignore_index=True) if not old_sal.empty else salidas
            final_lleg = pd.concat([old_lleg, llegadas], ignore_index=True) if not old_lleg.empty else llegadas

        # Escritura: reescribe el archivo completo (forma estable con openpyxl)
        with pd.ExcelWriter(self.path, engine="openpyxl", mode="w") as writer:
            final_sal.to_excel(writer, sheet_name=self.sheet_salidas, index=False)
            final_lleg.to_excel(writer, sheet_name=self.sheet_llegadas, index=False)
