from sqlalchemy import BigInteger, Boolean, ForeignKey, Integer, String, Text, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column
from sqlalchemy.types import JSON

from app.models.base import BaseModel


class SpendEventTypeConfig(BaseModel):
    """Configurable spend event type. Admins choose which types count as effective spend."""

    __tablename__ = "spend_event_type_configs"

    code: Mapped[str] = mapped_column(String(64), unique=True, nullable=False, index=True)
    label: Mapped[str] = mapped_column(String(64), nullable=False)
    description: Mapped[str | None] = mapped_column(String(255), nullable=True)
    enabled: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False, index=True)
    sort_order: Mapped[int] = mapped_column(Integer, default=0, nullable=False)


class UserSpendEvent(BaseModel):
    """Immutable effective spend event. Positive for paid consumption, negative for refund reversal."""

    __tablename__ = "user_spend_events"
    __table_args__ = (
        UniqueConstraint("event_key", name="uq_user_spend_events_event_key"),
    )

    user_id: Mapped[int] = mapped_column(
        BigInteger, ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True
    )
    event_type: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
    event_key: Mapped[str] = mapped_column(String(128), nullable=False)
    amount_cents: Mapped[int] = mapped_column(Integer, nullable=False, comment="Signed amount in cents")
    order_id: Mapped[int | None] = mapped_column(
        Integer, ForeignKey("orders.id", ondelete="SET NULL"), nullable=True, index=True
    )
    ref_no: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True)
    remark: Mapped[str | None] = mapped_column(Text, nullable=True)
    payload_snapshot: Mapped[dict | None] = mapped_column(JSON, nullable=True)
