"""cps v2: 活动 payload(淘口令/京东链接) + 群多平台/sid 可空 + 点击 event_type

Revision ID: cps_v2_platforms
Revises: cps_link_tables
Create Date: 2026-06-17 11:00:00.000000

接入淘宝/京东:
- cps_activity.payload   淘宝整段淘口令文本 / 京东推广链接(美团仍用 act_id)
- cps_group.platforms    该群发哪些平台(多选);sid 改可空(纯淘宝/京东无 sid)
- cps_link.sid 可空 + target_url 加长(淘口令较长)
- cps_click.event_type   visit / copy(淘宝落地页"复制口令")
"""
from typing import Sequence, Union

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


revision: str = "cps_v2_platforms"
down_revision: Union[str, Sequence[str], None] = "cps_link_tables"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def _has_column(insp: sa.Inspector, table: str, column: str) -> bool:
    return any(c["name"] == column for c in insp.get_columns(table))


def upgrade() -> None:
    bind = op.get_bind()
    insp = sa.inspect(bind)
    # SQLite 不认 ::jsonb cast(会报 "unrecognized token: :"),只有 PG 用显式 cast。
    # 两边列类型都靠上面的 with_variant 区分,这里只管 server_default 文本。
    platforms_default = (
        sa.text("'[\"meituan\"]'::jsonb")
        if bind.dialect.name == "postgresql"
        else sa.text("'[\"meituan\"]'")
    )

    # 活动:淘宝淘口令 / 京东链接
    # 加 add_column 存在性守卫:本迁移历史上在 SQLite 第一次跑时加完 payload 即在
    # platforms 那步炸掉(::jsonb),DDL 非事务不回滚 → 半应用状态。守卫让其可自愈重跑。
    if not _has_column(insp, "cps_activity", "payload"):
        op.add_column("cps_activity", sa.Column("payload", sa.Text(), nullable=True))

    # 群:多平台(现有群都是美团,server_default 回填)+ sid 可空。
    # SQLite 不支持 ALTER COLUMN,必须用 batch(重建表)才能改 nullable;PG 走原生 ALTER。
    with op.batch_alter_table("cps_group") as batch_op:
        if not _has_column(insp, "cps_group", "platforms"):
            batch_op.add_column(
                sa.Column(
                    "platforms",
                    sa.JSON().with_variant(postgresql.JSONB(), "postgresql"),
                    nullable=False,
                    server_default=platforms_default,
                )
            )
        batch_op.alter_column("sid", existing_type=sa.String(64), nullable=True)

    # link:sid 可空 + target 加长
    with op.batch_alter_table("cps_link") as batch_op:
        batch_op.alter_column("sid", existing_type=sa.String(64), nullable=True)
        batch_op.alter_column("target_url", existing_type=sa.String(1024), type_=sa.String(2048))

    # click:sid 可空 + 事件类型
    with op.batch_alter_table("cps_click") as batch_op:
        batch_op.alter_column("sid", existing_type=sa.String(64), nullable=True)
        if not _has_column(insp, "cps_click", "event_type"):
            batch_op.add_column(
                sa.Column("event_type", sa.String(16), nullable=False, server_default="visit")
            )


def downgrade() -> None:
    with op.batch_alter_table("cps_click") as batch_op:
        batch_op.drop_column("event_type")
        batch_op.alter_column("sid", existing_type=sa.String(64), nullable=False)
    with op.batch_alter_table("cps_link") as batch_op:
        batch_op.alter_column("target_url", existing_type=sa.String(2048), type_=sa.String(1024))
        batch_op.alter_column("sid", existing_type=sa.String(64), nullable=False)
    with op.batch_alter_table("cps_group") as batch_op:
        batch_op.drop_column("platforms")
        batch_op.alter_column("sid", existing_type=sa.String(64), nullable=False)
    with op.batch_alter_table("cps_activity") as batch_op:
        batch_op.drop_column("payload")
