# -*- coding: utf-8 -*-
"""
在测试库 test_etl_feiqiu 执行 SPI 建表迁移脚本。

迁移脚本：db/etl_feiqiu/migrations/2026-02-23_create_dws_member_spending_power_index.sql
目标表：dws.dws_member_spending_power_index

使用方式：
    python scripts/ops/run_migration_spi_table.py
"""

import os
import sys
from pathlib import Path

from dotenv import load_dotenv
import psycopg2

# 加载根 .env
_ROOT = Path(__file__).resolve().parents[2]
load_dotenv(_ROOT / ".env", override=False)

DSN = os.getenv("TEST_DB_DSN")
if not DSN:
    print("ERROR: TEST_DB_DSN 未配置，请在根 .env 中设置")
    sys.exit(1)

MIGRATION_FILE = (
    _ROOT / "db" / "etl_feiqiu" / "migrations"
    / "2026-02-23_create_dws_member_spending_power_index.sql"
)


def table_exists(conn) -> bool:
    """检查目标表是否已存在"""
    cur = conn.cursor()
    cur.execute("""
        SELECT 1 FROM information_schema.tables
        WHERE table_schema = 'dws'
          AND table_name = 'dws_member_spending_power_index'
    """)
    exists = cur.fetchone() is not None
    cur.close()
    return exists


def execute_migration(conn) -> bool:
    """执行迁移脚本，返回是否成功"""
    sql = MIGRATION_FILE.read_text(encoding="utf-8")

    # 提取主体 SQL（去掉注释中的回滚部分）
    main_lines = []
    in_rollback = False
    for line in sql.split("\n"):
        stripped = line.strip()
        if stripped.startswith("-- ====") and "回滚" in stripped:
            in_rollback = True
        if not in_rollback:
            main_lines.append(line)

    main_sql = "\n".join(main_lines).strip()
    if not main_sql:
        print("⚠️ 迁移脚本为空，跳过")
        return False

    try:
        cur = conn.cursor()
        cur.execute(main_sql)
        cur.close()
        print("✅ 迁移脚本执行成功")
        return True
    except Exception as e:
        print(f"❌ 迁移脚本执行失败: {e}")
        return False


def verify(conn) -> bool:
    """验证建表结果"""
    cur = conn.cursor()
    checks = []

    # 1. 表存在
    cur.execute("""
        SELECT 1 FROM information_schema.tables
        WHERE table_schema = 'dws'
          AND table_name = 'dws_member_spending_power_index'
    """)
    checks.append(("表 dws.dws_member_spending_power_index 存在", cur.fetchone() is not None))

    # 2. 关键字段完整
    expected_cols = [
        "spi_id", "site_id", "member_id",
        "spend_30", "spend_90", "recharge_90",
        "orders_30", "orders_90", "visit_days_30", "visit_days_90",
        "avg_ticket_90", "active_weeks_90", "daily_spend_ewma_90",
        "score_level_raw", "score_speed_raw", "score_stability_raw",
        "score_level_display", "score_speed_display", "score_stability_display",
        "raw_score", "display_score",
        "calc_time", "created_at", "updated_at",
    ]
    cur.execute("""
        SELECT column_name FROM information_schema.columns
        WHERE table_schema = 'dws'
          AND table_name = 'dws_member_spending_power_index'
        ORDER BY ordinal_position
    """)
    actual_cols = [r[0] for r in cur.fetchall()]
    missing = [c for c in expected_cols if c not in actual_cols]
    checks.append((f"字段完整（{len(actual_cols)} 列）", len(missing) == 0))
    if missing:
        print(f"    缺失字段: {missing}")

    # 3. 唯一索引 idx_spi_site_member 存在
    cur.execute("""
        SELECT 1 FROM pg_indexes
        WHERE schemaname = 'dws'
          AND tablename = 'dws_member_spending_power_index'
          AND indexname = 'idx_spi_site_member'
    """)
    checks.append(("唯一索引 idx_spi_site_member 存在", cur.fetchone() is not None))

    # 4. 查询索引 idx_spi_display_score 存在
    cur.execute("""
        SELECT 1 FROM pg_indexes
        WHERE schemaname = 'dws'
          AND tablename = 'dws_member_spending_power_index'
          AND indexname = 'idx_spi_display_score'
    """)
    checks.append(("查询索引 idx_spi_display_score 存在", cur.fetchone() is not None))

    cur.close()

    print("\n" + "=" * 50)
    print("建表验证结果")
    print("=" * 50)
    all_ok = True
    for name, ok in checks:
        status = "✅" if ok else "❌"
        print(f"  {status} {name}")
        if not ok:
            all_ok = False

    return all_ok


def main():
    dsn_display = DSN.split("@")[1] if "@" in DSN else DSN
    print(f"连接测试库: {dsn_display}")
    print(f"迁移脚本: {MIGRATION_FILE.name}\n")

    if not MIGRATION_FILE.exists():
        print(f"ERROR: 迁移脚本不存在: {MIGRATION_FILE}")
        sys.exit(1)

    conn = psycopg2.connect(DSN)
    conn.autocommit = True  # 建表 DDL 需要 autocommit

    # 检查表是否已存在
    if table_exists(conn):
        print("ℹ️ 表 dws.dws_member_spending_power_index 已存在，跳过建表")
    else:
        if not execute_migration(conn):
            conn.close()
            sys.exit(1)

    # 验证
    all_ok = verify(conn)
    conn.close()

    if all_ok:
        print("\n✅ SPI 建表迁移完成，所有验证通过")
    else:
        print("\n⚠️ 部分验证未通过，请检查")
        sys.exit(1)


if __name__ == "__main__":
    main()
