import enum

from sqlalchemy import BigInteger, ForeignKey, Integer, String
from sqlalchemy import Enum as SAEnum
from sqlalchemy.orm import Mapped, mapped_column

from app.models.base import BaseModel


class PointChangeType(str, enum.Enum):
    ORDER_REWARD = "order_reward"       # 消费返积分
    ORDER_REFUND = "order_refund"       # 退款扣回积分
    POINTS_USE = "points_use"           # 积分抵扣使用
    POINTS_REFUND = "points_refund"     # 退款返还积分
    ADMIN_ADJUST = "admin_adjust"       # 管理员调整
    ACTIVITY_GIFT = "activity_gift"     # 活动赠送
    AGENT_PROFIT = "agent_profit"       # 代理收益（积分形式）
    AGENT_SUBSIDY = "agent_subsidy"     # 代理补贴扣回（积分形式）
    REFERRAL_REWARD = "referral_reward"  # 普通会员推广奖励（积分形式）


class PointLog(BaseModel):
    """积分流水。每次积分变动写一条，不可修改，作为积分审计依据。"""

    __tablename__ = "point_logs"

    user_id: Mapped[int] = mapped_column(
        BigInteger, ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True
    )

    change_type: Mapped[PointChangeType] = mapped_column(
        SAEnum(PointChangeType, values_callable=lambda e: [m.value for m in e]),
        nullable=False,
        index=True,
    )

    # 变动数量，正数为获得，负数为消耗
    delta: Mapped[int] = mapped_column(Integer, nullable=False, comment="变动积分，正入负出")

    # 变动后积分快照
    balance_after: Mapped[int] = mapped_column(Integer, nullable=False, comment="变动后可用积分")

    # 关联订单ID
    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)

    # 操作人（管理员调账时记录）
    operator_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True)

    remark: Mapped[str | None] = mapped_column(String(255), nullable=True)
