"""Patient portal APIs — Phase 13.4."""
from __future__ import annotations

from uuid import UUID

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

from app.api.deps import get_db, require_tenant
from app.api.patient_deps import require_patient_context
from app.api.permissions import require_permissions
from app.permissions.definitions import PATIENT_PORTAL_MANAGE, PATIENT_PORTAL_VIEW
from app.schemas.appointments import AppointmentListResponse, AppointmentRead
from app.schemas.patient_portal import (
    PatientDocumentRefCreate,
    PatientDocumentRefRead,
    PatientNotificationPreferenceRead,
    PatientNotificationPreferenceUpsert,
    PatientPortalAppointmentBook,
    PatientPortalAppointmentCancel,
    PatientPortalProfileRead,
    PatientPortalProfileUpdate,
)
from app.services.patient_portal import PatientPortalService
from shared.security import CurrentUser

router = APIRouter()


@router.get("/me", response_model=PatientPortalProfileRead)
async def get_my_profile(
    patient_id: UUID = Depends(require_patient_context),
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(PATIENT_PORTAL_VIEW)),
):
    return await PatientPortalService(db).get_or_create_profile(tenant_id, patient_id, actor=user)


@router.patch("/me", response_model=PatientPortalProfileRead)
async def update_my_profile(
    body: PatientPortalProfileUpdate,
    patient_id: UUID = Depends(require_patient_context),
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(PATIENT_PORTAL_MANAGE)),
):
    return await PatientPortalService(db).update_profile(tenant_id, patient_id, body, actor=user)


@router.get("/appointments", response_model=AppointmentListResponse)
async def list_my_appointments(
    patient_id: UUID = Depends(require_patient_context),
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(require_permissions(PATIENT_PORTAL_VIEW)),
):
    items, total = await PatientPortalService(db).list_appointments(tenant_id, patient_id)
    return AppointmentListResponse(items=items, total=total, page=1, page_size=50)


@router.post("/appointments", response_model=AppointmentRead, status_code=status.HTTP_201_CREATED)
async def book_my_appointment(
    body: PatientPortalAppointmentBook,
    patient_id: UUID = Depends(require_patient_context),
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(PATIENT_PORTAL_MANAGE)),
):
    return await PatientPortalService(db).book_appointment(tenant_id, patient_id, body, actor=user)


@router.post("/appointments/{appointment_id}/cancel", response_model=AppointmentRead)
async def cancel_my_appointment(
    appointment_id: UUID,
    body: PatientPortalAppointmentCancel,
    patient_id: UUID = Depends(require_patient_context),
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(PATIENT_PORTAL_MANAGE)),
):
    return await PatientPortalService(db).cancel_appointment(
        tenant_id, patient_id, appointment_id, body, actor=user
    )


@router.get("/documents", response_model=list[PatientDocumentRefRead])
async def list_my_documents(
    patient_id: UUID = Depends(require_patient_context),
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(require_permissions(PATIENT_PORTAL_VIEW)),
):
    return await PatientPortalService(db).list_documents(tenant_id, patient_id)


@router.post("/documents", response_model=PatientDocumentRefRead, status_code=status.HTTP_201_CREATED)
async def create_my_document(
    body: PatientDocumentRefCreate,
    patient_id: UUID = Depends(require_patient_context),
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(PATIENT_PORTAL_MANAGE)),
):
    return await PatientPortalService(db).create_document(tenant_id, patient_id, body, actor=user)


@router.get("/notification-preferences", response_model=list[PatientNotificationPreferenceRead])
async def list_my_notification_prefs(
    patient_id: UUID = Depends(require_patient_context),
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(require_permissions(PATIENT_PORTAL_VIEW)),
):
    return await PatientPortalService(db).list_notification_prefs(tenant_id, patient_id)


@router.put("/notification-preferences", response_model=PatientNotificationPreferenceRead)
async def upsert_my_notification_pref(
    body: PatientNotificationPreferenceUpsert,
    patient_id: UUID = Depends(require_patient_context),
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(PATIENT_PORTAL_MANAGE)),
):
    return await PatientPortalService(db).upsert_notification_pref(
        tenant_id, patient_id, body, actor=user
    )
