"""Beauty Business 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 BusinessFormat(str, enum.Enum):
    SALON = "salon"
    BARBERSHOP = "barbershop"
    CLINIC = "clinic"
    LASER = "laser"
    SKIN_CARE = "skin_care"
    HAIR_TREATMENT = "hair_treatment"
    SPA = "spa"


class ProviderKind(str, enum.Enum):
    BOOKING_ENGINE = "booking_engine"
    CRM = "crm"
    LOYALTY = "loyalty"
    COMMUNICATION = "communication"
    ACCOUNTING = "accounting"
    DELIVERY = "delivery"
    EXPERIENCE = "experience"
    STORAGE = "storage"
    CUSTOM = "custom"


class ProviderStatus(str, enum.Enum):
    REGISTERED = "registered"
    ACTIVE = "active"
    INACTIVE = "inactive"
    FAILED = "failed"
    RETIRED = "retired"


class BookingEngineStatus(str, enum.Enum):
    REGISTERED = "registered"
    READY = "ready"
    ACTIVE = "active"
    DISABLED = "disabled"


class AuditAction(str, enum.Enum):
    CREATE = "create"
    UPDATE = "update"
    DELETE = "delete"
    RESTORE = "restore"
    STATUS_CHANGE = "status_change"
    REGISTER = "register"
    ENABLE = "enable"
    DISABLE = "disable"
    CONFIRM = "confirm"
    CHECK_IN = "check_in"
    COMPLETE = "complete"
    CANCEL = "cancel"
    NO_SHOW = "no_show"
    REDEEM = "redeem"
    DISPATCH = "dispatch"


class AppointmentStatus(str, enum.Enum):
    REQUESTED = "requested"
    CONFIRMED = "confirmed"
    CHECKED_IN = "checked_in"
    IN_PROGRESS = "in_progress"
    COMPLETED = "completed"
    CANCELLED = "cancelled"
    NO_SHOW = "no_show"


class AppointmentLifecycleAction(str, enum.Enum):
    CONFIRM = "confirm"
    CHECK_IN = "check_in"
    START = "start"
    COMPLETE = "complete"
    CANCEL = "cancel"
    NO_SHOW = "no_show"


class ScheduleExceptionKind(str, enum.Enum):
    CLOSED = "closed"
    CUSTOM_HOURS = "custom_hours"
    BREAK = "break"


class ResourceStatus(str, enum.Enum):
    AVAILABLE = "available"
    OCCUPIED = "occupied"
    MAINTENANCE = "maintenance"
    INACTIVE = "inactive"


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


class PackageStatus(str, enum.Enum):
    ACTIVE = "active"
    EXHAUSTED = "exhausted"
    EXPIRED = "expired"
    CANCELLED = "cancelled"


class MembershipStatus(str, enum.Enum):
    PENDING = "pending"
    ACTIVE = "active"
    FROZEN = "frozen"
    CANCELLED = "cancelled"
    EXPIRED = "expired"


class MembershipLifecycleAction(str, enum.Enum):
    ACTIVATE = "activate"
    FREEZE = "freeze"
    UNFREEZE = "unfreeze"
    CANCEL = "cancel"
    RENEW = "renew"


class StaffKind(str, enum.Enum):
    STYLIST = "stylist"
    BARBER = "barber"
    THERAPIST = "therapist"
    LASER_TECH = "laser_tech"
    RECEPTIONIST = "receptionist"
    MANAGER = "manager"
    OTHER = "other"


class CommissionStatus(str, enum.Enum):
    PENDING = "pending"
    ACCRUED = "accrued"
    PAID = "paid"
    VOID = "void"


class IntegrationDispatchStatus(str, enum.Enum):
    PENDING = "pending"
    SENT = "sent"
    FAILED = "failed"
    SKIPPED = "skipped"


class DayOfWeek(str, enum.Enum):
    MONDAY = "monday"
    TUESDAY = "tuesday"
    WEDNESDAY = "wednesday"
    THURSDAY = "thursday"
    FRIDAY = "friday"
    SATURDAY = "saturday"
    SUNDAY = "sunday"
