from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.orm import Session
from typing import Optional
from utils.utils import get_db, UserRole
from . import handler
from .schema import (
    UserCreate,
    UserUpdate,
    UserResponse,
    UserDetailsResponse,
    AuditlogCreate,
    AuditlogUpdate,
    AuditlogResponse,
    PaginatedResponse
)

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


@router.post(
    "/",
    response_model=UserResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create User",
    description="Creates a new user account with hashed password. Validates department existence if provided. Returns 409 if email already exists."
)
def create_user_route(data: UserCreate, db: Session = Depends(get_db)):
    return handler.create_user(db, data)


@router.get(
    "/",
    response_model=PaginatedResponse[UserResponse],
    summary="List Users",
    description="Returns a paginated list of users. Supports optional filters for role, active status, department, and search term (searches first name, last name, and email)."
)
def list_users_route(
    limit: int = Query(20, ge=1),
    offset: int = Query(0, ge=0),
    role: Optional[UserRole] = Query(None),
    is_active: Optional[bool] = Query(None),
    department_id: Optional[str] = Query(None),
    search: Optional[str] = Query(None),
    db: Session = Depends(get_db)
):
    return handler.list_users(db, limit, offset, role, is_active, department_id, search)


@router.get(
    "/{user_id}",
    response_model=UserResponse,
    summary="Get User",
    description="Returns a single user by ID. Returns 404 if user not found."
)
def get_user_route(user_id: str, db: Session = Depends(get_db)):
    return handler.get_user(db, user_id)


@router.get(
    "/{user_id}/details",
    response_model=UserDetailsResponse,
    summary="Get User Details",
    description="Returns user information with department name pre-loaded. Returns 404 if user not found."
)
def get_user_details_route(user_id: str, db: Session = Depends(get_db)):
    return handler.get_user_details(db, user_id)


@router.put(
    "/{user_id}",
    response_model=UserResponse,
    summary="Update User",
    description="Updates user fields. Only provided fields are updated. Validates email uniqueness and department existence. Returns 404 if user not found."
)
def update_user_route(user_id: str, data: UserUpdate, db: Session = Depends(get_db)):
    return handler.update_user(db, user_id, data)


@router.delete(
    "/{user_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete User",
    description="Deletes a user account. Returns 404 if user not found. Returns 409 if user is referenced by other records (appointments, consultations, etc)."
)
def delete_user_route(user_id: str, db: Session = Depends(get_db)):
    return handler.delete_user(db, user_id)


# Audit log routes
audit_router = APIRouter(prefix="/audit-logs", tags=["Audit Logs"])


@audit_router.post(
    "/",
    response_model=AuditlogResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Audit Log",
    description="Creates a new audit log entry recording a user action. Validates user existence if user_id is provided."
)
def create_auditlog_route(data: AuditlogCreate, db: Session = Depends(get_db)):
    return handler.create_auditlog(db, data)


@audit_router.get(
    "/",
    response_model=PaginatedResponse[AuditlogResponse],
    summary="List Audit Logs",
    description="Returns a paginated list of audit logs. Supports optional filters for user_id, entity_type, entity_id, and action."
)
def list_auditlogs_route(
    limit: int = Query(20, ge=1),
    offset: int = Query(0, ge=0),
    user_id: Optional[str] = Query(None),
    entity_type: Optional[str] = Query(None),
    entity_id: Optional[str] = Query(None),
    action: Optional[str] = Query(None),
    db: Session = Depends(get_db)
):
    return handler.list_auditlogs(db, limit, offset, user_id, entity_type, entity_id, action)


@audit_router.get(
    "/{auditlog_id}",
    response_model=AuditlogResponse,
    summary="Get Audit Log",
    description="Returns a single audit log entry by ID. Returns 404 if not found."
)
def get_auditlog_route(auditlog_id: str, db: Session = Depends(get_db)):
    return handler.get_auditlog(db, auditlog_id)


@audit_router.put(
    "/{auditlog_id}",
    response_model=AuditlogResponse,
    summary="Update Audit Log",
    description="Updates audit log entry fields. Only provided fields are updated. Validates user existence if user_id is provided. Returns 404 if not found."
)
def update_auditlog_route(auditlog_id: str, data: AuditlogUpdate, db: Session = Depends(get_db)):
    return handler.update_auditlog(db, auditlog_id, data)


@audit_router.delete(
    "/{auditlog_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Audit Log",
    description="Deletes an audit log entry. Returns 404 if not found."
)
def delete_auditlog_route(auditlog_id: str, db: Session = Depends(get_db)):
    return handler.delete_auditlog(db, auditlog_id)


router.include_router(audit_router)