"""init push tables

Revision ID: 0002_init_push_tables
Revises: 0001_init_content_tables
Create Date: 2026-02-03

"""

from __future__ import annotations

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql


# revision identifiers, used by Alembic.
revision = "0002_init_push_tables"
down_revision = "0001_init_content_tables"
branch_labels = None
depends_on = None


def upgrade() -> None:
    # push_tokens
    op.create_table(
        "push_tokens",
        sa.Column(
            "id",
            mysql.BIGINT(unsigned=True),
            primary_key=True,
            autoincrement=True,
            comment="主键",
        ),
        sa.Column("client_user_id", sa.String(length=64), nullable=False, comment="客户端用户标识（UUID）"),
        sa.Column(
            "platform",
            sa.Enum("ios", "android", name="push_platform"),
            nullable=False,
            comment="平台",
        ),
        sa.Column("push_token", sa.String(length=255), nullable=False, comment="Expo Push Token"),
        sa.Column("app_id", sa.String(length=255), nullable=False, comment="bundle id / package name（用于隔离）"),
        sa.Column(
            "env",
            sa.Enum("dev", "prod", name="push_env"),
            nullable=False,
            comment="环境隔离",
        ),
        sa.Column(
            "is_active",
            sa.Boolean(),
            server_default=sa.text("1"),
            nullable=False,
            comment="是否有效（发送失败且不可恢复时置为 false）",
        ),
        sa.Column("last_seen_at", sa.DateTime(), server_default=sa.func.now(), nullable=False, comment="最后一次上报时间"),
        sa.UniqueConstraint("env", "app_id", "push_token", name="uniq_env_app_token"),
        mysql_charset="utf8mb4",
    )
    op.create_index("idx_push_tokens_client_user_id", "push_tokens", ["client_user_id"], unique=False)
    op.create_index("idx_push_tokens_is_active", "push_tokens", ["is_active"], unique=False)

    # push_preferences
    op.create_table(
        "push_preferences",
        sa.Column("client_user_id", sa.String(length=64), primary_key=True, comment="客户端用户标识（UUID）"),
        sa.Column(
            "enabled",
            sa.Boolean(),
            server_default=sa.text("0"),
            nullable=False,
            comment="是否开启每日提醒（enabled=false 或 times_per_day=0 均视为关闭）",
        ),
        sa.Column(
            "times_per_day",
            sa.SmallInteger(),
            server_default="0",
            nullable=False,
            comment="每天推送次数（0～5）",
        ),
        sa.Column("timezone", sa.String(length=64), nullable=True, comment="IANA 时区（例如 Asia/Shanghai），来自客户端上报"),
        sa.Column("locale", sa.String(length=32), nullable=True, comment="客户端语言（例如 zh-CN/en/zh-TW），用于文案语言选择"),
        sa.Column("user_profile_json", sa.JSON(), nullable=True, comment="用户画像（V1.2；可选）。用于 Push 场景推荐文案生成。"),
        sa.Column("updated_at", sa.DateTime(), server_default=sa.func.now(), nullable=False, comment="更新时间"),
        mysql_charset="utf8mb4",
    )

    # push_send_log
    op.create_table(
        "push_send_log",
        sa.Column(
            "id",
            mysql.BIGINT(unsigned=True),
            primary_key=True,
            autoincrement=True,
            comment="主键",
        ),
        sa.Column("client_user_id", sa.String(length=64), nullable=False, comment="客户端用户标识（UUID）"),
        sa.Column("local_date", sa.Date(), nullable=False, comment="用户时区的本地日期（用于幂等）"),
        sa.Column("slot_index", sa.SmallInteger(), nullable=False, comment="当天第几条（1..times_per_day）"),
        sa.Column("scheduled_at", sa.DateTime(), nullable=False, comment="计划发送时间（UTC）"),
        sa.Column("sent_at", sa.DateTime(), nullable=True, comment="实际发送时间（UTC）"),
        sa.Column("status", sa.String(length=16), server_default="scheduled", nullable=False, comment="scheduled/sent/failed"),
        sa.Column("error", sa.Text(), nullable=True, comment="失败原因（可选）"),
        sa.Column("created_at", sa.DateTime(), server_default=sa.func.now(), nullable=False, comment="创建时间"),
        sa.UniqueConstraint("client_user_id", "local_date", "slot_index", name="uniq_user_date_slot"),
        mysql_charset="utf8mb4",
    )
    op.create_index("idx_push_log_user_date", "push_send_log", ["client_user_id", "local_date"], unique=False)
    op.create_index("idx_push_log_status", "push_send_log", ["status"], unique=False)


def downgrade() -> None:
    op.drop_index("idx_push_log_status", table_name="push_send_log")
    op.drop_index("idx_push_log_user_date", table_name="push_send_log")
    op.drop_table("push_send_log")

    op.drop_table("push_preferences")

    op.drop_index("idx_push_tokens_is_active", table_name="push_tokens")
    op.drop_index("idx_push_tokens_client_user_id", table_name="push_tokens")
    op.drop_table("push_tokens")

