"""Appointment lifecycle APIs — Phase 14.1."""
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, get_pagination, require_tenant
from app.api.permissions import require_permissions
from app.commands.appointments import AppointmentCommands
from app.permissions.definitions import (
    APPOINTMENTS_CANCEL,
    APPOINTMENTS_CHECK_IN,
    APPOINTMENTS_COMPLETE,
    APPOINTMENTS_CONFIRM,
    APPOINTMENTS_CREATE,
    APPOINTMENTS_NO_SHOW,
    APPOINTMENTS_UPDATE,
    APPOINTMENTS_VIEW,
)
from app.queries.appointments import AppointmentQueries
from app.schemas.appointment_core import (
    AppointmentCreate,
    AppointmentLifecycleRequest,
    AppointmentRead,
    AppointmentStatusHistoryRead,
    AppointmentUpdate,
)
from shared.pagination import PaginationParams
from shared.security import CurrentUser

router = APIRouter()

@router.post("", response_model=AppointmentRead, status_code=status.HTTP_201_CREATED)
async def create_appointment(body: AppointmentCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(require_permissions(APPOINTMENTS_CREATE))):
    return await AppointmentCommands(db).create(tenant_id, body, actor=user)

@router.get("", response_model=list[AppointmentRead])
async def list_appointments(tenant_id: UUID = Depends(require_tenant), pagination: PaginationParams = Depends(get_pagination), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(require_permissions(APPOINTMENTS_VIEW))):
    return await AppointmentQueries(db).list(tenant_id, offset=pagination.offset, limit=pagination.page_size)

@router.get("/{appointment_id}", response_model=AppointmentRead)
async def get_appointment(appointment_id: UUID, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(require_permissions(APPOINTMENTS_VIEW))):
    return await AppointmentQueries(db).get(tenant_id, appointment_id)

@router.patch("/{appointment_id}", response_model=AppointmentRead)
async def update_appointment(appointment_id: UUID, body: AppointmentUpdate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(require_permissions(APPOINTMENTS_UPDATE))):
    return await AppointmentCommands(db).update(tenant_id, appointment_id, body, actor=user)

@router.post("/{appointment_id}/confirm", response_model=AppointmentRead)
async def confirm_appointment(appointment_id: UUID, body: AppointmentLifecycleRequest, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(require_permissions(APPOINTMENTS_CONFIRM))):
    return await AppointmentCommands(db).confirm(tenant_id, appointment_id, body, actor=user)

@router.post("/{appointment_id}/check-in", response_model=AppointmentRead)
async def check_in_appointment(appointment_id: UUID, body: AppointmentLifecycleRequest, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(require_permissions(APPOINTMENTS_CHECK_IN))):
    return await AppointmentCommands(db).check_in(tenant_id, appointment_id, body, actor=user)

@router.post("/{appointment_id}/complete", response_model=AppointmentRead)
async def complete_appointment(appointment_id: UUID, body: AppointmentLifecycleRequest, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(require_permissions(APPOINTMENTS_COMPLETE))):
    return await AppointmentCommands(db).complete(tenant_id, appointment_id, body, actor=user)

@router.post("/{appointment_id}/cancel", response_model=AppointmentRead)
async def cancel_appointment(appointment_id: UUID, body: AppointmentLifecycleRequest, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(require_permissions(APPOINTMENTS_CANCEL))):
    return await AppointmentCommands(db).cancel(tenant_id, appointment_id, body, actor=user)

@router.post("/{appointment_id}/no-show", response_model=AppointmentRead)
async def no_show_appointment(appointment_id: UUID, body: AppointmentLifecycleRequest, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(require_permissions(APPOINTMENTS_NO_SHOW))):
    return await AppointmentCommands(db).no_show(tenant_id, appointment_id, body, actor=user)

@router.get("/{appointment_id}/history", response_model=list[AppointmentStatusHistoryRead])
async def list_appointment_history(appointment_id: UUID, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(require_permissions(APPOINTMENTS_VIEW))):
    return await AppointmentQueries(db).list_history(tenant_id, appointment_id)
