import sys
sys.path.insert(0, "/var/www/html/metafoliadorv2")

from fastapi import APIRouter, Depends, HTTPException, Query, Path
from sqlalchemy.orm import Session
from sqlalchemy import func

from app.models.database import get_db
from app.models.user import User
from app.models.role_permission import Role
from app.schemas import CreateUserRequest, UpdateUserRequest
from app.services.auth_service import hash_password
from app.services.timezone import iso

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


@router.get("", summary="Listar usuarios", description="Lista todos los usuarios del sistema. Filtrable por email o nombre.")
async def list_users(search: str = Query(None, description="Buscar por email o nombre"), db: Session = Depends(get_db)):
    q = db.query(User)
    if search:
        q = q.filter(User.email.ilike(f"%{search}%") | User.name.ilike(f"%{search}%"))
    users = q.order_by(User.name).all()
    role_cache = {}
    def get_role_all_permissions(role_name):
        if role_name not in role_cache:
            r = db.query(Role).filter(Role.name == role_name).first()
            role_cache[role_name] = r.all_permissions if r else False
        return role_cache[role_name]
    return [
        {
            "id": u.id,
            "name": u.name,
            "email": u.email,
            "role": u.role,
            "role_all_permissions": get_role_all_permissions(u.role),
            "active": u.active,
            "created_at": iso(u.created_at),
        }
        for u in users
    ]


@router.get("/{user_id}", summary="Obtener usuario", description="Devuelve el detalle de un usuario por su ID.")
async def get_user(user_id: int = Path(..., description="ID del usuario"), db: Session = Depends(get_db)):
    u = db.query(User).filter(User.id == user_id).first()
    if not u:
        raise HTTPException(status_code=404, detail="Usuario no encontrado")
    return {
        "id": u.id,
        "name": u.name,
        "email": u.email,
        "role": u.role,
        "active": u.active,
        "created_at": iso(u.created_at),
    }


@router.post("", status_code=201, summary="Crear usuario", description="Registra un nuevo usuario con email, contraseña (hasheada con SHA-256) y rol asignado.")
async def create_user(body: CreateUserRequest, db: Session = Depends(get_db)):
    if not body.email or not body.password:
        raise HTTPException(status_code=400, detail="email y password son requeridos")
    existing = db.query(User).filter(User.email == body.email).first()
    if existing:
        raise HTTPException(status_code=409, detail="El email ya existe")
    u = User(
        name=body.name or "",
        email=body.email,
        password_hash=hash_password(body.password),
        role=body.role or "user",
        active=body.active if body.active is not None else True,
    )
    db.add(u)
    db.commit()
    db.refresh(u)
    return {"id": u.id, "name": u.name, "email": u.email, "role": u.role, "active": u.active}


@router.put("/{user_id}", summary="Actualizar usuario", description="Modifica datos de un usuario: nombre, email, contraseña, rol o estado activo/inactivo.")
async def update_user(user_id: int = Path(..., description="ID del usuario"), body: UpdateUserRequest = None, db: Session = Depends(get_db)):
    u = db.query(User).filter(User.id == user_id).first()
    if not u:
        raise HTTPException(status_code=404, detail="Usuario no encontrado")
    if body.name is not None:
        u.name = body.name
    if body.email:
        existing = db.query(User).filter(User.email == body.email, User.id != user_id).first()
        if existing:
            raise HTTPException(status_code=409, detail="El email ya existe")
        u.email = body.email
    if body.password:
        u.password_hash = hash_password(body.password)
    if body.role is not None:
        u.role = body.role
    if body.active is not None:
        u.active = body.active
    db.commit()
    return {"ok": True}


@router.delete("/{user_id}", summary="Eliminar usuario", description="Elimina permanentemente un usuario del sistema.")
async def delete_user(user_id: int = Path(..., description="ID del usuario a eliminar"), db: Session = Depends(get_db)):
    u = db.query(User).filter(User.id == user_id).first()
    if not u:
        raise HTTPException(status_code=404, detail="Usuario no encontrado")
    db.delete(u)
    db.commit()
    return {"ok": True}
