"""Medical record APIs — Phase 13.5."""
from __future__ import annotations

from uuid import UUID

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

from app.api.deps import get_db, require_tenant
from app.api.permissions import require_permissions
from app.permissions.definitions import ENCOUNTERS_MANAGE, MEDICAL_RECORDS_MANAGE, MEDICAL_RECORDS_VIEW
from app.schemas.medical_records import (
    AllergyCreate,
    AllergyRead,
    ConditionCreate,
    ConditionRead,
    EncounterCreate,
    EncounterFinalize,
    EncounterRead,
    EncounterUpdate,
    ImmunizationCreate,
    ImmunizationRead,
    MedicalRecordAccessRequest,
    MedicalRecordCreate,
    MedicalRecordRead,
    MedicationCreate,
    MedicationRead,
)
from app.services.medical_records import MedicalRecordService
from shared.security import CurrentUser

router = APIRouter()
records_router = APIRouter()
encounters_router = APIRouter()


class ClinicalListsResponse(BaseModel):
    conditions: list[ConditionRead]
    allergies: list[AllergyRead]
    medications: list[MedicationRead]
    immunizations: list[ImmunizationRead]


@records_router.post("", response_model=MedicalRecordRead, status_code=status.HTTP_201_CREATED)
async def create_medical_record(
    body: MedicalRecordCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(MEDICAL_RECORDS_MANAGE)),
):
    return await MedicalRecordService(db).create_record(tenant_id, body, actor=user)


@records_router.get("/{record_id}", response_model=MedicalRecordRead)
async def get_medical_record(
    record_id: UUID,
    reason: str | None = Query(default=None, max_length=500),
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(MEDICAL_RECORDS_VIEW)),
):
    access = MedicalRecordAccessRequest(reason=reason)
    return await MedicalRecordService(db).get_record(tenant_id, record_id, actor=user, access=access)


@records_router.get("/{record_id}/clinical-lists", response_model=ClinicalListsResponse)
async def get_clinical_lists(
    record_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(require_permissions(MEDICAL_RECORDS_VIEW)),
):
    data = await MedicalRecordService(db).list_clinical_lists(tenant_id, record_id)
    return ClinicalListsResponse(**data)


@records_router.post("/{record_id}/conditions", response_model=ConditionRead, status_code=status.HTTP_201_CREATED)
async def add_condition(
    record_id: UUID,
    body: ConditionCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(MEDICAL_RECORDS_MANAGE)),
):
    return await MedicalRecordService(db).add_condition(tenant_id, record_id, body, actor=user)


@records_router.post("/{record_id}/allergies", response_model=AllergyRead, status_code=status.HTTP_201_CREATED)
async def add_allergy(
    record_id: UUID,
    body: AllergyCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(MEDICAL_RECORDS_MANAGE)),
):
    return await MedicalRecordService(db).add_allergy(tenant_id, record_id, body, actor=user)


@records_router.post("/{record_id}/medications", response_model=MedicationRead, status_code=status.HTTP_201_CREATED)
async def add_medication(
    record_id: UUID,
    body: MedicationCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(MEDICAL_RECORDS_MANAGE)),
):
    return await MedicalRecordService(db).add_medication(tenant_id, record_id, body, actor=user)


@records_router.post("/{record_id}/immunizations", response_model=ImmunizationRead, status_code=status.HTTP_201_CREATED)
async def add_immunization(
    record_id: UUID,
    body: ImmunizationCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(MEDICAL_RECORDS_MANAGE)),
):
    return await MedicalRecordService(db).add_immunization(tenant_id, record_id, body, actor=user)


@encounters_router.post("", response_model=EncounterRead, status_code=status.HTTP_201_CREATED)
async def create_encounter(
    body: EncounterCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(ENCOUNTERS_MANAGE)),
):
    return await MedicalRecordService(db).create_encounter(tenant_id, body, actor=user)


@encounters_router.patch("/{encounter_id}", response_model=EncounterRead)
async def update_encounter(
    encounter_id: UUID,
    body: EncounterUpdate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(ENCOUNTERS_MANAGE)),
):
    return await MedicalRecordService(db).update_encounter(tenant_id, encounter_id, body, actor=user)


@encounters_router.post("/{encounter_id}/finalize", response_model=EncounterRead)
async def finalize_encounter(
    encounter_id: UUID,
    body: EncounterFinalize,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(ENCOUNTERS_MANAGE)),
):
    return await MedicalRecordService(db).finalize_encounter(tenant_id, encounter_id, body, actor=user)
