"""Hospitality domain enums and dialect-safe GUID type."""
from __future__ import annotations

import enum
import uuid

from sqlalchemy.dialects.postgresql import UUID as PG_UUID
from sqlalchemy.types import CHAR, TypeDecorator


class GUID(TypeDecorator):
    impl = CHAR
    cache_ok = True

    def load_dialect_impl(self, dialect):
        if dialect.name == "postgresql":
            return dialect.type_descriptor(PG_UUID(as_uuid=True))
        return dialect.type_descriptor(CHAR(36))

    def process_bind_param(self, value, dialect):
        if value is None:
            return value
        if dialect.name == "postgresql":
            return value if isinstance(value, uuid.UUID) else uuid.UUID(str(value))
        return str(value)

    def process_result_value(self, value, dialect):
        if value is None:
            return value
        if isinstance(value, uuid.UUID):
            return value
        return uuid.UUID(str(value))


class LifecycleStatus(str, enum.Enum):
    DRAFT = "draft"
    ACTIVE = "active"
    INACTIVE = "inactive"
    SUSPENDED = "suspended"
    ARCHIVED = "archived"


class VenueFormat(str, enum.Enum):
    """Configurable venue formats — never hardcoded business engines."""

    CAFE = "cafe"
    COFFEE_SHOP = "coffee_shop"
    RESTAURANT = "restaurant"
    FAST_FOOD = "fast_food"
    BAKERY = "bakery"
    PASTRY = "pastry"
    ICE_CREAM = "ice_cream"
    JUICE_BAR = "juice_bar"
    CLOUD_KITCHEN = "cloud_kitchen"
    FOOD_COURT = "food_court"
    CATERING = "catering"
    TAKE_AWAY = "take_away"
    OTHER = "other"


class BundleKey(str, enum.Enum):
    """Licensable feature bundles — activation is tenant-scoped."""

    DIGITAL_MENU = "digital_menu"
    QR_MENU = "qr_menu"
    QR_ORDERING = "qr_ordering"
    POS_LITE = "pos_lite"
    POS_PRO = "pos_pro"
    KITCHEN = "kitchen"
    RESERVATION = "reservation"
    TABLE_SERVICE = "table_service"
    DELIVERY_CONNECTOR = "delivery_connector"
    ACCOUNTING_CONNECTOR = "accounting_connector"
    CRM_CONNECTOR = "crm_connector"
    LOYALTY_CONNECTOR = "loyalty_connector"
    COMMUNICATION_CONNECTOR = "communication_connector"
    WEBSITE_CONNECTOR = "website_connector"
    ANALYTICS = "analytics"
    AI_ASSISTANT = "ai_assistant"


class BundleStatus(str, enum.Enum):
    AVAILABLE = "available"
    ACTIVE = "active"
    SUSPENDED = "suspended"
    RETIRED = "retired"


class TableStatus(str, enum.Enum):
    AVAILABLE = "available"
    OCCUPIED = "occupied"
    RESERVED = "reserved"
    CLEANING = "cleaning"
    OUT_OF_SERVICE = "out_of_service"


class MenuStatus(str, enum.Enum):
    DRAFT = "draft"
    PUBLISHED = "published"
    ARCHIVED = "archived"


class AuditAction(str, enum.Enum):
    CREATE = "create"
    UPDATE = "update"
    DELETE = "delete"
    RESTORE = "restore"
    STATUS_CHANGE = "status_change"
    ACTIVATE = "activate"
    DEACTIVATE = "deactivate"
    LINK = "link"
    UNLINK = "unlink"


class ModifierSelectionMode(str, enum.Enum):
    SINGLE = "single"
    MULTIPLE = "multiple"


class MediaKind(str, enum.Enum):
    IMAGE = "image"
    VIDEO = "video"
    THUMBNAIL = "thumbnail"
    ICON = "icon"
    OTHER = "other"


class AvailabilityScope(str, enum.Enum):
    MENU = "menu"
    CATEGORY = "category"
    ITEM = "item"


class LocalizationTarget(str, enum.Enum):
    MENU = "menu"
    CATEGORY = "category"
    ITEM = "item"
    MODIFIER_GROUP = "modifier_group"
    MODIFIER_OPTION = "modifier_option"
    ALLERGEN = "allergen"


# Phase 12.2 — QR Menu & QR Ordering shells
class QrTargetType(str, enum.Enum):
    VENUE = "venue"
    MENU = "menu"
    DINING_AREA = "dining_area"
    TABLE = "table"


class QrSessionStatus(str, enum.Enum):
    OPEN = "open"
    CLOSED = "closed"
    EXPIRED = "expired"
    CANCELLED = "cancelled"


class OrderingSessionStatus(str, enum.Enum):
    DRAFT = "draft"
    OPEN = "open"
    SUBMITTED = "submitted"
    CANCELLED = "cancelled"
    CLOSED = "closed"


class CartStatus(str, enum.Enum):
    ACTIVE = "active"
    CHECKED_OUT = "checked_out"
    ABANDONED = "abandoned"
    CANCELLED = "cancelled"


# Phase 12.3 — Table Service & Reservations
class ReservationStatus(str, enum.Enum):
    PENDING = "pending"
    CONFIRMED = "confirmed"
    SEATED = "seated"
    COMPLETED = "completed"
    CANCELLED = "cancelled"
    NO_SHOW = "no_show"


class TableAssignmentStatus(str, enum.Enum):
    ACTIVE = "active"
    RELEASED = "released"
    TRANSFERRED = "transferred"


class ServiceRequestKind(str, enum.Enum):
    CALL_WAITER = "call_waiter"
    WATER = "water"
    BILL = "bill"
    OTHER = "other"


class ServiceRequestStatus(str, enum.Enum):
    OPEN = "open"
    ACKNOWLEDGED = "acknowledged"
    CLOSED = "closed"
    CANCELLED = "cancelled"


class WaitlistStatus(str, enum.Enum):
    WAITING = "waiting"
    SEATED = "seated"
    CANCELLED = "cancelled"
    EXPIRED = "expired"


# Phase 12.4 — POS Lite
class PosShiftStatus(str, enum.Enum):
    OPEN = "open"
    CLOSED = "closed"


class PosTicketStatus(str, enum.Enum):
    DRAFT = "draft"
    OPEN = "open"
    PAID = "paid"
    VOID = "void"
    CANCELLED = "cancelled"


# Phase 12.5 — POS Pro
class PosPaymentMethod(str, enum.Enum):
    CASH = "cash"
    CARD = "card"
    OTHER = "other"


class PosDiscountKind(str, enum.Enum):
    PERCENT = "percent"
    FIXED = "fixed"


# Phase 12.6 — Kitchen
class KitchenTicketSource(str, enum.Enum):
    POS_TICKET = "pos_ticket"
    ORDERING_SESSION = "ordering_session"


class KitchenTicketStatus(str, enum.Enum):
    QUEUED = "queued"
    PREPARING = "preparing"
    READY = "ready"
    BUMPED = "bumped"
    CANCELLED = "cancelled"


class KitchenItemStatus(str, enum.Enum):
    QUEUED = "queued"
    PREPARING = "preparing"
    READY = "ready"
    BUMPED = "bumped"
    CANCELLED = "cancelled"


# Phase 12.7 — Connectors
class ConnectorKind(str, enum.Enum):
    DELIVERY = "delivery"
    ACCOUNTING = "accounting"
    CRM = "crm"
    LOYALTY = "loyalty"
    COMMUNICATION = "communication"
    WEBSITE = "website"


class ConnectorStatus(str, enum.Enum):
    DRAFT = "draft"
    ACTIVE = "active"
    SUSPENDED = "suspended"
    RETIRED = "retired"


class DispatchStatus(str, enum.Enum):
    PENDING = "pending"
    SENT = "sent"
    FAILED = "failed"
    ACKED = "acked"


class DispatchDirection(str, enum.Enum):
    OUTBOUND = "outbound"


# Phase 12.9 — AI Assistant
class AiRequestStatus(str, enum.Enum):
    PENDING = "pending"
    COMPLETED = "completed"
    FAILED = "failed"
