from fastapi import APIRouter, UploadFile, File, Form, HTTPException
from typing import List
import shutil

from api.schemas import (
    CreditEvaluationResponseV2,
    CompanyConsistencySummary,
)
from api.config import DATA_ROOT
from api.utils.storage import normalize_name

from src.app.pipeline import run_credit_pipeline

ALLOWED_TERMS = (15, 30, 45)

router = APIRouter(prefix="/credit-score", tags=["Credit Scoring"])

# ============================================================
# ENDPOINT OFICIAL — V2
# ============================================================

@router.post("/evaluate/v2", response_model=CreditEvaluationResponseV2)
def evaluate_credit_v2(
    input_company_name: str = Form(..., description="Nome da empresa"),
    input_nuit: str = Form(..., description="NUIT"),
    input_meses_atividade: int = Form(..., description="Meses de atividade"),
    faturamento_mensal: float | None = Form(None),
    valor_credito: float = Form(...),
    prazo_dias: int = Form(...),
    document_types: List[str] = Form(...),
    documents: List[UploadFile] = File(...),
):
    """
    Avaliação de crédito end-to-end:
    documentos → company_consistency_report → scoring → decisão
    """

    if prazo_dias not in ALLOWED_TERMS:
        raise HTTPException(
            status_code=422,
            detail=f"prazo_dias deve ser um de {list(ALLOWED_TERMS)}",
        )

    payload = _execute_pipeline(
        company_name=input_company_name,
        nuit=input_nuit,
        meses_atividade=input_meses_atividade,
        faturamento_mensal=faturamento_mensal,
        valor_credito=valor_credito,
        prazo_dias=prazo_dias,
        document_types=document_types,
        documents=documents,
    )

    decision = payload["decision"]
    score = payload["score"]
    risk = payload["risk"]
    documents_result = payload["documents"]
    company_consistency = payload.get("company_consistency")

    # --------------------------------------------------------
    # Extrato bancário (resumo)
    # --------------------------------------------------------
    bank_statement_summary = None
    for r in documents_result:
        bf = getattr(r, "features", {}) or {}
        if bf.get("bank_statement_features"):
            bank_statement_summary = bf["bank_statement_features"]
            break

    return CreditEvaluationResponseV2(
        score=score.score,
        risk_class=risk["risk_class"],  # ✅
        confidence=score.confidence,
        decision=decision.decision,

        approved_amount=decision.approved_amount,
        approved_term_days=decision.approved_term_days,

        company_consistency=CompanyConsistencySummary(
            status=company_consistency["status"],
            confidence_score=company_consistency["confidence_score"],
            alerts=company_consistency["alerts"],
        ) if company_consistency else None,

        reasons=decision.reasons,
        flags=decision.flags,

        recommended_max_value=risk.get("recommended_max_value"),  # ✅
        recommended_term_days=risk.get("recommended_term_days"),  # ✅

        bank_statement_summary=bank_statement_summary,
    )


# ============================================================
# FUNÇÃO INTERNA — EXECUÇÃO PADRÃO DO PIPELINE
# ============================================================

def _execute_pipeline(
    *,
    company_name: str,
    nuit: str | None,
    meses_atividade: int,
    faturamento_mensal: float | None,
    valor_credito: float,
    prazo_dias: int,
    document_types: List[str],
    documents: List[UploadFile],
) -> dict:
    """
    Responsável por:
    - validar inputs
    - guardar documentos
    - executar pipeline oficial
    """

    if len(document_types) != len(documents):
        raise HTTPException(
            status_code=400,
            detail="Cada documento deve ter um tipo correspondente",
        )

    company_dir = DATA_ROOT / normalize_name(company_name)
    company_dir.mkdir(parents=True, exist_ok=True)

    saved_paths: List[str] = []

    for doc_type, file in zip(document_types, documents):
        if not file.filename:
            continue

        doc_dir = company_dir / doc_type.lower()
        doc_dir.mkdir(parents=True, exist_ok=True)

        file_path = doc_dir / file.filename
        with open(file_path, "wb") as buffer:
            shutil.copyfileobj(file.file, buffer)

        saved_paths.append(str(file_path))

    if not saved_paths:
        raise HTTPException(
            status_code=400,
            detail="Nenhum documento válido foi submetido",
        )

    return run_credit_pipeline(
        files=saved_paths,
        input_company_name=company_name,
        input_nuit=nuit,
        input_meses_atividade=meses_atividade,
        faturamento_mensal=faturamento_mensal,
        valor_credito=valor_credito,
        prazo_dias=prazo_dias,
    )
