from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from sqlalchemy import text
from app.database import get_db
from app.models.fournisseur import Fournisseur, MailType
from pydantic import BaseModel
from typing import Optional, List
from urllib.parse import quote

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


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

class FournisseurCreate(BaseModel):
    raison_sociale: str
    email: Optional[str] = None
    telephone: Optional[str] = None
    adresse: Optional[str] = None
    code_postal: Optional[str] = None
    ville: Optional[str] = None
    contact_nom: Optional[str] = None
    contact_poste: Optional[str] = None
    notes: Optional[str] = None

class FournisseurUpdate(FournisseurCreate):
    raison_sociale: Optional[str] = None

class MailTypeUpdate(BaseModel):
    objet: Optional[str] = None
    corps: Optional[str] = None


# ─── FOURNISSEURS CRUD ────────────────────────────────────────────────────────

@router.get("/")
def get_fournisseurs(db: Session = Depends(get_db)):
    fournisseurs = db.query(Fournisseur).order_by(Fournisseur.raison_sociale).all()
    return [_fmt(f) for f in fournisseurs]


@router.get("/{fournisseur_id}")
def get_fournisseur(fournisseur_id: int, db: Session = Depends(get_db)):
    f = db.query(Fournisseur).filter(Fournisseur.id == fournisseur_id).first()
    if not f:
        raise HTTPException(404, "Fournisseur non trouvé")
    return _fmt(f)


@router.post("/", status_code=201)
def create_fournisseur(data: FournisseurCreate, db: Session = Depends(get_db)):
    f = Fournisseur(**data.dict())
    db.add(f)
    db.commit()
    db.refresh(f)
    return _fmt(f)


@router.put("/{fournisseur_id}")
def update_fournisseur(fournisseur_id: int, data: FournisseurUpdate, db: Session = Depends(get_db)):
    f = db.query(Fournisseur).filter(Fournisseur.id == fournisseur_id).first()
    if not f:
        raise HTTPException(404, "Fournisseur non trouvé")
    for k, v in data.dict(exclude_none=True).items():
        setattr(f, k, v)
    db.commit()
    db.refresh(f)
    return _fmt(f)


@router.delete("/{fournisseur_id}")
def delete_fournisseur(fournisseur_id: int, db: Session = Depends(get_db)):
    f = db.query(Fournisseur).filter(Fournisseur.id == fournisseur_id).first()
    if not f:
        raise HTTPException(404, "Fournisseur non trouvé")
    db.delete(f)
    db.commit()
    return {"ok": True}


def _fmt(f: Fournisseur):
    return {
        "id": f.id,
        "raison_sociale": f.raison_sociale,
        "email": f.email,
        "telephone": f.telephone,
        "adresse": f.adresse,
        "code_postal": f.code_postal,
        "ville": f.ville,
        "contact_nom": f.contact_nom,
        "contact_poste": f.contact_poste,
        "notes": f.notes,
    }


# ─── ARTICLES PAR FOURNISSEUR ────────────────────────────────────────────────

@router.get("/{fournisseur_id}/articles")
def get_articles_fournisseur(fournisseur_id: int, db: Session = Depends(get_db)):
    """Retourne les articles liés à ce fournisseur (1 ou 2) avec leur statut stock"""
    rows = db.execute(text("""
        SELECT
            a.id, a.code, a.designation, a.unite, a.prix_achat_ht,
            a.stock_actuel, a.seuil_alerte, a.statut,
            CASE WHEN a.fournisseur_1_id = :fid THEN 1 ELSE 2 END as rang,
            CASE WHEN a.fournisseur_1_id = :fid THEN a.ref_fournisseur_1 ELSE a.ref_fournisseur_2 END as ref_fourn
        FROM articles a
        WHERE a.fournisseur_1_id = :fid OR a.fournisseur_2_id = :fid
        ORDER BY a.designation
    """), {"fid": fournisseur_id}).fetchall()

    return [
        {
            "id": r[0],
            "code": r[1],
            "designation": r[2],
            "unite": r[3],
            "prix_achat_ht": r[4],
            "stock_actuel": r[5],
            "seuil_alerte": r[6],
            "statut": r[7],
            "rang_fournisseur": r[8],
            "ref_fournisseur": r[9],
            "en_alerte": (r[5] or 0) <= (r[6] or 0),
        }
        for r in rows
    ]


# ─── ARTICLES EN ALERTE PAR FOURNISSEUR ──────────────────────────────────────

@router.get("/{fournisseur_id}/articles-alerte")
def get_articles_alerte(fournisseur_id: int, db: Session = Depends(get_db)):
    """Retourne uniquement les articles en rupture ou sous le seuil d'alerte"""
    rows = db.execute(text("""
        SELECT
            a.id, a.code, a.designation, a.unite, a.prix_achat_ht,
            a.stock_actuel, a.seuil_alerte,
            CASE WHEN a.fournisseur_1_id = :fid THEN a.ref_fournisseur_1 ELSE a.ref_fournisseur_2 END as ref_fourn,
            CASE WHEN a.fournisseur_1_id = :fid THEN a.delai_livraison_1 ELSE a.delai_livraison_2 END as delai
        FROM articles a
        WHERE (a.fournisseur_1_id = :fid OR a.fournisseur_2_id = :fid)
          AND (a.stock_actuel IS NULL OR a.stock_actuel <= COALESCE(a.seuil_alerte, 0))
        ORDER BY a.designation
    """), {"fid": fournisseur_id}).fetchall()

    return [
        {
            "id": r[0],
            "code": r[1],
            "designation": r[2],
            "unite": r[3],
            "prix_achat_ht": r[4],
            "stock_actuel": r[5] or 0,
            "seuil_alerte": r[6] or 0,
            "ref_fournisseur": r[7],
            "delai_livraison": r[8],
        }
        for r in rows
    ]


# ─── GÉNÉRATION MAILTO ───────────────────────────────────────────────────────

@router.post("/{fournisseur_id}/generer-mail")
def generer_mail(
    fournisseur_id: int,
    articles: List[dict],  # [{id, designation, quantite, ref_fournisseur, unite}]
    db: Session = Depends(get_db)
):
    """Génère un mailto: avec la liste des articles à commander"""
    f = db.query(Fournisseur).filter(Fournisseur.id == fournisseur_id).first()
    if not f:
        raise HTTPException(404, "Fournisseur non trouvé")
    if not f.email:
        raise HTTPException(400, "Ce fournisseur n'a pas d'email")

    # Récupérer le mail type
    mail_type = db.query(MailType).filter(MailType.id == 1).first()
    objet = mail_type.objet if mail_type else "Commande de fournitures"
    corps_template = mail_type.corps if mail_type else "Bonjour,\n\n{articles}\n\nCordialement,\n{entreprise}"

    # Récupérer le nom entreprise
    try:
        ent = db.execute(text("SELECT raison_sociale FROM entreprise WHERE id = 1")).fetchone()
        nom_entreprise = ent[0] if ent else ""
    except:
        nom_entreprise = ""

    # Construire la liste articles
    lignes_articles = []
    for a in articles:
        ref = f" (Réf. {a['ref_fournisseur']})" if a.get('ref_fournisseur') else ""
        qte = a.get('quantite', 1)
        unite = a.get('unite', '')
        lignes_articles.append(f"- {a['designation']}{ref} : {qte} {unite}")

    bloc_articles = "\n".join(lignes_articles)
    corps = corps_template.replace("{articles}", bloc_articles).replace("{entreprise}", nom_entreprise)

    mailto = f"mailto:{f.email}?subject={quote(objet)}&body={quote(corps)}"

    return {
        "mailto": mailto,
        "email": f.email,
        "objet": objet,
        "corps": corps,
    }


# ─── MAIL TYPE ───────────────────────────────────────────────────────────────

@router.get("/mail-type/get")
def get_mail_type(db: Session = Depends(get_db)):
    mt = db.query(MailType).filter(MailType.id == 1).first()
    if not mt:
        return {"objet": "Commande de fournitures", "corps": ""}
    return {"objet": mt.objet, "corps": mt.corps}


@router.put("/mail-type/update")
def update_mail_type(data: MailTypeUpdate, db: Session = Depends(get_db)):
    mt = db.query(MailType).filter(MailType.id == 1).first()
    if not mt:
        mt = MailType(id=1)
        db.add(mt)
    if data.objet is not None:
        mt.objet = data.objet
    if data.corps is not None:
        mt.corps = data.corps
    db.commit()
    return {"ok": True}
