"""QR Menu & QR Ordering APIs — Phase 12.2."""
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.qr import (
    CartCreate,
    CartLineCreate,
    CartLineRead,
    CartRead,
    QrCodeCreate,
    QrCodeRead,
    QrMenuSessionCreate,
    QrMenuSessionRead,
    QrOrderingSessionCreate,
    QrOrderingSessionRead,
)
from app.services.qr import (
    CartLineService,
    CartService,
    QrCodeService,
    QrMenuSessionService,
    QrOrderingSessionService,
)
from shared.pagination import PaginationParams
from shared.security import CurrentUser

qr_codes_router = APIRouter()
qr_menu_sessions_router = APIRouter()
qr_ordering_sessions_router = APIRouter()
carts_router = APIRouter()
cart_lines_router = APIRouter()


@qr_codes_router.post("", response_model=QrCodeRead, status_code=status.HTTP_201_CREATED)
async def create_qr_code(
    body: QrCodeCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await QrCodeService(db).create(tenant_id, body, actor=user)


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


@qr_codes_router.get("/by-token/{token}", response_model=QrCodeRead)
async def get_qr_code_by_token(
    token: str,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await QrCodeService(db).get_by_token(tenant_id, token)


@qr_codes_router.get("/{qr_code_id}", response_model=QrCodeRead)
async def get_qr_code(
    qr_code_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await QrCodeService(db).get(tenant_id, qr_code_id)


@qr_menu_sessions_router.post("", response_model=QrMenuSessionRead, status_code=status.HTTP_201_CREATED)
async def create_qr_menu_session(
    body: QrMenuSessionCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await QrMenuSessionService(db).create(tenant_id, body, actor=user)


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


@qr_menu_sessions_router.get("/by-token/{token}", response_model=QrMenuSessionRead)
async def get_qr_menu_session_by_token(
    token: str,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await QrMenuSessionService(db).get_by_token(tenant_id, token)


@qr_menu_sessions_router.get("/{session_id}", response_model=QrMenuSessionRead)
async def get_qr_menu_session(
    session_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await QrMenuSessionService(db).get(tenant_id, session_id)


@qr_ordering_sessions_router.post("", response_model=QrOrderingSessionRead, status_code=status.HTTP_201_CREATED)
async def create_qr_ordering_session(
    body: QrOrderingSessionCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await QrOrderingSessionService(db).create(tenant_id, body, actor=user)


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


@qr_ordering_sessions_router.get("/{session_id}", response_model=QrOrderingSessionRead)
async def get_qr_ordering_session(
    session_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await QrOrderingSessionService(db).get(tenant_id, session_id)


@qr_ordering_sessions_router.post("/{session_id}/submit", response_model=QrOrderingSessionRead)
async def submit_qr_ordering_session(
    session_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await QrOrderingSessionService(db).submit(tenant_id, session_id, actor=user)


@carts_router.post("", response_model=CartRead, status_code=status.HTTP_201_CREATED)
async def create_cart(
    body: CartCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await CartService(db).create(tenant_id, body, actor=user)


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


@carts_router.get("/{cart_id}", response_model=CartRead)
async def get_cart(
    cart_id: UUID,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    _user: CurrentUser = Depends(get_current_user),
):
    return await CartService(db).get(tenant_id, cart_id)


@cart_lines_router.post("", response_model=CartLineRead, status_code=status.HTTP_201_CREATED)
async def create_cart_line(
    body: CartLineCreate,
    tenant_id: UUID = Depends(require_tenant),
    db: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await CartLineService(db).add(tenant_id, body, actor=user)


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