"""API routes."""
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 shared.pagination import PaginationParams
from shared.security import CurrentUser

from app.permissions.definitions import APPOINTMENTS_CREATE, APPOINTMENTS_VIEW
from app.permissions.definitions import SCHEDULES_CREATE, SCHEDULES_VIEW
from app.permissions.definitions import WAITING_LIST_CREATE, WAITING_LIST_VIEW
from app.schemas.appointments import AppointmentTypeCreate, AppointmentTypeRead
from app.schemas.appointments import ScheduleExceptionCreate, ScheduleExceptionRead
from app.schemas.appointments import StaffAvailabilityCreate, StaffAvailabilityRead
from app.schemas.appointments import StaffScheduleCreate, StaffScheduleRead
from app.schemas.appointments import WaitingListEntryCreate, WaitingListEntryRead
from app.services.appointments import AppointmentTypeService
from app.services.appointments import ScheduleExceptionService
from app.services.appointments import StaffAvailabilityService
from app.services.appointments import StaffScheduleService
from app.services.appointments import WaitingListEntryService


staffSchedule_router = APIRouter()

@staffSchedule_router.post("", response_model=StaffScheduleRead, status_code=status.HTTP_201_CREATED)
async def create_staffSchedule(body: StaffScheduleCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(require_permissions(SCHEDULES_CREATE))):
    return await StaffScheduleService(db).create(tenant_id, body, actor=user)

@staffSchedule_router.get("", response_model=list[StaffScheduleRead])
async def list_staffSchedule(tenant_id: UUID = Depends(require_tenant), pagination: PaginationParams = Depends(get_pagination), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(require_permissions(SCHEDULES_VIEW))):
    return await StaffScheduleService(db).list(tenant_id, offset=pagination.offset, limit=pagination.page_size)

@staffSchedule_router.get("/{entity_id}", response_model=StaffScheduleRead)
async def get_staffSchedule(entity_id: UUID, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(require_permissions(SCHEDULES_VIEW))):
    return await StaffScheduleService(db).get(tenant_id, entity_id)


staffAvailability_router = APIRouter()

@staffAvailability_router.post("", response_model=StaffAvailabilityRead, status_code=status.HTTP_201_CREATED)
async def create_staffAvailability(body: StaffAvailabilityCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(require_permissions(SCHEDULES_CREATE))):
    return await StaffAvailabilityService(db).create(tenant_id, body, actor=user)

@staffAvailability_router.get("", response_model=list[StaffAvailabilityRead])
async def list_staffAvailability(tenant_id: UUID = Depends(require_tenant), pagination: PaginationParams = Depends(get_pagination), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(require_permissions(SCHEDULES_VIEW))):
    return await StaffAvailabilityService(db).list(tenant_id, offset=pagination.offset, limit=pagination.page_size)

@staffAvailability_router.get("/{entity_id}", response_model=StaffAvailabilityRead)
async def get_staffAvailability(entity_id: UUID, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(require_permissions(SCHEDULES_VIEW))):
    return await StaffAvailabilityService(db).get(tenant_id, entity_id)


scheduleException_router = APIRouter()

@scheduleException_router.post("", response_model=ScheduleExceptionRead, status_code=status.HTTP_201_CREATED)
async def create_scheduleException(body: ScheduleExceptionCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(require_permissions(SCHEDULES_CREATE))):
    return await ScheduleExceptionService(db).create(tenant_id, body, actor=user)

@scheduleException_router.get("", response_model=list[ScheduleExceptionRead])
async def list_scheduleException(tenant_id: UUID = Depends(require_tenant), pagination: PaginationParams = Depends(get_pagination), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(require_permissions(SCHEDULES_VIEW))):
    return await ScheduleExceptionService(db).list(tenant_id, offset=pagination.offset, limit=pagination.page_size)

@scheduleException_router.get("/{entity_id}", response_model=ScheduleExceptionRead)
async def get_scheduleException(entity_id: UUID, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(require_permissions(SCHEDULES_VIEW))):
    return await ScheduleExceptionService(db).get(tenant_id, entity_id)


appointmentType_router = APIRouter()

@appointmentType_router.post("", response_model=AppointmentTypeRead, status_code=status.HTTP_201_CREATED)
async def create_appointmentType(body: AppointmentTypeCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(require_permissions(APPOINTMENTS_CREATE))):
    return await AppointmentTypeService(db).create(tenant_id, body, actor=user)

@appointmentType_router.get("", response_model=list[AppointmentTypeRead])
async def list_appointmentType(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 AppointmentTypeService(db).list(tenant_id, offset=pagination.offset, limit=pagination.page_size)

@appointmentType_router.get("/{entity_id}", response_model=AppointmentTypeRead)
async def get_appointmentType(entity_id: UUID, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(require_permissions(APPOINTMENTS_VIEW))):
    return await AppointmentTypeService(db).get(tenant_id, entity_id)


waitingListEntry_router = APIRouter()

@waitingListEntry_router.post("", response_model=WaitingListEntryRead, status_code=status.HTTP_201_CREATED)
async def create_waitingListEntry(body: WaitingListEntryCreate, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), user: CurrentUser = Depends(require_permissions(WAITING_LIST_CREATE))):
    return await WaitingListEntryService(db).create(tenant_id, body, actor=user)

@waitingListEntry_router.get("", response_model=list[WaitingListEntryRead])
async def list_waitingListEntry(tenant_id: UUID = Depends(require_tenant), pagination: PaginationParams = Depends(get_pagination), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(require_permissions(WAITING_LIST_VIEW))):
    return await WaitingListEntryService(db).list(tenant_id, offset=pagination.offset, limit=pagination.page_size)

@waitingListEntry_router.get("/{entity_id}", response_model=WaitingListEntryRead)
async def get_waitingListEntry(entity_id: UUID, tenant_id: UUID = Depends(require_tenant), db: AsyncSession = Depends(get_db), _user: CurrentUser = Depends(require_permissions(WAITING_LIST_VIEW))):
    return await WaitingListEntryService(db).get(tenant_id, entity_id)
