"""15 天不活跃清零相关表。

- inactivity_reset_log:每次清零一行,记清零前三桶余额快照 + 原因 + 判定时活跃时间/不活跃天数,
  供纠纷排查(需求①)。清零同时另写 2 条钱包流水(金币 + 折算现金,biz_type=inactivity_reset),
  资金流可逐笔回溯。**邀请现金是产品红线、不清零**,invite_cash_balance_cents_before 仅为清零时
  仍保留的邀请现金快照(便于排查、非被清金额;见 wallet.CoinAccount 注释)。
- inactivity_notification_log:每次预警一行,记推送时余额快照 + 档位 + 通道 + 状态,
  兼作"预警去重"依据(created_at > last_active)与"待推送"占位 outbox(v1 通道=log)。

append-only,不更新。user_id 只索引、不设外键(同 analytics_event,避免删用户级联/历史留痕)。
"""
from __future__ import annotations

from datetime import datetime

from sqlalchemy import DateTime, Integer, String, func
from sqlalchemy.orm import Mapped, mapped_column

from app.db.base import Base


class InactivityResetLog(Base):
    __tablename__ = "inactivity_reset_log"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    user_id: Mapped[int] = mapped_column(Integer, index=True, nullable=False)
    coin_balance_before: Mapped[int] = mapped_column(Integer, nullable=False)
    cash_balance_cents_before: Mapped[int] = mapped_column(Integer, nullable=False)
    invite_cash_balance_cents_before: Mapped[int] = mapped_column(Integer, nullable=False)
    last_active_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
    inactive_days: Mapped[int] = mapped_column(Integer, nullable=False)
    reason: Mapped[str] = mapped_column(String(32), nullable=False)
    reset_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now(), index=True, nullable=False
    )

    def __repr__(self) -> str:  # pragma: no cover
        return f"<InactivityResetLog id={self.id} user_id={self.user_id} coin={self.coin_balance_before}>"


class InactivityNotificationLog(Base):
    __tablename__ = "inactivity_notification_log"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    user_id: Mapped[int] = mapped_column(Integer, index=True, nullable=False)
    stage: Mapped[int] = mapped_column(Integer, nullable=False)      # 提前天数档(如 7 / 2)
    inactive_days: Mapped[int] = mapped_column(Integer, nullable=False)
    coin_balance: Mapped[int] = mapped_column(Integer, nullable=False)
    cash_balance_cents: Mapped[int] = mapped_column(Integer, nullable=False)
    invite_cash_balance_cents: Mapped[int] = mapped_column(Integer, nullable=False)
    channel: Mapped[str] = mapped_column(String(16), nullable=False)   # log / jpush / sms
    status: Mapped[str] = mapped_column(String(16), nullable=False)    # placeholder / sent / failed
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now(), index=True, nullable=False
    )

    def __repr__(self) -> str:  # pragma: no cover
        return f"<InactivityNotificationLog id={self.id} user_id={self.user_id} stage={self.stage}>"
