from typing import Annotated

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

from .. import crud, models, schemas, security
from ..database import get_db

router = APIRouter(prefix="/api/yatra/admin/users", tags=["admin-users"])

# Only superadmins may manage admin accounts.
SuperAdmin = Annotated[
    models.AdminUser, Depends(security.require_roles(*security.SUPERADMIN_ONLY))
]


@router.post("", response_model=schemas.AdminUserOut, status_code=status.HTTP_201_CREATED)
def create_admin_user(
    payload: schemas.AdminUserCreate,
    _: SuperAdmin,
    db: Annotated[Session, Depends(get_db)],
) -> models.AdminUser:
    if crud.get_admin_by_email(db, payload.email) is not None:
        raise HTTPException(
            status_code=status.HTTP_409_CONFLICT,
            detail="An admin with this email already exists",
        )
    return crud.create_admin(db, payload)


@router.get("", response_model=list[schemas.AdminUserOut])
def list_admin_users(
    _: SuperAdmin,
    db: Annotated[Session, Depends(get_db)],
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=500),
) -> list[models.AdminUser]:
    return crud.list_admins(db, skip=skip, limit=limit)


@router.patch("/{admin_id}", response_model=schemas.AdminUserOut)
def update_admin_user(
    admin_id: int,
    payload: schemas.AdminUserUpdate,
    _: SuperAdmin,
    db: Annotated[Session, Depends(get_db)],
) -> models.AdminUser:
    admin = crud.get_admin(db, admin_id)
    if admin is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Admin not found")
    return crud.update_admin(db, admin, payload)


@router.delete("/{admin_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_admin_user(
    admin_id: int,
    current: SuperAdmin,
    db: Annotated[Session, Depends(get_db)],
) -> None:
    admin = crud.get_admin(db, admin_id)
    if admin is None:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Admin not found")
    if admin.id == current.id:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="You cannot delete your own account",
        )
    crud.delete_admin(db, admin)
