from typing import Literal

from fastapi import APIRouter, Depends, Query
from sqlalchemy.ext.asyncio import AsyncSession

from app.database.session import get_db
from app.domain.entities.patient import PatientEntity
from app.domain.entities.responses.paginated_patient import PaginatedPatientsResponseEntity
from app.infrastructure.dependencies import get_current_user
from app.infrastructure.patients_service import PatientsService

router = APIRouter()


@router.get(
    "/",
    response_model=PaginatedPatientsResponseEntity,
    summary="Get all patients with pagination",
    description="Returns a paginated list of patients and total count",
)
async def get_all_patients(
        page: int = Query(1, ge=1, description="Page number"),
        page_size: int = Query(10, ge=1, le=100, description="Number of patients per page"),
        search: str = Query(None, description="Search term for filtering patients"),
        sort_order: Literal["asc", "desc"] = Query("asc", description="Sort order by first_name (asc or desc)"),
        all_params: bool = Query(False, description="Get all patients"),
        db: AsyncSession = Depends(get_db),
        user=Depends(get_current_user),
):
    patients_service = PatientsService(db)
    patients, total_count = await patients_service.get_all_patients(page, page_size, search, sort_order, all_params)
    return {"patients": patients, "total_count": total_count}


@router.post(
    "/",
    response_model=PatientEntity,
    summary="Create a new patient",
    description="Creates a new patient",
)
async def create_patient(
        patient: PatientEntity,
        db: AsyncSession = Depends(get_db),
        user=Depends(get_current_user),
):
    patients_service = PatientsService(db)
    return await patients_service.create_patient(patient)


@router.put(
    "/{patient_id}/",
    response_model=PatientEntity,
    summary="Update a patient",
    description="Updates a patient",
)
async def update_patient(
        patient_id: int,
        patient: PatientEntity,
        db: AsyncSession = Depends(get_db),
        user=Depends(get_current_user),
):
    patients_service = PatientsService(db)
    return await patients_service.update_patient(patient_id, patient)


@router.delete(
    "/{patient_id}/",
    response_model=PatientEntity,
    summary="Delete a patient",
    description="Deletes a patient",
)
async def delete_patient(
        patient_id: int,
        db: AsyncSession = Depends(get_db),
        user=Depends(get_current_user),
):
    patient_service = PatientsService(db)
    return await patient_service.delete_patient(patient_id)
