"""Doctor panel APIs — Phase 13.2."""
from __future__ import annotations

from uuid import UUID

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

from app.api.deps import get_db, get_pagination, require_tenant
from app.api.permissions import require_permissions
from app.commands.doctor_panel import DoctorPanelCommands
from app.models.types import VisitSessionStatus
from app.permissions.definitions import (
    DOCTOR_PANEL_VIEW,
    VISIT_NOTES_MANAGE,
    VISIT_SESSIONS_MANAGE,
)
from app.queries.doctor_panel import DoctorPanelQueries
from app.schemas.doctor_panel import (
    DoctorDashboardRead,
    DoctorQueueRead,
    VisitNoteCreate,
    VisitNoteRead,
    VisitNoteUpdate,
    VisitSessionActionRequest,
    VisitSessionCreate,
    VisitSessionRead,
)
from app.specifications.doctor_panel import VisitSessionListSpec
from shared.pagination import PaginationParams
from shared.security import CurrentUser

doctor_panel_router = APIRouter()
visit_sessions_router = APIRouter()
visit_notes_router = APIRouter()


def _visit_spec(
    doctor_id: UUID | None = Query(default=None),
    clinic_id: UUID | None = Query(default=None),
    status_filter: VisitSessionStatus | None = Query(default=None, alias="status"),
) -> VisitSessionListSpec:
    return VisitSessionListSpec(
        doctor_id=doctor_id,
        clinic_id=clinic_id,
        status=status_filter,
    )


@doctor_panel_router.get("/dashboard", response_model=DoctorDashboardRead)
async def doctor_dashboard(
    doctor_id: UUID = Query(...),
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(require_permissions(DOCTOR_PANEL_VIEW)),
):
    return await DoctorPanelQueries(db).dashboard(tenant_id, doctor_id=doctor_id)


@doctor_panel_router.get("/queue", response_model=DoctorQueueRead)
async def doctor_queue(
    doctor_id: UUID = Query(...),
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(require_permissions(DOCTOR_PANEL_VIEW)),
):
    return await DoctorPanelQueries(db).queue(tenant_id, doctor_id=doctor_id)


@visit_sessions_router.post("", response_model=VisitSessionRead, status_code=status.HTTP_201_CREATED)
async def create_visit_session(
    body: VisitSessionCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(VISIT_SESSIONS_MANAGE)),
):
    return await DoctorPanelCommands(db).create_session(tenant_id, body, actor=user)


@visit_sessions_router.get("", response_model=list[VisitSessionRead])
async def list_visit_sessions(
    tenant_id: UUID = Depends(require_tenant),
    pagination: PaginationParams = Depends(get_pagination),
    spec: VisitSessionListSpec = Depends(_visit_spec),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(require_permissions(DOCTOR_PANEL_VIEW)),
):
    return await DoctorPanelQueries(db).list_sessions(
        tenant_id, offset=pagination.offset, limit=pagination.page_size, spec=spec
    )


@visit_sessions_router.get("/{visit_session_id}", response_model=VisitSessionRead)
async def get_visit_session(
    visit_session_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(require_permissions(DOCTOR_PANEL_VIEW)),
):
    return await DoctorPanelQueries(db).get_session(tenant_id, visit_session_id)


@visit_sessions_router.post("/{visit_session_id}/start", response_model=VisitSessionRead)
async def start_visit_session(
    visit_session_id: UUID,
    body: VisitSessionActionRequest,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(VISIT_SESSIONS_MANAGE)),
):
    return await DoctorPanelCommands(db).start_session(
        tenant_id, visit_session_id, body, actor=user
    )


@visit_sessions_router.post("/{visit_session_id}/finish", response_model=VisitSessionRead)
async def finish_visit_session(
    visit_session_id: UUID,
    body: VisitSessionActionRequest,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(VISIT_SESSIONS_MANAGE)),
):
    return await DoctorPanelCommands(db).finish_session(
        tenant_id, visit_session_id, body, actor=user
    )


@visit_sessions_router.post("/{visit_session_id}/defer", response_model=VisitSessionRead)
async def defer_visit_session(
    visit_session_id: UUID,
    body: VisitSessionActionRequest,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(VISIT_SESSIONS_MANAGE)),
):
    return await DoctorPanelCommands(db).defer_session(
        tenant_id, visit_session_id, body, actor=user
    )


@visit_sessions_router.post("/{visit_session_id}/call-next", response_model=VisitSessionRead)
async def call_next_visit(
    visit_session_id: UUID,
    body: VisitSessionActionRequest,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(VISIT_SESSIONS_MANAGE)),
):
    return await DoctorPanelCommands(db).call_next(
        tenant_id, visit_session_id, body, actor=user
    )


@visit_notes_router.post("", response_model=VisitNoteRead, status_code=status.HTTP_201_CREATED)
async def create_visit_note(
    body: VisitNoteCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(VISIT_NOTES_MANAGE)),
):
    return await DoctorPanelCommands(db).create_note(tenant_id, body, actor=user)


@visit_notes_router.get("", response_model=list[VisitNoteRead])
async def list_visit_notes(
    visit_session_id: UUID = Query(...),
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(require_permissions(DOCTOR_PANEL_VIEW)),
):
    return await DoctorPanelQueries(db).list_notes(tenant_id, visit_session_id)


@visit_notes_router.patch("/{note_id}", response_model=VisitNoteRead)
async def update_visit_note(
    note_id: UUID,
    body: VisitNoteUpdate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(require_permissions(VISIT_NOTES_MANAGE)),
):
    return await DoctorPanelCommands(db).update_note(tenant_id, note_id, body, actor=user)
