"""Enumerations used by SQLAlchemy models.

The string values map directly to the MySQL ``ENUM`` members defined in the
approved database design.
"""

import enum


class UserRole(enum.Enum):
    """Role assigned to a user account."""

    STUDENT = "student"
    SUPER_ADMIN = "super_admin"


class AccountStatus(enum.Enum):
    """Lifecycle status of a user account."""

    ACTIVE = "active"
    INACTIVE = "inactive"
    SUSPENDED = "suspended"
    BANNED = "banned"


class VerificationPurpose(enum.Enum):
    """Purpose of a one-time verification code.

    Drives the generic verification framework (see
    :mod:`app.auth.otp_service`). Codes are isolated per purpose so a
    password-reset code can never satisfy an email-verification check. Only
    ``EMAIL_VERIFICATION`` is wired to a live flow today; the rest are defined
    now so future authentication features (password reset, email change, login
    verification, 2FA) need only reference an existing purpose — no schema or
    framework change."""

    EMAIL_VERIFICATION = "email_verification"
    PASSWORD_RESET = "password_reset"
    EMAIL_CHANGE = "email_change"
    LOGIN_VERIFICATION = "login_verification"
    TWO_FACTOR = "two_factor"


class StudentVerificationStatus(enum.Enum):
    """Moderated "Verified Student" status.

    The Verified Student badge is **not** automatic: a student submits their
    university details and an administrator approves them. Distinct from email
    verification (``User.is_verified``), which never grants the badge."""

    NOT_VERIFIED = "not_verified"
    PENDING = "pending"
    VERIFIED = "verified"
    REJECTED = "rejected"


class VerificationHistoryAction(enum.Enum):
    """A single event in a student's verification lifecycle (audit trail)."""

    SUBMITTED = "submitted"
    APPROVED = "approved"
    REJECTED = "rejected"
    UPDATED = "updated"


class ListingCondition(enum.Enum):
    """Physical condition of a listed product."""

    NEW = "new"
    EXCELLENT = "excellent"
    GOOD = "good"
    FAIR = "fair"
    POOR = "poor"


class ListingStatus(enum.Enum):
    """Lifecycle status of a marketplace listing."""

    DRAFT = "draft"
    AVAILABLE = "available"
    RESERVED = "reserved"
    SOLD = "sold"
    EXPIRED = "expired"
    REMOVED = "removed"


class ListingVisibility(enum.Enum):
    """Whether a listing is shown publicly or hidden."""

    PUBLIC = "public"
    HIDDEN = "hidden"


class ReviewStatus(enum.Enum):
    """Moderation review result for a listing."""

    APPROVED = "approved"
    REJECTED = "rejected"


class OfferStatus(enum.Enum):
    """Lifecycle status of an offer.

    Phase 1 uses only ``PENDING``. The remaining states are defined now so the
    enum remains complete for later phases without introducing behavior yet.
    """

    PENDING = "pending"
    ACCEPTED = "accepted"
    REJECTED = "rejected"
    COUNTERED = "countered"
    WITHDRAWN = "withdrawn"
    EXPIRED = "expired"
    # Terminal state reached when the sale is finalised via a CompletedTransaction
    # (Trust System Phase 1). An accepted offer becomes COMPLETED on completion.
    COMPLETED = "completed"


class SubscriptionStatus(enum.Enum):
    """Lifecycle status of a premium subscription."""

    ACTIVE = "active"
    EXPIRED = "expired"
    CANCELLED = "cancelled"


class PaymentStatus(enum.Enum):
    """Lifecycle status of a payment attempt (provider-agnostic).

    Mirrors the states a gateway reports: a ``CREATED`` order, an ``AUTHORIZED``
    (funds held) or ``CAPTURED`` (settled) payment, a ``FAILED`` attempt, or a
    ``REFUNDED`` payment. Premium is only ever activated for a ``CAPTURED``
    payment; the value set is intentionally provider-neutral so a future gateway
    (Stripe, Cashfree, …) reuses it unchanged."""

    CREATED = "created"
    AUTHORIZED = "authorized"
    CAPTURED = "captured"
    FAILED = "failed"
    REFUNDED = "refunded"


class PremiumRequestStatus(enum.Enum):
    """Review status of a manual premium activation request."""

    PENDING = "pending"
    APPROVED = "approved"
    REJECTED = "rejected"
    # Admin asked the student for more information; they may edit/resubmit.
    MORE_INFO = "more_info"


class ReportEntityType(enum.Enum):
    """Type of entity a report targets.

    Only ``LISTING`` and ``USER`` are actioned today; ``MESSAGE`` and
    ``ADVERTISEMENT`` are defined now so future entity types need no schema
    redesign — the report table already stores a generic ``entity_public_id``.
    """

    LISTING = "listing"
    USER = "user"
    MESSAGE = "message"
    ADVERTISEMENT = "advertisement"


class ReportReason(enum.Enum):
    """Why a piece of content was reported."""

    SCAM = "scam"
    SPAM = "spam"
    FAKE_ITEM = "fake_item"
    PROHIBITED_ITEM = "prohibited_item"
    OFFENSIVE_CONTENT = "offensive_content"
    WRONG_CATEGORY = "wrong_category"
    DUPLICATE = "duplicate"
    OTHER = "other"


class ReportStatus(enum.Enum):
    """Lifecycle status of a moderation report."""

    PENDING = "pending"
    UNDER_REVIEW = "under_review"
    RESOLVED = "resolved"
    DISMISSED = "dismissed"


class AdvertisementType(enum.Enum):
    """Type of advertisement.

    ``BANNER`` covers internal promotions (ProvatSoft products such as SkillUp
    and future offerings). ``REWARDED`` unlocks additional chat messages.
    """

    BANNER = "banner"
    REWARDED = "rewarded"


class AdvertisementMediaType(enum.Enum):
    """Creative media an advertisement carries.

    ``IMAGE`` is the original banner behaviour (served from ``image_path``);
    ``VIDEO`` renders an HTML5 video from ``media_url`` in the rewarded flow.
    Defaults to ``IMAGE`` so existing advertisements are unchanged.
    """

    IMAGE = "image"
    VIDEO = "video"


class AdvertisementPlacement(enum.Enum):
    """Where an advertisement is displayed in the product.

    ``CHAT`` is the single home of the rewarded "watch an ad to unlock messages"
    flow: rewarded advertisements (``AdvertisementType.REWARDED``) are always
    assigned this placement. There is intentionally **no** separate ``rewarded``
    placement — the advertisement *type* describes how an advertisement behaves,
    while the placement describes *where* it appears. This matches the approved
    schema (``ENUM('landing','marketplace','chat','sidebar')``).
    """

    LANDING = "landing"
    MARKETPLACE = "marketplace"
    CHAT = "chat"
    SIDEBAR = "sidebar"

    @property
    def display_name(self) -> str:
        """Human-facing label for the admin UI.

        ``chat`` reads as "Chat Unlock" so administrators recognise it as the
        rewarded chat-unlock placement; every other member title-cases its value.
        """
        return "Chat Unlock" if self.value == "chat" else self.value.title()


class NotificationType(enum.Enum):
    """Category of a user notification.

    Values mirror the approved ``notifications.notification_type`` ENUM. The set
    is intentionally broad so new platform events reuse an existing member; add a
    new member here (and migrate the ENUM) only when none fits.
    """

    MESSAGE = "message"
    OFFER = "offer"
    OFFER_ACCEPTED = "offer_accepted"
    OFFER_REJECTED = "offer_rejected"
    MEETUP = "meetup"
    FAVORITE = "favorite"
    LISTING = "listing"
    PREMIUM = "premium"
    ADVERTISEMENT = "advertisement"
    REPORT = "report"
    SYSTEM = "system"


class RelatedEntityType(enum.Enum):
    """Type of the record a notification refers to (``related_entity_id``)."""

    LISTING = "listing"
    OFFER = "offer"
    CONVERSATION = "conversation"
    MESSAGE = "message"
    MEETUP = "meetup"
    REPORT = "report"
    ADVERTISEMENT = "advertisement"
    SUBSCRIPTION = "subscription"
    SYSTEM = "system"
