from datetime import datetime, timedelta, timezone

from fastapi import APIRouter, Depends, HTTPException, Request, status
from sqlalchemy.orm import Session

from ..core.config import get_settings
from ..core.security import create_access_token, verify_password
from ..db_models.internal import LogAdmin, SesionAdmin, UsuarioAdmin
from ..dependencies import get_current_admin, get_internal_db, oauth2_scheme
from ..schemas.auth import AdminInfo, LoginRequest, TokenResponse

router = APIRouter(prefix="/auth", tags=["Autenticación"])
settings = get_settings()


@router.post("/login", response_model=TokenResponse, summary="Iniciar sesión")
def login(request: Request, body: LoginRequest, db: Session = Depends(get_internal_db)):
    user = (
        db.query(UsuarioAdmin)
        .filter(
            (UsuarioAdmin.username == body.username)
            | (UsuarioAdmin.email == body.username)
        )
        .first()
    )

    if not user or not verify_password(body.password, user.password_hash):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Usuario o contraseña incorrectos",
        )

    if not user.activo:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Cuenta desactivada",
        )

    expires = timedelta(minutes=settings.jwt_access_token_expire_minutes)
    token = create_access_token({"sub": str(user.id_usuario), "username": user.username}, expires)

    client_ip = request.client.host if request.client else None
    session = SesionAdmin(
        id_usuario=user.id_usuario,
        token=token,
        ip=client_ip,
        user_agent=request.headers.get("user-agent"),
        fecha_expiracion=datetime.now(timezone.utc) + expires,
    )
    db.add(session)

    user.ultimo_login = datetime.now(timezone.utc)

    db.add(LogAdmin(
        id_usuario=user.id_usuario,
        accion="LOGIN",
        descripcion=f"Login desde {client_ip or 'desconocido'}",
    ))
    db.commit()

    return TokenResponse(
        access_token=token,
        expires_in=settings.jwt_access_token_expire_minutes * 60,
    )


@router.post("/logout", summary="Cerrar sesión")
def logout(
    token: str = Depends(oauth2_scheme),
    current_admin: UsuarioAdmin = Depends(get_current_admin),
    db: Session = Depends(get_internal_db),
):
    db.query(SesionAdmin).filter(SesionAdmin.token == token).delete()
    db.add(LogAdmin(
        id_usuario=current_admin.id_usuario,
        accion="LOGOUT",
        descripcion="Sesión cerrada",
    ))
    db.commit()
    return {"message": "Sesión cerrada correctamente"}


@router.get("/me", response_model=AdminInfo, summary="Información del administrador actual")
def me(current_admin: UsuarioAdmin = Depends(get_current_admin)):
    return AdminInfo(
        id_usuario=current_admin.id_usuario,
        username=current_admin.username,
        email=current_admin.email,
        nombre=current_admin.nombre,
        rol=current_admin.rol.nombre,
        activo=current_admin.activo,
        ultimo_login=current_admin.ultimo_login,
        fecha_creacion=current_admin.fecha_creacion,
    )


@router.get("/sessions", summary="Sesiones activas del administrador actual")
def get_sessions(
    current_admin: UsuarioAdmin = Depends(get_current_admin),
    db: Session = Depends(get_internal_db),
):
    sessions = (
        db.query(SesionAdmin)
        .filter(
            SesionAdmin.id_usuario == current_admin.id_usuario,
            SesionAdmin.fecha_expiracion > datetime.now(timezone.utc),
        )
        .all()
    )
    return [
        {
            "id_sesion": s.id_sesion,
            "ip": s.ip,
            "user_agent": s.user_agent,
            "fecha_inicio": s.fecha_inicio,
            "fecha_expiracion": s.fecha_expiracion,
        }
        for s in sessions
    ]


@router.get("/logs", summary="Registro de actividad del administrador actual")
def get_logs(
    current_admin: UsuarioAdmin = Depends(get_current_admin),
    db: Session = Depends(get_internal_db),
    limit: int = 100,
):
    logs = (
        db.query(LogAdmin)
        .filter(LogAdmin.id_usuario == current_admin.id_usuario)
        .order_by(LogAdmin.fecha.desc())
        .limit(limit)
        .all()
    )
    return [
        {
            "id_log": log.id_log,
            "accion": log.accion,
            "descripcion": log.descripcion,
            "fecha": log.fecha,
        }
        for log in logs
    ]
