"""Table combination models — grouping tables into combined seating arrangements."""

import uuid

from sqlalchemy import Column
from sqlalchemy.dialects.postgresql import JSONB
from sqlmodel import Field, SQLModel

from app.db.base import TenantModel


class TableCombinationBase(SQLModel):
    name: str = Field(nullable=False)
    # User-edited position of the merged combination rectangle on the
    # floor-plan editor canvas. `None` = no override → frontend falls
    # back to the centroid of the component tables.
    merged_x: float | None = Field(default=None, nullable=True)
    merged_y: float | None = Field(default=None, nullable=True)


class TableCombination(TableCombinationBase, TenantModel, table=True):
    """A named group of tables that form a combined seating arrangement.

    ``table_ids`` stores the ordered list of table UUIDs in the combination.
    ``combined_capacity`` is server-computed from enabled CombinedChairConfig rows.
    """

    __tablename__ = "table_combination"  # pyright: ignore[reportAssignmentType]

    id: str = Field(
        default_factory=lambda: str(uuid.uuid4()),
        primary_key=True,
    )
    table_ids: list[str] = Field(
        default_factory=list,
        sa_column=Column(JSONB, nullable=False),
    )
    combined_capacity: int = Field(default=0, nullable=False)


class TableCombinationCreate(TableCombinationBase):
    table_ids: list[str]


class TableCombinationUpdate(SQLModel):
    """Partial update — every field is optional so the same endpoint serves
    both ``name`` / ``table_ids`` rewrites and high-frequency position drag
    saves (which arrive with only `merged_x` / `merged_y`)."""

    name: str | None = None
    table_ids: list[str] | None = None
    merged_x: float | None = None
    merged_y: float | None = None


class TableCombinationRead(TableCombinationBase):
    id: str
    restaurant_id: str
    table_ids: list[str]
    combined_capacity: int
    chair_configs: list["CombinedChairConfigRead"] = []


# ── CombinedChairConfig ─────────────────────────────────────────────────────


class CombinedChairConfigBase(SQLModel):
    slot_index: int = Field(ge=0, nullable=False)
    side: str = Field(nullable=False)
    enabled: bool = Field(default=True, nullable=False)


class CombinedChairConfig(CombinedChairConfigBase, table=True):
    """Combo-scoped chair override — one row per chair slot per table in the combo."""

    __tablename__ = "combined_chair_config"  # pyright: ignore[reportAssignmentType]

    id: str = Field(
        default_factory=lambda: str(uuid.uuid4()),
        primary_key=True,
    )
    combination_id: str = Field(
        foreign_key="table_combination.id",
        index=True,
        nullable=False,
    )
    table_id: str = Field(
        foreign_key="floor_table.id",
        index=True,
        nullable=False,
    )
    restaurant_id: str = Field(foreign_key="restaurant.id", index=True, nullable=False)


class CombinedChairConfigRead(CombinedChairConfigBase):
    id: str
    combination_id: str
    table_id: str


class CombinedChairConfigUpdate(SQLModel):
    """Partial update — only ``enabled`` can be toggled."""

    enabled: bool
