"""Table Service & Reservations APIs — Phase 12.3."""
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.core.security import get_current_user
from app.schemas.table_service import (
    ReservationCreate,
    ReservationRead,
    ReservationStatusUpdate,
    ServiceRequestCreate,
    ServiceRequestRead,
    ServiceRequestStatusUpdate,
    TableAssignmentCreate,
    TableAssignmentRead,
    WaitlistEntryCreate,
    WaitlistEntryRead,
    WaitlistEntryStatusUpdate,
)
from app.services.table_service import (
    ReservationService,
    ServiceRequestService,
    TableAssignmentService,
    WaitlistEntryService,
)
from shared.pagination import PaginationParams
from shared.security import CurrentUser

reservations_router = APIRouter()
table_assignments_router = APIRouter()
service_requests_router = APIRouter()
waitlist_router = APIRouter()


@reservations_router.post("", response_model=ReservationRead, status_code=status.HTTP_201_CREATED)
async def create_reservation(
    body: ReservationCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await ReservationService(db).create(tenant_id, body, actor=user)


@reservations_router.get("", response_model=list[ReservationRead])
async def list_reservations(
    tenant_id: UUID = Depends(require_tenant),
    pagination: PaginationParams = Depends(get_pagination),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await ReservationService(db).list(tenant_id, offset=pagination.offset, limit=pagination.page_size)


@reservations_router.get("/{reservation_id}", response_model=ReservationRead)
async def get_reservation(
    reservation_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await ReservationService(db).get(tenant_id, reservation_id)


@reservations_router.post("/{reservation_id}/status", response_model=ReservationRead)
async def change_reservation_status(
    reservation_id: UUID,
    body: ReservationStatusUpdate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await ReservationService(db).change_status(
        tenant_id, reservation_id, body.status, actor=user
    )


@table_assignments_router.post(
    "", response_model=TableAssignmentRead, status_code=status.HTTP_201_CREATED
)
async def create_table_assignment(
    body: TableAssignmentCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await TableAssignmentService(db).create(tenant_id, body, actor=user)


@table_assignments_router.get("", response_model=list[TableAssignmentRead])
async def list_table_assignments(
    tenant_id: UUID = Depends(require_tenant),
    pagination: PaginationParams = Depends(get_pagination),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await TableAssignmentService(db).list(
        tenant_id, offset=pagination.offset, limit=pagination.page_size
    )


@table_assignments_router.get("/{assignment_id}", response_model=TableAssignmentRead)
async def get_table_assignment(
    assignment_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await TableAssignmentService(db).get(tenant_id, assignment_id)


@table_assignments_router.post("/{assignment_id}/release", response_model=TableAssignmentRead)
async def release_table_assignment(
    assignment_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await TableAssignmentService(db).release(tenant_id, assignment_id, actor=user)


@service_requests_router.post(
    "", response_model=ServiceRequestRead, status_code=status.HTTP_201_CREATED
)
async def create_service_request(
    body: ServiceRequestCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await ServiceRequestService(db).create(tenant_id, body, actor=user)


@service_requests_router.get("", response_model=list[ServiceRequestRead])
async def list_service_requests(
    tenant_id: UUID = Depends(require_tenant),
    pagination: PaginationParams = Depends(get_pagination),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await ServiceRequestService(db).list(
        tenant_id, offset=pagination.offset, limit=pagination.page_size
    )


@service_requests_router.get("/{request_id}", response_model=ServiceRequestRead)
async def get_service_request(
    request_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await ServiceRequestService(db).get(tenant_id, request_id)


@service_requests_router.post("/{request_id}/status", response_model=ServiceRequestRead)
async def change_service_request_status(
    request_id: UUID,
    body: ServiceRequestStatusUpdate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await ServiceRequestService(db).change_status(
        tenant_id, request_id, body.status, actor=user
    )


@waitlist_router.post("", response_model=WaitlistEntryRead, status_code=status.HTTP_201_CREATED)
async def create_waitlist_entry(
    body: WaitlistEntryCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await WaitlistEntryService(db).create(tenant_id, body, actor=user)


@waitlist_router.get("", response_model=list[WaitlistEntryRead])
async def list_waitlist_entries(
    tenant_id: UUID = Depends(require_tenant),
    pagination: PaginationParams = Depends(get_pagination),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await WaitlistEntryService(db).list(
        tenant_id, offset=pagination.offset, limit=pagination.page_size
    )


@waitlist_router.get("/{entry_id}", response_model=WaitlistEntryRead)
async def get_waitlist_entry(
    entry_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await WaitlistEntryService(db).get(tenant_id, entry_id)


@waitlist_router.post("/{entry_id}/status", response_model=WaitlistEntryRead)
async def change_waitlist_entry_status(
    entry_id: UUID,
    body: WaitlistEntryStatusUpdate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await WaitlistEntryService(db).change_status(
        tenant_id, entry_id, body.status, actor=user
    )
