"""Table and chair business logic — chair generation and reservation guards."""

from sqlalchemy.ext.asyncio import AsyncSession
from sqlmodel import select

from app.models.chair import Chair, ChairSide
from app.models.reservation import Reservation
from app.models.table import FloorTable, TableShape


def generate_chairs(table: FloorTable) -> list[Chair]:
    """Return new Chair instances for *table* based on its shape and slot_count.

    Generation rules (from spec):
    - **round**:     all chairs ``side="around"``
    - **square**:    chairs distributed evenly across top → right → bottom → left
    - **rectangle**: chairs split between ``top`` and ``bottom`` only
    """
    chairs: list[Chair] = []

    if table.shape == TableShape.ROUND:
        for i in range(table.slot_count):
            chairs.append(
                Chair(
                    table_id=table.id,
                    slot_index=i,
                    side=ChairSide.AROUND,
                    enabled=True,
                    restaurant_id=table.restaurant_id,
                )
            )

    elif table.shape == TableShape.SQUARE:
        sides = [ChairSide.TOP, ChairSide.RIGHT, ChairSide.BOTTOM, ChairSide.LEFT]
        for i in range(table.slot_count):
            chairs.append(
                Chair(
                    table_id=table.id,
                    slot_index=i,
                    side=sides[i % len(sides)],
                    enabled=True,
                    restaurant_id=table.restaurant_id,
                )
            )

    elif table.shape == TableShape.RECTANGLE:
        half = table.slot_count // 2
        remainder = table.slot_count % 2
        top_count = half + remainder  # odd seat goes to top
        for i in range(top_count):
            chairs.append(
                Chair(
                    table_id=table.id,
                    slot_index=i,
                    side=ChairSide.TOP,
                    enabled=True,
                    restaurant_id=table.restaurant_id,
                )
            )
        for i in range(half):
            chairs.append(
                Chair(
                    table_id=table.id,
                    slot_index=top_count + i,
                    side=ChairSide.BOTTOM,
                    enabled=True,
                    restaurant_id=table.restaurant_id,
                )
            )

    else:
        # Unknown shape — fall back to "around" like round tables
        for i in range(table.slot_count):
            chairs.append(
                Chair(
                    table_id=table.id,
                    slot_index=i,
                    side=ChairSide.AROUND,
                    enabled=True,
                    restaurant_id=table.restaurant_id,
                )
            )

    return chairs


async def has_future_reservations(session: AsyncSession, table_id: str) -> bool:
    """Return ``True`` if *table_id* has any pending/confirmed reservations in the future."""
    from sqlalchemy import func

    from app.models.restaurant import Restaurant

    # reserved_at is naive in restaurant-local time;
    # convert UTC now() to each restaurant's local time for comparison.
    local_now = func.timezone(Restaurant.timezone, func.now())
    result = await session.execute(
        select(Reservation.id)
        .join(Restaurant, Reservation.restaurant_id == Restaurant.id)  # type: ignore[arg-type]
        .where(
            Reservation.table_id == table_id,
            Reservation.status.in_(["pending", "confirmed"]),  # type: ignore[attr-defined]
            Reservation.reserved_at > local_now,
        )
        .limit(1)
    )
    return result.scalar_one_or_none() is not None
