"""代理余额流水表"""
import enum
from datetime import datetime

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

from app.models.base import BaseModel


class AgentBalanceChangeType(str, enum.Enum):
    SUBSIDY_FREEZE = "subsidy_freeze"      # 下单时冻结补贴
    SUBSIDY_CHARGE = "subsidy_charge"      # 服务开通后扣除补贴
    SUBSIDY_RELEASE = "subsidy_release"    # 退款/取消时释放冻结补贴
    SUBSIDY_REFUND = "subsidy_refund"      # 开通后退款返还补贴
    PROFIT_SETTLE = "profit_settle"        # 收益结算入账
    PROFIT_REVERSE = "profit_reverse"      # 退款时扣回已结算收益
    RECHARGE = "recharge"                  # 代理充值
    WITHDRAW = "withdraw"                  # 代理提现
    ADMIN_ADJUST = "admin_adjust"          # 管理员调整


class AgentBalanceLog(BaseModel):
    """代理余额变动流水，作为代理资金审计依据。"""

    __tablename__ = "agent_balance_logs"

    user_id: Mapped[int] = mapped_column(
        BigInteger, ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True,
        comment="代理用户ID",
    )
    change_type: Mapped[AgentBalanceChangeType] = mapped_column(
        SAEnum(AgentBalanceChangeType, values_callable=lambda e: [m.value for m in e]),
        nullable=False, index=True, comment="变动类型",
    )
    # 变动金额（分），正数为入账，负数为扣款
    delta: Mapped[int] = mapped_column(Integer, nullable=False, comment="变动金额，单位分，正入负出")
    # 变动后可用余额快照
    balance_after: Mapped[int] = mapped_column(Integer, nullable=False, comment="变动后可用余额，单位分")
    # 变动后冻结余额快照
    frozen_balance_after: Mapped[int] = mapped_column(Integer, nullable=False, comment="变动后冻结余额，单位分")
    order_id: Mapped[int | None] = mapped_column(
        Integer, ForeignKey("orders.id", ondelete="SET NULL"), nullable=True, index=True,
        comment="关联订单ID",
    )
    ref_no: Mapped[str | None] = mapped_column(String(64), nullable=True, index=True, comment="业务单号")
    remark: Mapped[str | None] = mapped_column(Text, nullable=True, comment="备注")
    operator_id: Mapped[int | None] = mapped_column(
        BigInteger, nullable=True, comment="操作人ID，管理员操作时记录",
    )
