"""Regras operacionais de disponibilidade, qualificação e progressão."""

from __future__ import annotations

from datetime import date

import pandas as pd

from .utils import normalizar_texto


def piloto_disponivel(tripulante: str, data_missao: date, indisponibilidades: pd.DataFrame) -> bool:
    trip = normalizar_texto(tripulante)
    conflitos = indisponibilidades[
        (indisponibilidades["tripulante"] == trip)
        & (indisponibilidades["inicio"] <= data_missao)
        & (indisponibilidades["fim"] >= data_missao)
    ]
    return conflitos.empty


def classe_principal(qualificacao: str) -> str:
    qual = normalizar_texto(qualificacao)
    for classe in ["IN", "PO", "PB", "AL"]:
        if classe in qual.split("/"):
            return classe
        if classe in qual.split():
            return classe
    return "OUTRO"


def qualificacao_base_aeronave(tripulante: str, aeronave: str, cadastro: pd.DataFrame) -> str:
    linha = cadastro[cadastro["tripulante"] == normalizar_texto(tripulante)]
    if linha.empty:
        return "OUTRO"
    qt = [x for x in normalizar_texto(linha.iloc[0]["qt"]).split("/") if x]
    quals = [x for x in normalizar_texto(linha.iloc[0]["qualificacao"]).split("/") if x]
    if len(qt) == len(quals) and aeronave in qt:
        return classe_principal(quals[qt.index(aeronave)])
    return classe_principal(linha.iloc[0]["qualificacao"])


def subprograma_concluido(progresso: pd.DataFrame, tripulante: str, aeronave: str, subprograma: str, catalogo: pd.DataFrame) -> bool:
    necessarias = set(catalogo[(catalogo["aeronave"] == aeronave) & (catalogo["subprograma"] == subprograma)]["oi"])
    if not necessarias:
        return False
    concluidas = set(
        progresso[
            (progresso["tripulante"] == normalizar_texto(tripulante))
            & (progresso["aeronave"] == aeronave)
            & (progresso["subprograma"] == subprograma)
            & (progresso["concluida"] == True)
        ]["oi"]
    )
    return necessarias.issubset(concluidas)


def qualificacao_operacional(tripulante: str, aeronave: str, cadastro: pd.DataFrame, progresso: pd.DataFrame, catalogo: pd.DataFrame) -> str:
    rank = {"OUTRO": 0, "AL": 1, "PB": 2, "PO": 3, "IN": 4}[qualificacao_base_aeronave(tripulante, aeronave, cadastro)]
    if subprograma_concluido(progresso, tripulante, aeronave, "SPFO-1", catalogo):
        rank = max(rank, 2)
    if subprograma_concluido(progresso, tripulante, aeronave, "SPFO-2", catalogo):
        rank = max(rank, 3)
    if aeronave == "C98" and subprograma_concluido(progresso, tripulante, aeronave, "SPQE-3", catalogo):
        rank = max(rank, 4)
    if aeronave == "C97" and subprograma_concluido(progresso, tripulante, aeronave, "SPQE-4", catalogo):
        rank = max(rank, 4)
    return {0: "OUTRO", 1: "AL", 2: "PB", 3: "PO", 4: "IN"}[rank]


def concluiu_ois(progresso: pd.DataFrame, tripulante: str, aeronave: str, ois: list[str]) -> bool:
    concluidas = set(
        progresso[
            (progresso["tripulante"] == normalizar_texto(tripulante))
            & (progresso["aeronave"] == aeronave)
            & (progresso["concluida"] == True)
        ]["oi"]
    )
    return set(ois).issubset(concluidas)


def eh_instrutor_adaptado(tripulante: str, aeronave: str, cadastro: pd.DataFrame, progresso: pd.DataFrame, catalogo: pd.DataFrame) -> bool:
    trip = normalizar_texto(tripulante)
    instrutores_base = {
        "C95": {"MES", "BRI"},
        "C97": {"AEU", "MAT"},
        "C98": {"BRI", "FIA", "MDO", "SLS", "CFF"},
    }
    if trip in instrutores_base.get(aeronave, set()):
        return True
    if aeronave == "C97" and trip in {"SEI", "LPS"}:
        return concluiu_ois(progresso, trip, aeronave, ["01TL01D41", "04TL01N42"])
    if aeronave == "C98" and trip in {"MCH", "DOG"}:
        return concluiu_ois(progresso, trip, aeronave, ["01TL01D31", "04TL01N32"])
    return qualificacao_operacional(trip, aeronave, cadastro, progresso, catalogo) == "IN"


def combinar_progresso_com_historico(progresso: pd.DataFrame, historico: pd.DataFrame, catalogo: pd.DataFrame) -> pd.DataFrame:
    if historico.empty:
        return progresso
    voadas = historico[(historico["oi"] != "") & (historico["horas_voadas"] > 0)]
    if voadas.empty:
        return progresso
    hist = voadas.merge(catalogo[["aeronave", "subprograma", "oi"]].drop_duplicates(), on=["aeronave", "oi"], how="left")
    hist = hist.dropna(subset=["subprograma"])
    hist = hist[["tripulante", "aeronave", "subprograma", "oi", "horas_voadas"]].rename(columns={"horas_voadas": "horas_realizadas"})
    hist["concluida"] = True
    return pd.concat([progresso, hist], ignore_index=True).drop_duplicates(["tripulante", "aeronave", "subprograma", "oi"])
