from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.orm import Session
from typing import Optional
from utils.utils import get_db
from . import handler
from .schema import (
    PatientCreate,
    PatientUpdate,
    PatientResponse,
    PatientDetailResponse,
    PaginatedPatientResponse,
    MedicalrecordCreate,
    MedicalrecordUpdate,
    MedicalrecordResponse,
)

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


@router.post(
    "/",
    response_model=PatientResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Patient",
    description="Creates a new patient record and automatically creates an associated medical record. Returns 409 if patient_number already exists. Returns 400 if insurance provider does not exist.",
)
def create_patient_route(data: PatientCreate, db: Session = Depends(get_db)):
    return handler.create_patient(db, data)


@router.get(
    "/",
    response_model=PaginatedPatientResponse,
    summary="List Patients",
    description="Returns a paginated list of patients. Supports optional search filter on first_name, last_name, patient_number, and email fields.",
)
def list_patients_route(
    limit: int = Query(20, ge=1),
    offset: int = Query(0, ge=0),
    search: Optional[str] = None,
    db: Session = Depends(get_db),
):
    return handler.list_patients(db, limit, offset, search=search)


@router.get(
    "/{patient_id}",
    response_model=PatientResponse,
    summary="Get Patient",
    description="Returns a single patient record by ID. Returns 404 if patient not found.",
)
def get_patient_route(patient_id: str, db: Session = Depends(get_db)):
    return handler.get_patient(db, patient_id)


@router.get(
    "/{patient_id}/details",
    response_model=PatientDetailResponse,
    summary="Get Patient Details",
    description="Returns detailed patient record with insurance provider, medical record, and appointments including doctor and department information. Returns 404 if patient not found.",
)
def get_patient_details_route(patient_id: str, db: Session = Depends(get_db)):
    return handler.get_patient_details(db, patient_id)


@router.put(
    "/{patient_id}",
    response_model=PatientResponse,
    summary="Update Patient",
    description="Updates patient record fields. Only provided fields are updated. Returns 404 if patient not found. Returns 409 if patient_number already exists. Returns 400 if insurance provider does not exist.",
)
def update_patient_route(
    patient_id: str,
    data: PatientUpdate,
    db: Session = Depends(get_db),
):
    return handler.update_patient(db, patient_id, data)


@router.delete(
    "/{patient_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Patient",
    description="Deletes a patient record and cascades to all associated records (medical record, appointments, consultations, etc.). Returns 404 if patient not found. Returns 409 if patient has records that prevent deletion.",
)
def delete_patient_route(patient_id: str, db: Session = Depends(get_db)):
    return handler.delete_patient(db, patient_id)


@router.post(
    "/medical-records",
    response_model=MedicalrecordResponse,
    status_code=status.HTTP_201_CREATED,
    summary="Create Medical Record",
    description="Creates a medical record for a patient. Returns 409 if medical record already exists for this patient. Returns 400 if patient does not exist.",
)
def create_medicalrecord_route(data: MedicalrecordCreate, db: Session = Depends(get_db)):
    return handler.create_medicalrecord(db, data)


@router.get(
    "/medical-records",
    response_model=list,
    summary="List Medical Records",
    description="Returns a paginated list of medical records. Supports optional filter by patient_id.",
)
def list_medicalrecords_route(
    limit: int = Query(20, ge=1),
    offset: int = Query(0, ge=0),
    patient_id: Optional[str] = None,
    db: Session = Depends(get_db),
):
    result = handler.list_medicalrecords(db, limit, offset, patient_id=patient_id)
    return result["items"]


@router.get(
    "/medical-records/{record_id}",
    response_model=MedicalrecordResponse,
    summary="Get Medical Record",
    description="Returns a single medical record by ID. Returns 404 if medical record not found.",
)
def get_medicalrecord_route(record_id: str, db: Session = Depends(get_db)):
    return handler.get_medicalrecord(db, record_id)


@router.put(
    "/medical-records/{record_id}",
    response_model=MedicalrecordResponse,
    summary="Update Medical Record",
    description="Updates medical record fields. Only provided fields are updated. Returns 404 if medical record not found. Returns 400 if patient does not exist.",
)
def update_medicalrecord_route(
    record_id: str,
    data: MedicalrecordUpdate,
    db: Session = Depends(get_db),
):
    return handler.update_medicalrecord(db, record_id, data)


@router.delete(
    "/medical-records/{record_id}",
    status_code=status.HTTP_200_OK,
    summary="Delete Medical Record",
    description="Deletes a medical record. Returns 404 if medical record not found. Returns 409 if medical record has references that prevent deletion.",
)
def delete_medicalrecord_route(record_id: str, db: Session = Depends(get_db)):
    return handler.delete_medicalrecord(db, record_id)