# -*- coding: utf-8 -*-
"""
ETL 统一分析 — 编排入口

合并「数据流结构分析」和「ETL 数据一致性检查」为一个统一流程。
支持三种模式：
  --mode structure    仅结构分析（analyze_dataflow + gen_dataflow_report）
  --mode consistency  仅一致性检查（etl_consistency_check）
  --mode full         全部执行（默认）

数据源：
  默认主动调 API 采集最近 60 天数据。
  --source etl-log    切换为读 ETL 落盘 JSON（一致性检查模式）

用法:
    cd C:\\Project\\NeoZQYY
    uv run python scripts/ops/etl_unified_analysis.py
    uv run python scripts/ops/etl_unified_analysis.py --mode consistency --source etl-log
    uv run python scripts/ops/etl_unified_analysis.py --mode structure --date-from 2026-01-01
"""
from __future__ import annotations

import argparse
import subprocess
import sys
from datetime import datetime
from pathlib import Path
from zoneinfo import ZoneInfo

# 确保 scripts/ops 在 sys.path 中，以便 import _env_paths
_SCRIPT_DIR = Path(__file__).resolve().parent
if str(_SCRIPT_DIR) not in sys.path:
    sys.path.insert(0, str(_SCRIPT_DIR))

from _env_paths import get_output_path, ensure_repo_root

ensure_repo_root()

TZ = ZoneInfo("Asia/Shanghai")
NOW = datetime.now(TZ)
TS = NOW.strftime("%Y%m%d_%H%M%S")


def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        description="ETL 统一分析 — 结构分析 + 数据一致性检查",
    )
    parser.add_argument(
        "--mode",
        choices=["structure", "consistency", "full"],
        default="full",
        help="执行模式：structure=仅结构分析, consistency=仅一致性检查, full=全部（默认）",
    )
    parser.add_argument(
        "--source",
        choices=["api", "etl-log"],
        default="api",
        help="数据源：api=主动调 API 采集（默认）, etl-log=读 ETL 落盘 JSON",
    )
    parser.add_argument(
        "--date-from", type=str, default=None,
        help="数据获取起始日期 (YYYY-MM-DD)，默认 60 天前",
    )
    parser.add_argument(
        "--date-to", type=str, default=None,
        help="数据获取截止日期 (YYYY-MM-DD)，默认今天",
    )
    parser.add_argument(
        "--limit", type=int, default=200,
        help="每端点最大记录数（默认 200）",
    )
    parser.add_argument(
        "--tables", type=str, default=None,
        help="要分析的表名列表（逗号分隔，缺省=全部）",
    )
    return parser


def run_subprocess(cmd: list[str], label: str) -> int:
    """运行子进程，实时输出 stdout/stderr，返回 exit code"""
    print(f"\n{'='*60}")
    print(f"[{label}] 开始执行...")
    print(f"  命令: {' '.join(cmd)}")
    print(f"{'='*60}\n")

    proc = subprocess.run(
        cmd,
        cwd=str(Path(__file__).resolve().parents[2]),  # 项目根目录
    )
    if proc.returncode != 0:
        print(f"\n❌ [{label}] 执行失败 (exit code: {proc.returncode})")
    else:
        print(f"\n✅ [{label}] 执行完成")
    return proc.returncode


def run_structure_analysis(args: argparse.Namespace) -> int:
    """执行数据流结构分析（采集 + 报告生成）"""
    from datetime import date, timedelta

    # 阶段 1：数据采集
    cmd = [sys.executable, "scripts/ops/analyze_dataflow.py"]
    if args.date_from:
        cmd += ["--date-from", args.date_from]
    else:
        # 默认 60 天
        default_from = (date.today() - timedelta(days=60)).isoformat()
        cmd += ["--date-from", default_from]
    if args.date_to:
        cmd += ["--date-to", args.date_to]
    if args.limit:
        cmd += ["--limit", str(args.limit)]
    if args.tables:
        cmd += ["--tables", args.tables]

    rc = run_subprocess(cmd, "数据流采集")
    if rc != 0:
        return rc

    # 阶段 2：报告生成
    cmd2 = [sys.executable, "scripts/ops/gen_dataflow_report.py"]
    rc2 = run_subprocess(cmd2, "数据流报告生成")
    return rc2


def run_consistency_check(args: argparse.Namespace) -> int:
    """执行 ETL 数据一致性检查"""
    cmd = [sys.executable, "scripts/ops/etl_consistency_check.py"]
    rc = run_subprocess(cmd, "ETL 数据一致性检查")
    return rc


def merge_reports(structure_ok: bool, consistency_ok: bool) -> Path | None:
    """合并两份报告为一份统一报告"""
    report_root = get_output_path("ETL_REPORT_ROOT")
    analyze_root = get_output_path("SYSTEM_ANALYZE_ROOT")

    # 找最新的 dataflow 报告
    dataflow_report = None
    if structure_ok:
        dataflow_files = sorted(analyze_root.glob("dataflow_*.md"), reverse=True)
        if dataflow_files:
            dataflow_report = dataflow_files[0]

    # 找最新的 consistency 报告
    consistency_report = None
    if consistency_ok:
        consistency_files = sorted(report_root.glob("consistency_check_*.md"), reverse=True)
        if consistency_files:
            consistency_report = consistency_files[0]

    if not dataflow_report and not consistency_report:
        print("⚠️ 没有找到任何报告文件，跳过合并")
        return None

    # 合并
    lines: list[str] = []
    lines.append("# ETL 统一分析报告")
    lines.append("")
    lines.append(f"生成时间: {NOW.strftime('%Y-%m-%d %H:%M:%S')} CST")
    lines.append(f"模式: 结构分析{'✅' if structure_ok else '❌'} + 一致性检查{'✅' if consistency_ok else '❌'}")
    lines.append("")
    lines.append("---")
    lines.append("")

    if dataflow_report:
        lines.append("# 第一部分：数据流结构分析")
        lines.append("")
        content = dataflow_report.read_text(encoding="utf-8")
        # 跳过原报告的一级标题行（避免重复标题）
        for line in content.splitlines():
            if line.startswith("# ") and "数据流" in line:
                continue
            lines.append(line)
        lines.append("")
        lines.append("---")
        lines.append("")

    if consistency_report:
        lines.append("# 第二部分：ETL 数据一致性检查")
        lines.append("")
        content = consistency_report.read_text(encoding="utf-8")
        for line in content.splitlines():
            if line.startswith("# ") and "一致性" in line:
                continue
            lines.append(line)
        lines.append("")

    out_file = report_root / f"etl_unified_analysis_{TS}.md"
    out_file.write_text("\n".join(lines), encoding="utf-8")
    return out_file


def main() -> None:
    parser = build_parser()
    args = parser.parse_args()

    print(f"{'='*60}")
    print(f"ETL 统一分析")
    print(f"{'='*60}")
    print(f"  模式:     {args.mode}")
    print(f"  数据源:   {args.source}")
    print(f"  日期范围: {args.date_from or '默认60天前'} ~ {args.date_to or '今天'}")
    print(f"{'='*60}")

    structure_ok = False
    consistency_ok = False
    any_failure = False

    # 结构分析
    if args.mode in ("structure", "full"):
        rc = run_structure_analysis(args)
        structure_ok = rc == 0
        if rc != 0:
            any_failure = True
            if args.mode == "structure":
                sys.exit(rc)

    # 一致性检查
    if args.mode in ("consistency", "full"):
        rc = run_consistency_check(args)
        consistency_ok = rc == 0
        if rc != 0:
            any_failure = True
            if args.mode == "consistency":
                sys.exit(rc)

    # 合并报告（仅 full 模式且至少有一个成功）
    if args.mode == "full" and (structure_ok or consistency_ok):
        print(f"\n{'='*60}")
        print(f"[报告合并] 开始合并...")
        print(f"{'='*60}")
        merged = merge_reports(structure_ok, consistency_ok)
        if merged:
            print(f"\n✅ 统一报告已生成: {merged}")
        else:
            print(f"\n⚠️ 报告合并失败")

    # 最终摘要
    print(f"\n{'='*60}")
    print(f"ETL 统一分析完成")
    print(f"{'='*60}")
    if args.mode in ("structure", "full"):
        print(f"  结构分析:   {'✅ 成功' if structure_ok else '❌ 失败'}")
    if args.mode in ("consistency", "full"):
        print(f"  一致性检查: {'✅ 成功' if consistency_ok else '❌ 失败'}")
    print(f"{'='*60}")

    if any_failure:
        sys.exit(1)


if __name__ == "__main__":
    main()
