"""Loyalty 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 ProgramStatus(str, enum.Enum):
    DRAFT = "draft"
    ACTIVE = "active"
    SUSPENDED = "suspended"
    ARCHIVED = "archived"


class MemberStatus(str, enum.Enum):
    PENDING = "pending"
    ACTIVE = "active"
    SUSPENDED = "suspended"  # 7.0 compat; treated as frozen for lifecycle
    FROZEN = "frozen"
    EXPIRED = "expired"
    CANCELLED = "cancelled"
    TRANSFERRED = "transferred"
    CLOSED = "closed"


class MembershipLifecycleAction(str, enum.Enum):
    ENROLL = "enroll"
    ACTIVATE = "activate"
    RENEW = "renew"
    FREEZE = "freeze"
    RESUME = "resume"
    TRANSFER = "transfer"
    CANCEL = "cancel"
    EXPIRE = "expire"


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


class PointAccountStatus(str, enum.Enum):
    OPEN = "open"
    FROZEN = "frozen"
    CLOSED = "closed"


class LedgerEntryType(str, enum.Enum):
    EARN = "earn"
    REDEEM = "redeem"
    ADJUST = "adjust"
    EXPIRE = "expire"


class RewardType(str, enum.Enum):
    COUPON = "coupon"
    DISCOUNT = "discount"
    CASHBACK = "cashback"
    VOUCHER = "voucher"
    GIFT = "gift"
    CUSTOM = "custom"


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


class CampaignStatus(str, enum.Enum):
    DRAFT = "draft"
    SCHEDULED = "scheduled"
    ACTIVE = "active"
    PAUSED = "paused"
    EXPIRED = "expired"
    ARCHIVED = "archived"


class WalletAccountStatus(str, enum.Enum):
    OPEN = "open"
    FROZEN = "frozen"
    CLOSED = "closed"


class WalletLedgerEntryType(str, enum.Enum):
    CREDIT = "credit"
    DEBIT = "debit"
    ADJUST = "adjust"
    TRANSFER_IN = "transfer_in"
    TRANSFER_OUT = "transfer_out"


class RedemptionStatus(str, enum.Enum):
    PENDING = "pending"
    FULFILLED = "fulfilled"
    CANCELLED = "cancelled"
    EXPIRED = "expired"


class CampaignApplicationStatus(str, enum.Enum):
    APPLIED = "applied"
    REVERSED = "reversed"


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


class ReferralCodeStatus(str, enum.Enum):
    ACTIVE = "active"
    REVOKED = "revoked"


class ReferralAttributionStatus(str, enum.Enum):
    PENDING = "pending"
    CONVERTED = "converted"
    REWARDED = "rewarded"
    CANCELLED = "cancelled"


class AuditAction(str, enum.Enum):
    CREATE = "create"
    UPDATE = "update"
    DELETE = "delete"
    RESTORE = "restore"
    STATUS_CHANGE = "status_change"
    ENROLL = "enroll"
    ASSIGN = "assign"
    ACTIVATE = "activate"
    RENEW = "renew"
    FREEZE = "freeze"
    RESUME = "resume"
    TRANSFER = "transfer"
    CANCEL = "cancel"
    EXPIRE = "expire"
    EARN = "earn"
    REDEEM = "redeem"
    ADJUST = "adjust"
    POINTS_EXPIRE = "points_expire"
    REDEEM_REWARD = "redeem_reward"
    FULFILL_REWARD = "fulfill_reward"
    CANCEL_REDEMPTION = "cancel_redemption"
    SCHEDULE = "schedule"
    PAUSE = "pause"
    APPLY = "apply"
    RULES_UPDATE = "rules_update"
    ISSUE_CODE = "issue_code"
    REVOKE_CODE = "revoke_code"
    ATTRIBUTE = "attribute"
    CONVERT = "convert"
    REWARD = "reward"
    WALLET_OPEN = "wallet_open"
    WALLET_CREDIT = "wallet_credit"
    WALLET_DEBIT = "wallet_debit"
    WALLET_ADJUST = "wallet_adjust"
    WALLET_TRANSFER = "wallet_transfer"
    WALLET_CLOSE = "wallet_close"
