"""Sports Center 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 MembershipStatus(str, enum.Enum):
    PENDING = "pending"
    ACTIVE = "active"
    FROZEN = "frozen"
    EXPIRED = "expired"
    SUSPENDED = "suspended"
    CANCELLED = "cancelled"


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


class FamilyRelationship(str, enum.Enum):
    SPOUSE = "spouse"
    PARENT = "parent"
    CHILD = "child"
    SIBLING = "sibling"
    GUARDIAN = "guardian"
    OTHER = "other"


class CardKind(str, enum.Enum):
    PHYSICAL = "physical"
    DIGITAL = "digital"
    QR = "qr"
    BARCODE = "barcode"


class CardStatus(str, enum.Enum):
    PENDING = "pending"
    ACTIVE = "active"
    REVOKED = "revoked"
    EXPIRED = "expired"
    LOST = "lost"


class WaiverStatus(str, enum.Enum):
    DRAFT = "draft"
    PENDING = "pending"
    SIGNED = "signed"
    EXPIRED = "expired"
    REVOKED = "revoked"


class DocumentKind(str, enum.Enum):
    ID = "id"
    PHOTO = "photo"
    MEDICAL = "medical"
    WAIVER = "waiver"
    CONTRACT = "contract"
    OTHER = "other"


class DeviceStatus(str, enum.Enum):
    REGISTERED = "registered"
    CONNECTED = "connected"
    DISCONNECTED = "disconnected"
    MAINTENANCE = "maintenance"
    RETIRED = "retired"


class LockerStatus(str, enum.Enum):
    AVAILABLE = "available"
    ASSIGNED = "assigned"
    MAINTENANCE = "maintenance"
    RETIRED = "retired"


class ConnectorCapability(str, enum.Enum):
    """Generic device/access capability kinds — never vendor-specific."""

    QR = "qr"
    RFID = "rfid"
    BARCODE = "barcode"
    FINGERPRINT = "fingerprint"
    FACE_RECOGNITION = "face_recognition"
    TURNSTILE = "turnstile"
    DOOR_CONTROLLER = "door_controller"
    PAYMENT_TERMINAL = "payment_terminal"
    ATTENDANCE_DEVICE = "attendance_device"
    CUSTOM = "custom"


class FacilityKind(str, enum.Enum):
    """Generic facility classification — no sport-specific rules."""

    GENERAL = "general"
    COURT = "court"
    ROOM = "room"
    POOL = "pool"
    FIELD = "field"
    STUDIO = "studio"
    OTHER = "other"


class AuditAction(str, enum.Enum):
    CREATE = "create"
    UPDATE = "update"
    DELETE = "delete"
    RESTORE = "restore"
    STATUS_CHANGE = "status_change"
    ASSIGN = "assign"
    RELEASE = "release"
    CONNECT = "connect"
    DISCONNECT = "disconnect"


class PricingModelKind(str, enum.Enum):
    """How catalog prices are expressed — amounts are config, not Accounting postings."""

    FIXED = "fixed"
    RECURRING = "recurring"
    TIERED = "tiered"
    USAGE = "usage"
    CUSTOM = "custom"


class BillingPeriod(str, enum.Enum):
    ONCE = "once"
    DAILY = "daily"
    WEEKLY = "weekly"
    MONTHLY = "monthly"
    QUARTERLY = "quarterly"
    YEARLY = "yearly"
    CUSTOM = "custom"


class RuleKind(str, enum.Enum):
    ELIGIBILITY = "eligibility"
    ACCESS = "access"
    USAGE = "usage"
    TRANSFER = "transfer"
    CUSTOM = "custom"


class StaffKind(str, enum.Enum):
    COACH = "coach"
    TRAINER = "trainer"
    NUTRITIONIST = "nutritionist"
    MEDICAL = "medical"
    RECEPTION = "reception"
    MANAGER = "manager"


class AssignmentKind(str, enum.Enum):
    MEMBER = "member"
    SPORT = "sport"
    PROGRAM = "program"


class BookingStatus(str, enum.Enum):
    PENDING = "pending"
    CONFIRMED = "confirmed"
    CANCELLED = "cancelled"
    COMPLETED = "completed"
    NO_SHOW = "no_show"


class SessionKind(str, enum.Enum):
    CLASS = "class"
    PRIVATE = "private"
    OPEN = "open"
    BLOCKED = "blocked"


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


class RecurrenceKind(str, enum.Enum):
    NONE = "none"
    DAILY = "daily"
    WEEKLY = "weekly"
    MONTHLY = "monthly"


class AttendanceKind(str, enum.Enum):
    CHECK_IN = "check_in"
    CHECK_OUT = "check_out"
    MANUAL = "manual"
    GATE = "gate"


class AttendanceStatus(str, enum.Enum):
    PRESENT = "present"
    LATE = "late"
    ABSENT = "absent"
    EXCUSED = "excused"


class AccessResult(str, enum.Enum):
    GRANTED = "granted"
    DENIED = "denied"


class ProgramStatus(str, enum.Enum):
    DRAFT = "draft"
    ACTIVE = "active"
    COMPLETED = "completed"
    ARCHIVED = "archived"


class WorkoutStatus(str, enum.Enum):
    DRAFT = "draft"
    ACTIVE = "active"
    COMPLETED = "completed"
    ARCHIVED = "archived"


class GoalStatus(str, enum.Enum):
    ACTIVE = "active"
    ACHIEVED = "achieved"
    ABANDONED = "abandoned"


class AssessmentKind(str, enum.Enum):
    FITNESS = "fitness"
    SKILL = "skill"
    BODY_COMPOSITION = "body_composition"
    CUSTOM = "custom"


class CompetitionKind(str, enum.Enum):
    TOURNAMENT = "tournament"
    LEAGUE = "league"
    MATCH_SERIES = "match_series"
    CUSTOM = "custom"


class CompetitionStatus(str, enum.Enum):
    DRAFT = "draft"
    SCHEDULED = "scheduled"
    ACTIVE = "active"
    COMPLETED = "completed"
    CANCELLED = "cancelled"


class RegistrationStatus(str, enum.Enum):
    PENDING = "pending"
    CONFIRMED = "confirmed"
    CANCELLED = "cancelled"
    WAITLISTED = "waitlisted"


class MatchStatus(str, enum.Enum):
    SCHEDULED = "scheduled"
    IN_PROGRESS = "in_progress"
    COMPLETED = "completed"
    CANCELLED = "cancelled"


class ResultOutcome(str, enum.Enum):
    WIN = "win"
    LOSS = "loss"
    DRAW = "draw"
    FORFEIT = "forfeit"
    NO_CONTEST = "no_contest"


class MedalKind(str, enum.Enum):
    GOLD = "gold"
    SILVER = "silver"
    BRONZE = "bronze"
    PARTICIPATION = "participation"
