import uuid
from datetime import datetime

from sqlmodel import Field, SQLModel

from app.db.base import TenantModel
from app.utils.tz import UtcDatetime


class ReservationBase(SQLModel):
    guest_name: str = Field(nullable=False)
    guest_email: str | None = Field(default=None)
    guest_phone: str | None = Field(default=None)
    party_size: int = Field(ge=1, le=20, nullable=False)
    reserved_at: UtcDatetime = Field(nullable=False)
    end_time: UtcDatetime = Field(nullable=False)
    completed_at: UtcDatetime | None = Field(default=None, nullable=True)
    notes: str | None = Field(default=None)
    operator_comment: str | None = Field(default=None)
    status: str = Field(default="pending", index=True, nullable=False)
    source: str = Field(default="manual", nullable=False)
    table_auto_assigned: bool | None = Field(default=True, nullable=True)


class Reservation(ReservationBase, TenantModel, table=True):
    __tablename__ = "reservation"

    id: str = Field(
        default_factory=lambda: str(uuid.uuid4()),
        primary_key=True,
    )
    customer_id: str | None = Field(
        default=None,
        foreign_key="customer.id",
        index=True,
        nullable=True,
    )
    table_id: str | None = Field(
        default=None,
        foreign_key="floor_table.id",
        index=True,
        nullable=True,
    )
    combination_id: str | None = Field(
        default=None,
        nullable=True,
    )
    served_at: UtcDatetime | None = Field(default=None, nullable=True)


class ReservationCreate(ReservationBase):
    table_id: str | None = None
    combination_id: str | None = None
    dishes: list[dict] | None = None  # Menu-mode: [{menu_item_id, quantity}]
    dishes_text: str | None = None  # Free-text mode dish description


class ReservationRead(ReservationBase):
    id: str
    restaurant_id: str
    customer_id: str | None = None
    end_time: UtcDatetime
    table_id: str | None = None
    combination_id: str | None = None
    table_auto_assigned: bool | None = None
    served_at: UtcDatetime | None = None
    completed_at: UtcDatetime | None = None
    operator_comment: str | None = None


class ReservationPatch(SQLModel):
    """Partial update schema — only set fields are applied."""

    guest_name: str | None = None
    guest_email: str | None = None
    guest_phone: str | None = None
    party_size: int | None = Field(default=None, ge=1, le=20)
    reserved_at: datetime | None = None
    notes: str | None = None
    end_time: datetime | None = None
    table_id: str | None = None
    combination_id: str | None = None
    table_auto_assigned: bool | None = None
    completed_at: datetime | None = None


class ReservationActionResponse(SQLModel):
    """Response for approve/reject actions."""

    id: str
    status: str


class ReservationApprovalRequest(SQLModel):
    """Optional body for approve/reject actions."""

    comment: str | None = None


class MoveReservationRequest(SQLModel):
    """Request body for moving a reservation to a different table or combination."""

    table_id: str | None = None
    combination_id: str | None = None
