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

from app import models
from app.core import security
from app.core.database import get_db
from app.schemas import auth as schemas

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


@router.post("/register", response_model=schemas.TokenOut, status_code=status.HTTP_201_CREATED)
def register(data: schemas.RegisterIn, db: Session = Depends(get_db)) -> schemas.TokenOut:
    """Registra una cuenta nueva y devuelve el token de acceso."""
    if db.scalar(select(models.User).where(models.User.email == data.email.lower())):
        raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="Ese email ya está registrado")

    user = models.User(
        email = data.email.lower(),
        password_hash = security.get_password_hash(data.password),
        full_name = data.full_name,
        phone = data.phone,
        role = data.role,
        country = data.country.upper(),
    )
    db.add(user)
    db.commit()
    db.refresh(user)

    access_token = security.create_access_token(data={"sub": str(user.id)})
    return schemas.TokenOut(access_token=access_token, user=schemas.UserOut.model_validate(user))


@router.post("/login", response_model=schemas.TokenOut)
def login(data: schemas.LoginIn, db: Session = Depends(get_db)) -> schemas.TokenOut:
    """Autentica por email/contraseña y devuelve el token de acceso."""
    user = security.authenticate_user(db, data.email, data.password)
    if user is None:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Email o contraseña incorrectos",
            headers={"WWW-Authenticate": "Bearer"},
        )
    access_token = security.create_access_token(data={"sub": str(user.id)})
    return schemas.TokenOut(access_token=access_token, user=schemas.UserOut.model_validate(user))


@router.get("/me", response_model=schemas.UserOut)
def me(current_user: models.User = Depends(security.get_current_user)) -> models.User:
    """Devuelve la cuenta autenticada."""
    return current_user


@router.get("/users", response_model=list[schemas.UserOut])
def list_users(
    db: Session = Depends(get_db),
    _current_user: models.User = Depends(security.get_current_admin_user),
) -> list[models.User]:
    """Lista todas las cuentas registradas. Solo para administradores."""
    return db.scalars(select(models.User)).all()
