from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app.database import get_db
from app.models.transport import TarifTransport, ParametreCout
from pydantic import BaseModel
from typing import Optional

router = APIRouter(prefix="/api/transport", tags=["transport"])


# ─── SCHÉMAS ─────────────────────────────────────────────────────────────────

class TarifUpdate(BaseModel):
    prix_rotation: float
    majoration_convoi: Optional[float] = 1.20

class ParametreUpdate(BaseModel):
    valeur: float


# ─── TARIFS TRANSPORT ────────────────────────────────────────────────────────

@router.get("/tarifs")
def get_tarifs(db: Session = Depends(get_db)):
    tarifs = db.query(TarifTransport).order_by(TarifTransport.departement).all()
    return [
        {
            "id": t.id,
            "departement": t.departement,
            "nom_departement": t.nom_departement,
            "prix_rotation": t.prix_rotation,
            "majoration_convoi": t.majoration_convoi,
            "prix_convoi": round(t.prix_rotation * t.majoration_convoi, 2),
        }
        for t in tarifs
    ]


@router.get("/tarifs/{departement}")
def get_tarif(departement: str, db: Session = Depends(get_db)):
    # Accepte "86" ou "086" ou "8" → normalise en 2 chiffres
    dept = departement.strip().zfill(2)
    t = db.query(TarifTransport).filter(TarifTransport.departement == dept).first()
    if not t:
        raise HTTPException(status_code=404, detail=f"Département {dept} non trouvé")
    return {
        "departement": t.departement,
        "nom_departement": t.nom_departement,
        "prix_rotation": t.prix_rotation,
        "majoration_convoi": t.majoration_convoi,
        "prix_convoi": round(t.prix_rotation * t.majoration_convoi, 2),
    }


@router.put("/tarifs/{departement}")
def update_tarif(departement: str, data: TarifUpdate, db: Session = Depends(get_db)):
    dept = departement.strip().zfill(2)
    t = db.query(TarifTransport).filter(TarifTransport.departement == dept).first()
    if not t:
        raise HTTPException(status_code=404, detail=f"Département {dept} non trouvé")
    t.prix_rotation = data.prix_rotation
    t.majoration_convoi = data.majoration_convoi
    db.commit()
    db.refresh(t)
    return {
        "departement": t.departement,
        "nom_departement": t.nom_departement,
        "prix_rotation": t.prix_rotation,
        "majoration_convoi": t.majoration_convoi,
        "prix_convoi": round(t.prix_rotation * t.majoration_convoi, 2),
    }


# ─── PARAMÈTRES DE COÛT ──────────────────────────────────────────────────────

@router.get("/parametres")
def get_parametres(db: Session = Depends(get_db)):
    params = db.query(ParametreCout).all()
    return {p.cle: {"valeur": p.valeur, "unite": p.unite, "label": p.label} for p in params}


@router.put("/parametres/{cle}")
def update_parametre(cle: str, data: ParametreUpdate, db: Session = Depends(get_db)):
    p = db.query(ParametreCout).filter(ParametreCout.cle == cle).first()
    if not p:
        raise HTTPException(status_code=404, detail=f"Paramètre {cle} non trouvé")
    p.valeur = data.valeur
    db.commit()
    return {"cle": p.cle, "valeur": p.valeur, "unite": p.unite, "label": p.label}


@router.post("/parametres")
def create_parametre(data: dict, db: Session = Depends(get_db)):
    from pydantic import BaseModel
    cle = data.get("cle","").strip().lower().replace(" ","_")
    if not cle:
        raise HTTPException(status_code=400, detail="Clé manquante")
    if db.query(ParametreCout).filter(ParametreCout.cle == cle).first():
        raise HTTPException(status_code=409, detail="Clé déjà existante")
    p = ParametreCout(cle=cle, valeur=data.get("valeur",0.0), unite=data.get("unite","€/m³"), label=data.get("label",""))
    db.add(p); db.commit(); db.refresh(p)
    return {"cle": p.cle, "valeur": p.valeur, "unite": p.unite, "label": p.label}


@router.delete("/parametres/{cle}")
def delete_parametre(cle: str, db: Session = Depends(get_db)):
    p = db.query(ParametreCout).filter(ParametreCout.cle == cle).first()
    if not p:
        raise HTTPException(status_code=404, detail=f"Paramètre {cle} non trouvé")
    db.delete(p); db.commit()
    return {"deleted": cle}


# ─── CALCUL COÛT TRANSPORT POUR UN PROJET ────────────────────────────────────

@router.get("/cout-projet/{projet_id}")
def cout_transport_projet(projet_id: int, db: Session = Depends(get_db)):
    from app.models.projet import Projet, Piece

    projet = db.query(Projet).filter(Projet.id == projet_id).first()
    if not projet:
        raise HTTPException(status_code=404, detail="Projet non trouvé")

    # Déduire le département depuis le code postal
    cp = projet.code_postal_chantier or ""
    dept = cp[:2].zfill(2) if cp else None

    tarif = None
    if dept:
        tarif = db.query(TarifTransport).filter(TarifTransport.departement == dept).first()

    if not tarif:
        return {
            "projet_id": projet_id,
            "departement": dept,
            "tarif_trouve": False,
            "cout_transport": 0,
            "detail": "Aucun tarif trouvé pour ce département"
        }

    # Compter les transports normaux vs convoi
    pieces = db.query(Piece).filter(Piece.projet_id == projet_id).all()
    nb_convoi = sum(1 for p in pieces if p.convoi_exceptionnel)
    nb_normal = max(0, (projet.nb_transports or 0) - nb_convoi)

    cout_normal = nb_normal * tarif.prix_rotation
    cout_convoi = nb_convoi * tarif.prix_rotation * tarif.majoration_convoi
    cout_total = round(cout_normal + cout_convoi, 2)

    return {
        "projet_id": projet_id,
        "departement": dept,
        "nom_departement": tarif.nom_departement,
        "tarif_trouve": True,
        "nb_transports_normal": nb_normal,
        "nb_transports_convoi": nb_convoi,
        "prix_rotation": tarif.prix_rotation,
        "majoration_convoi": tarif.majoration_convoi,
        "cout_normal": round(cout_normal, 2),
        "cout_convoi": round(cout_convoi, 2),
        "cout_transport": cout_total,
    }
