"""Hospitality foundation DTOs — Phase 12.0."""
from __future__ import annotations

from datetime import datetime
from uuid import UUID

from pydantic import BaseModel, Field

from app.models.types import (
    BundleKey,
    BundleStatus,
    LifecycleStatus,
    MenuStatus,
    TableStatus,
    VenueFormat,
)
from app.schemas.common import ORMBase


class VenueCreate(BaseModel):
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.DRAFT
    venue_format: VenueFormat = VenueFormat.RESTAURANT
    legal_name: str | None = Field(default=None, max_length=255)
    timezone: str = Field(default="Asia/Tehran", max_length=64)
    language: str = Field(default="fa", max_length=16)
    currency_code: str = Field(default="IRR", max_length=3)
    settings: dict | None = None


class VenueUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    venue_format: VenueFormat | None = None
    legal_name: str | None = Field(default=None, max_length=255)
    timezone: str | None = Field(default=None, max_length=64)
    language: str | None = Field(default=None, max_length=16)
    currency_code: str | None = Field(default=None, max_length=3)
    settings: dict | None = None
    version: int | None = None


class VenueRead(ORMBase):
    id: UUID
    tenant_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    venue_format: VenueFormat
    legal_name: str | None
    timezone: str
    language: str
    currency_code: str
    settings: dict | None
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class BranchCreate(BaseModel):
    venue_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    address: dict | None = None
    timezone: str | None = Field(default=None, max_length=64)
    working_hours: dict | None = None
    metadata_json: dict | None = None


class BranchUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: LifecycleStatus | None = None
    address: dict | None = None
    timezone: str | None = Field(default=None, max_length=64)
    working_hours: dict | None = None
    metadata_json: dict | None = None


class BranchRead(ORMBase):
    id: UUID
    tenant_id: UUID
    venue_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    address: dict | None
    timezone: str | None
    working_hours: dict | None
    metadata_json: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class DiningAreaCreate(BaseModel):
    venue_id: UUID
    branch_id: UUID | None = None
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    sort_order: int = 0
    metadata_json: dict | None = None


class DiningAreaRead(ORMBase):
    id: UUID
    tenant_id: UUID
    venue_id: UUID
    branch_id: UUID | None
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    sort_order: int
    metadata_json: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class DiningTableCreate(BaseModel):
    venue_id: UUID
    dining_area_id: UUID | None = None
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    capacity: int = 2
    status: TableStatus = TableStatus.AVAILABLE
    qr_token: str | None = Field(default=None, max_length=100)
    metadata_json: dict | None = None


class DiningTableRead(ORMBase):
    id: UUID
    tenant_id: UUID
    venue_id: UUID
    dining_area_id: UUID | None
    code: str
    name: str
    capacity: int
    status: TableStatus
    qr_token: str | None
    metadata_json: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class MenuCreate(BaseModel):
    venue_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: MenuStatus = MenuStatus.DRAFT
    currency_code: str = Field(default="IRR", max_length=3)
    is_default: bool = False
    metadata_json: dict | None = None


class MenuUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    description: str | None = None
    status: MenuStatus | None = None
    currency_code: str | None = Field(default=None, max_length=3)
    is_default: bool | None = None
    metadata_json: dict | None = None
    version: int | None = None


class MenuRead(ORMBase):
    id: UUID
    tenant_id: UUID
    venue_id: UUID
    code: str
    name: str
    description: str | None
    status: MenuStatus
    currency_code: str
    is_default: bool
    metadata_json: dict | None
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class MenuCategoryCreate(BaseModel):
    venue_id: UUID
    menu_id: UUID
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    sort_order: int = 0


class MenuCategoryRead(ORMBase):
    id: UUID
    tenant_id: UUID
    venue_id: UUID
    menu_id: UUID
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    sort_order: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class MenuItemCreate(BaseModel):
    venue_id: UUID
    menu_id: UUID
    category_id: UUID | None = None
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    base_price: int = 0
    currency_code: str = Field(default="IRR", max_length=3)
    is_available: bool = True
    sort_order: int = 0
    attributes: dict | None = None
    preparation_minutes: int | None = None
    calories: int | None = None
    spicy_level: int = 0
    is_vegetarian: bool = False
    is_vegan: bool = False
    is_gluten_free: bool = False
    tags: list[str] | None = None
    primary_media_ref: str | None = Field(default=None, max_length=255)


class MenuItemRead(ORMBase):
    id: UUID
    tenant_id: UUID
    venue_id: UUID
    menu_id: UUID
    category_id: UUID | None
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    base_price: int
    currency_code: str
    is_available: bool
    sort_order: int
    attributes: dict | None
    preparation_minutes: int | None
    calories: int | None
    spicy_level: int
    is_vegetarian: bool
    is_vegan: bool
    is_gluten_free: bool
    tags: list | None
    primary_media_ref: str | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class BundleDefinitionCreate(BaseModel):
    code: str = Field(max_length=50)
    bundle_key: BundleKey
    name: str = Field(max_length=255)
    description: str | None = None
    status: BundleStatus = BundleStatus.AVAILABLE
    feature_keys: list[str] | None = None
    permission_prefixes: list[str] | None = None
    api_prefixes: list[str] | None = None
    metadata_json: dict | None = None


class BundleDefinitionRead(ORMBase):
    id: UUID
    tenant_id: UUID
    code: str
    bundle_key: BundleKey
    name: str
    description: str | None
    status: BundleStatus
    feature_keys: list | None
    permission_prefixes: list | None
    api_prefixes: list | None
    metadata_json: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class TenantBundleActivate(BaseModel):
    bundle_definition_id: UUID
    venue_id: UUID | None = None
    metadata_json: dict | None = None


class TenantBundleRead(ORMBase):
    id: UUID
    tenant_id: UUID
    venue_id: UUID | None
    bundle_definition_id: UUID
    bundle_key: BundleKey
    status: BundleStatus
    activated_by: str | None
    metadata_json: dict | None
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class FeatureToggleUpsert(BaseModel):
    feature_key: str = Field(max_length=100)
    enabled: bool = False
    venue_id: UUID | None = None
    bundle_key: BundleKey | None = None
    metadata_json: dict | None = None


class FeatureToggleRead(ORMBase):
    id: UUID
    tenant_id: UUID
    venue_id: UUID | None
    feature_key: str
    enabled: bool
    bundle_key: BundleKey | None
    metadata_json: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class HospitalityRoleCreate(BaseModel):
    venue_id: UUID | None = None
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    description: str | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE
    permission_keys: list[str] | None = None


class HospitalityRoleRead(ORMBase):
    id: UUID
    tenant_id: UUID
    venue_id: UUID | None
    code: str
    name: str
    description: str | None
    status: LifecycleStatus
    permission_keys: list | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class HospitalityPermissionCreate(BaseModel):
    code: str = Field(max_length=100)
    name: str = Field(max_length=255)
    description: str | None = None
    bundle_key: BundleKey | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE


class HospitalityPermissionRead(ORMBase):
    id: UUID
    tenant_id: UUID
    code: str
    name: str
    description: str | None
    bundle_key: BundleKey | None
    status: LifecycleStatus
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class HospitalityConfigurationCreate(BaseModel):
    venue_id: UUID | None = None
    branch_id: UUID | None = None
    code: str = Field(max_length=50)
    name: str = Field(max_length=255)
    config: dict | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE


class HospitalityConfigurationUpdate(BaseModel):
    name: str | None = Field(default=None, max_length=255)
    config: dict | None = None
    status: LifecycleStatus | None = None
    version: int | None = None


class HospitalityConfigurationRead(ORMBase):
    id: UUID
    tenant_id: UUID
    venue_id: UUID | None
    branch_id: UUID | None
    code: str
    name: str
    config: dict | None
    status: LifecycleStatus
    version: int
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class HospitalityEventCreate(BaseModel):
    venue_id: UUID
    event_type: str = Field(max_length=100)
    title: str = Field(max_length=255)
    payload: dict | None = None
    status: LifecycleStatus = LifecycleStatus.ACTIVE


class HospitalityEventRead(ORMBase):
    id: UUID
    tenant_id: UUID
    venue_id: UUID
    event_type: str
    title: str
    payload: dict | None
    status: LifecycleStatus
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime


class HospitalitySettingUpsert(BaseModel):
    key: str = Field(max_length=100)
    value: dict | None = None
    venue_id: UUID | None = None


class HospitalitySettingRead(ORMBase):
    id: UUID
    tenant_id: UUID
    venue_id: UUID | None
    key: str
    value: dict | None
    is_deleted: bool
    created_by: str | None
    updated_by: str | None
    created_at: datetime
    updated_at: datetime
