"""Digital Menu Catalog APIs — Phase 12.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.core.security import get_current_user
from app.schemas.catalog import (
    AllergenCreate,
    AllergenRead,
    AvailabilityWindowCreate,
    AvailabilityWindowRead,
    MenuItemAllergenLinkCreate,
    MenuItemAllergenLinkRead,
    MenuItemModifierLinkCreate,
    MenuItemModifierLinkRead,
    MenuLocalizationRead,
    MenuLocalizationUpsert,
    MenuMediaRefCreate,
    MenuMediaRefRead,
    ModifierGroupCreate,
    ModifierGroupRead,
    ModifierOptionCreate,
    ModifierOptionRead,
)
from app.services.catalog import (
    AllergenService,
    AvailabilityWindowService,
    MenuItemAllergenService,
    MenuItemModifierService,
    MenuLocalizationService,
    MenuMediaRefService,
    ModifierGroupService,
    ModifierOptionService,
)
from shared.pagination import PaginationParams
from shared.security import CurrentUser

allergens_router = APIRouter()
modifier_groups_router = APIRouter()
modifier_options_router = APIRouter()
menu_item_modifiers_router = APIRouter()
menu_item_allergens_router = APIRouter()
availability_windows_router = APIRouter()
menu_media_refs_router = APIRouter()
menu_localizations_router = APIRouter()


@allergens_router.post("", response_model=AllergenRead, status_code=status.HTTP_201_CREATED)
async def create_allergen(
    body: AllergenCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await AllergenService(db).create(tenant_id, body, actor=user)


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


@allergens_router.get("/{allergen_id}", response_model=AllergenRead)
async def get_allergen(
    allergen_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await AllergenService(db).get(tenant_id, allergen_id)


@modifier_groups_router.post("", response_model=ModifierGroupRead, status_code=status.HTTP_201_CREATED)
async def create_modifier_group(
    body: ModifierGroupCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await ModifierGroupService(db).create(tenant_id, body, actor=user)


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


@modifier_groups_router.get("/{group_id}", response_model=ModifierGroupRead)
async def get_modifier_group(
    group_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await ModifierGroupService(db).get(tenant_id, group_id)


@modifier_options_router.post("", response_model=ModifierOptionRead, status_code=status.HTTP_201_CREATED)
async def create_modifier_option(
    body: ModifierOptionCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await ModifierOptionService(db).create(tenant_id, body, actor=user)


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


@modifier_options_router.get("/{option_id}", response_model=ModifierOptionRead)
async def get_modifier_option(
    option_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await ModifierOptionService(db).get(tenant_id, option_id)


@menu_item_modifiers_router.post("/link", response_model=MenuItemModifierLinkRead, status_code=status.HTTP_201_CREATED)
async def link_modifier(
    body: MenuItemModifierLinkCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await MenuItemModifierService(db).link(tenant_id, body, actor=user)


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


@menu_item_allergens_router.post("/link", response_model=MenuItemAllergenLinkRead, status_code=status.HTTP_201_CREATED)
async def link_allergen(
    body: MenuItemAllergenLinkCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await MenuItemAllergenService(db).link(tenant_id, body, actor=user)


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


@availability_windows_router.post("", response_model=AvailabilityWindowRead, status_code=status.HTTP_201_CREATED)
async def create_window(
    body: AvailabilityWindowCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await AvailabilityWindowService(db).create(tenant_id, body, actor=user)


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


@availability_windows_router.get("/{window_id}", response_model=AvailabilityWindowRead)
async def get_window(
    window_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await AvailabilityWindowService(db).get(tenant_id, window_id)


@menu_media_refs_router.post("", response_model=MenuMediaRefRead, status_code=status.HTTP_201_CREATED)
async def create_media(
    body: MenuMediaRefCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await MenuMediaRefService(db).create(tenant_id, body, actor=user)


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


@menu_media_refs_router.get("/{media_id}", response_model=MenuMediaRefRead)
async def get_media(
    media_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await MenuMediaRefService(db).get(tenant_id, media_id)


@menu_localizations_router.post("/upsert", response_model=MenuLocalizationRead)
async def upsert_localization(
    body: MenuLocalizationUpsert,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await MenuLocalizationService(db).upsert(tenant_id, body, actor=user)


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


@menu_localizations_router.get("/{localization_id}", response_model=MenuLocalizationRead)
async def get_localization(
    localization_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await MenuLocalizationService(db).get(tenant_id, localization_id)
