"""
Routes API pour la gestion des articles
"""
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from typing import List, Optional
from app.database import get_db
from app.models import Article, MouvementStock, StatutArticle
from app.schemas.article import (
    ArticleCreate,
    ArticleUpdate,
    ArticleResponse,
    MouvementStockCreate,
    MouvementStockResponse
)

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


@router.get("/", response_model=List[ArticleResponse])
def lire_articles(
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=1000),
    categorie_id: Optional[int] = None,
    statut: Optional[StatutArticle] = None,
    recherche: Optional[str] = None,
    db: Session = Depends(get_db)
):
    """Récupère la liste des articles avec filtres optionnels"""
    query = db.query(Article)
    
    if categorie_id:
        query = query.filter(Article.categorie_id == categorie_id)
    if statut:
        query = query.filter(Article.statut == statut)
    if recherche:
        query = query.filter(
            (Article.code.ilike(f"%{recherche}%")) |
            (Article.designation.ilike(f"%{recherche}%"))
        )
    
    articles = query.offset(skip).limit(limit).all()
    return articles


@router.get("/{article_id}", response_model=ArticleResponse)
def lire_article(article_id: int, db: Session = Depends(get_db)):
    """Récupère un article spécifique par son ID"""
    article = db.query(Article).filter(Article.id == article_id).first()
    if not article:
        raise HTTPException(status_code=404, detail="Article non trouvé")
    return article


@router.post("/", response_model=ArticleResponse, status_code=201)
def creer_article(article: ArticleCreate, db: Session = Depends(get_db)):
    """Crée un nouvel article"""
    if db.query(Article).filter(Article.code == article.code).first():
        raise HTTPException(status_code=400, detail="Ce code article existe déjà")
    
    db_article = Article(
        **article.model_dump(),
        stock_actuel=article.stock_initial,
        statut=StatutArticle.NOUVEAU
    )
    
    db.add(db_article)
    db.commit()
    db.refresh(db_article)
    return db_article


@router.put("/{article_id}", response_model=ArticleResponse)
def modifier_article(
    article_id: int,
    article_update: ArticleUpdate,
    db: Session = Depends(get_db)
):
    """Modifie un article existant"""
    db_article = db.query(Article).filter(Article.id == article_id).first()
    if not db_article:
        raise HTTPException(status_code=404, detail="Article non trouvé")
    
    update_data = article_update.model_dump(exclude_unset=True)
    for field, value in update_data.items():
        setattr(db_article, field, value)
    
    db.commit()
    db.refresh(db_article)
    return db_article


@router.delete("/{article_id}", status_code=204)
def supprimer_article(article_id: int, db: Session = Depends(get_db)):
    """Supprime définitivement un article"""
    db_article = db.query(Article).filter(Article.id == article_id).first()
    if not db_article:
        raise HTTPException(status_code=404, detail="Article non trouvé")
    
    db.delete(db_article)
    db.commit()
    return None


@router.post("/mouvements", response_model=MouvementStockResponse, status_code=201)
def creer_mouvement_stock(
    mouvement: MouvementStockCreate,
    db: Session = Depends(get_db)
):
    """Crée un mouvement de stock et met à jour le récap Xbat si projet_id fourni"""
    from math import ceil
    from datetime import datetime

    article = db.query(Article).filter(Article.id == mouvement.article_id).first()
    if not article:
        raise HTTPException(status_code=404, detail="Article non trouvé")

    db_mouvement = MouvementStock(
        article_id=mouvement.article_id,
        quantite=mouvement.quantite,
        type_mouvement=mouvement.type_mouvement,
        reference=mouvement.reference,
        commentaire=mouvement.commentaire,
        projet_id=mouvement.projet_id,
        niveau_id=mouvement.niveau_id
    )
    db.add(db_mouvement)

    article.stock_actuel += mouvement.quantite

    if article.stock_actuel <= article.seuil_alerte:
        article.statut = StatutArticle.STOCK_FAIBLE
    elif article.statut == StatutArticle.STOCK_FAIBLE and article.stock_actuel > article.seuil_alerte:
        article.statut = StatutArticle.ACTIF

    db.commit()
    db.refresh(db_mouvement)
    return db_mouvement


@router.get("/{article_id}/mouvements", response_model=List[MouvementStockResponse])
def lire_mouvements_article(
    article_id: int,
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db)
):
    """Récupère l'historique des mouvements de stock d'un article"""
    mouvements = db.query(MouvementStock)\
        .filter(MouvementStock.article_id == article_id)\
        .order_by(MouvementStock.date_mouvement.desc())\
        .offset(skip).limit(limit).all()
    
    return mouvements

@router.get("/{article_id}/detail")
def lire_article_detail(article_id: int, db: Session = Depends(get_db)):
    """Récupère un article avec les noms des fournisseurs liés"""
    from app.models.fournisseur import Fournisseur
    article = db.query(Article).filter(Article.id == article_id).first()
    if not article:
        raise HTTPException(status_code=404, detail="Article non trouvé")
    
    f1 = db.query(Fournisseur).filter(Fournisseur.id == article.fournisseur_1_id).first() if article.fournisseur_1_id else None
    f2 = db.query(Fournisseur).filter(Fournisseur.id == article.fournisseur_2_id).first() if article.fournisseur_2_id else None

    return {
        "id": article.id,
        "code": article.code,
        "designation": article.designation,
        "categorie_id": article.categorie_id,
        "prix_achat_ht": article.prix_achat_ht,
        "unite": article.unite,
        "stock_actuel": article.stock_actuel,
        "stock_initial": article.stock_initial,
        "seuil_alerte": article.seuil_alerte,
        "statut": article.statut,
        "taux_perte": article.taux_perte,
        "description": article.description,
        "fournisseur_1_id": article.fournisseur_1_id,
        "fournisseur_1_nom": f1.raison_sociale if f1 else None,
        "fournisseur_2_id": article.fournisseur_2_id,
        "fournisseur_2_nom": f2.raison_sociale if f2 else None,
        "ref_fournisseur_1": article.ref_fournisseur_1,
        "ref_fournisseur_2": article.ref_fournisseur_2,
        "delai_livraison_1": getattr(article, 'delai_livraison_1', None),
        "delai_livraison_2": getattr(article, 'delai_livraison_2', None),
    }


@router.get("/liste/avec-fournisseurs")
def lire_articles_avec_fournisseurs(
    categorie_id: Optional[int] = None,
    db: Session = Depends(get_db)
):
    """Récupère tous les articles avec les noms des fournisseurs"""
    from app.models.fournisseur import Fournisseur
    query = db.query(Article)
    if categorie_id:
        query = query.filter(Article.categorie_id == categorie_id)
    articles = query.all()

    fournisseurs = {f.id: f.raison_sociale for f in db.query(Fournisseur).all()}

    result = []
    for a in articles:
        result.append({
            "id": a.id,
            "code": a.code,
            "designation": a.designation,
            "categorie_id": a.categorie_id,
            "prix_achat_ht": a.prix_achat_ht,
            "unite": a.unite,
            "stock_actuel": a.stock_actuel,
            "seuil_alerte": a.seuil_alerte,
            "statut": a.statut,
            "taux_perte": a.taux_perte,
            "fournisseur_1_id": a.fournisseur_1_id,
            "fournisseur_1_nom": fournisseurs.get(a.fournisseur_1_id),
            "fournisseur_2_id": a.fournisseur_2_id,
            "fournisseur_2_nom": fournisseurs.get(a.fournisseur_2_id),
            "ref_fournisseur_1": a.ref_fournisseur_1,
            "ref_fournisseur_2": a.ref_fournisseur_2,
        })
    return result
