from fastapi import APIRouter, Depends, Form, HTTPException, Request
from fastapi.responses import RedirectResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session

from app import models
from app.database import get_db
from app.securite import exiger_admin, hacher_mot_de_passe, obtenir_jeton_csrf, verifier_csrf

router = APIRouter(prefix="/utilisateurs", tags=["utilisateurs"], dependencies=[Depends(exiger_admin)])
templates = Jinja2Templates(directory="app/templates")


@router.get("")
def liste_utilisateurs(request: Request, db: Session = Depends(get_db)):
    utilisateurs = db.query(models.Utilisateur).order_by(models.Utilisateur.nom_complet).all()
    return templates.TemplateResponse(
        "utilisateurs/liste.html",
        {"request": request, "utilisateurs": utilisateurs, "csrf_token": obtenir_jeton_csrf(request)},
    )


@router.get("/journal")
def journal_connexions(request: Request, db: Session = Depends(get_db)):
    entrees = (
        db.query(models.JournalConnexion)
        .order_by(models.JournalConnexion.date_heure.desc())
        .limit(200)
        .all()
    )
    return templates.TemplateResponse(
        "utilisateurs/journal.html", {"request": request, "entrees": entrees}
    )


@router.get("/nouveau")
def formulaire_utilisateur(request: Request):
    return templates.TemplateResponse(
        "utilisateurs/formulaire.html", {"request": request, "csrf_token": obtenir_jeton_csrf(request)}
    )


@router.post("/nouveau")
def creer_utilisateur(
    request: Request,
    csrf_token: str = Form(...),
    identifiant: str = Form(...),
    nom_complet: str = Form(...),
    mot_de_passe: str = Form(...),
    confirmation_mot_de_passe: str = Form(...),
    est_admin: bool = Form(False),
    db: Session = Depends(get_db),
):
    erreur = None
    if not verifier_csrf(request, csrf_token):
        erreur = "Session expirée, veuillez réessayer."
    elif len(mot_de_passe) < 8:
        erreur = "Le mot de passe doit contenir au moins 8 caractères."
    elif mot_de_passe != confirmation_mot_de_passe:
        erreur = "Les mots de passe ne correspondent pas."
    elif db.query(models.Utilisateur).filter(models.Utilisateur.identifiant == identifiant.strip()).first():
        erreur = "Cet identifiant est déjà utilisé."

    if erreur:
        return templates.TemplateResponse(
            "utilisateurs/formulaire.html",
            {"request": request, "csrf_token": obtenir_jeton_csrf(request), "erreur": erreur},
            status_code=400,
        )

    db.add(
        models.Utilisateur(
            identifiant=identifiant.strip(),
            nom_complet=nom_complet.strip(),
            mot_de_passe_hash=hacher_mot_de_passe(mot_de_passe),
            est_admin=est_admin,
            actif=True,
        )
    )
    db.commit()
    return RedirectResponse(url="/utilisateurs?succes=Compte créé", status_code=303)


@router.post("/{utilisateur_id}/desactiver")
def desactiver_utilisateur(
    utilisateur_id: int,
    request: Request,
    csrf_token: str = Form(...),
    db: Session = Depends(get_db),
    utilisateur_admin: models.Utilisateur = Depends(exiger_admin),
):
    if not verifier_csrf(request, csrf_token):
        raise HTTPException(status_code=403, detail="Jeton de sécurité invalide")
    if utilisateur_id == utilisateur_admin.id:
        return RedirectResponse(
            url="/utilisateurs?erreur=Impossible de désactiver votre propre compte", status_code=303
        )

    cible = db.get(models.Utilisateur, utilisateur_id)
    if cible is None:
        raise HTTPException(status_code=404, detail="Utilisateur introuvable")

    if cible.est_admin:
        autres_admins_actifs = (
            db.query(models.Utilisateur)
            .filter(models.Utilisateur.est_admin.is_(True), models.Utilisateur.actif.is_(True), models.Utilisateur.id != cible.id)
            .count()
        )
        if autres_admins_actifs == 0:
            return RedirectResponse(
                url="/utilisateurs?erreur=Impossible de désactiver le dernier administrateur", status_code=303
            )

    cible.actif = False
    db.commit()
    return RedirectResponse(url="/utilisateurs?succes=Compte désactivé", status_code=303)


@router.post("/{utilisateur_id}/reactiver")
def reactiver_utilisateur(
    utilisateur_id: int, request: Request, csrf_token: str = Form(...), db: Session = Depends(get_db)
):
    if not verifier_csrf(request, csrf_token):
        raise HTTPException(status_code=403, detail="Jeton de sécurité invalide")
    cible = db.get(models.Utilisateur, utilisateur_id)
    if cible is None:
        raise HTTPException(status_code=404, detail="Utilisateur introuvable")
    cible.actif = True
    db.commit()
    return RedirectResponse(url="/utilisateurs?succes=Compte réactivé", status_code=303)
