"""
Pipeline 入口 — 按阶段运行投标书生成流程

用法:
    python run_pipeline.py --phase 1                                # 使用默认路径
    python run_pipeline.py --phase 1 --tender data/招标.pdf         # 指定新招标
    python run_pipeline.py --phase 1 --history data/history/        # 指定历史数据目录
    python run_pipeline.py --phase 2
    python run_pipeline.py --phase 1-3
    python run_pipeline.py --list
"""

import sys
import os
import json
import glob

sys.stdout.reconfigure(encoding="utf-8")
BASE_DIR = os.path.dirname(os.path.abspath(__file__))


# ── 阶段配置 ──

PHASES = {
    1: {
        "name": "phase1_parsing",
        "title": "招标解析与历史比对",
        "desc": "输入新招标PDF + 历史招投标数据目录 → 输出招标信息、表格、历史浓缩及相似度权重",
        "outputs": [
            "output/phase1_new_tender.json",
            "output/phase1_tender_tables/tables.json",
            "output/phase1_historical_summary.json",
        ],
    },
    2: {
        "name": "phase2_outline",
        "title": "投标大纲生成",
        "desc": "基于新招标要求和加权后的历史参考，用 LLM 生成目录大纲",
        "outputs": ["output/phase2_bid_outline.json"],
        "deps": [1],
    },
    3: {
        "name": "phase3_collection",
        "title": "公司信息模板生成",
        "desc": "生成投标公司需要补充的信息清单（简化版 JSON）",
        "outputs": ["output/phase3_company_template.json"],
        "deps": [1],
    },
    4: {
        "name": "phase4_filling",
        "title": "内容填充（待开发）",
        "outputs": ["output/phase4_bid_fill_draft.json"],
        "deps": [2, 3],
    },
    5: {
        "name": "phase5_validation",
        "title": "一致性校验（待开发）",
        "outputs": ["output/phase5_consistency_report.json"],
        "deps": [4],
    },
    6: {
        "name": "phase6_export",
        "title": "DOCX 导出（待开发）",
        "outputs": ["output/phase6_bid_final.docx"],
        "deps": [4, 5],
    },
}


# ── 阶段执行 ──

def run_phase(phase_num: int, tender: str = None, history: str = None):
    info = PHASES[phase_num]
    print(f"\n{'='*60}")
    print(f"Phase {phase_num}: {info['title']}")
    print(f"{'='*60}")
    print(f"说明: {info['desc']}")

    for dep in info.get("deps", []):
        for out_path in PHASES[dep]["outputs"]:
            if not os.path.exists(os.path.join(BASE_DIR, out_path)):
                print(f"  [WARN] 依赖 Phase {dep} 输出不存在: {out_path}")

    if phase_num == 1:
        _run_phase1(tender, history)
    elif phase_num == 2:
        _run_phase2()
    elif phase_num == 3:
        _run_phase3()
    else:
        print(f"  [INFO] Phase {phase_num} 尚未开发")


# ════════════════════════════════════════════════════════════
# Phase 1: 新招标解析 + 历史招投标比对
# ════════════════════════════════════════════════════════════

def _run_phase1(tender_path: str = None, history_dir: str = None):
    """
    输入:
      - 新招标文件 PDF（1 份）
      - 历史数据目录（N 组），每组结构:
          项目文件夹/
          ├── 招标文件.pdf    ← 历史招标（用于和新招标算相似度）
          └── 投标文件.pdf    ← 对应的投标（按相似度加权影响新投标）

    输出:
      - output/phase1_new_tender.json          新招标解析结果（文本+特征+表格索引）
      - output/phase1_tender_tables/tables.json 表格元数据
      - output/phase1_historical_summary.json   历史数据汇总（含相似度权重+投标结构）
    """
    from phase1_parsing.extract_pdf_text import extract_text, extract_tender_sections, extract_project_overview
    from phase1_parsing.extract_pdf_tables import extract_tables
    from phase1_parsing.analyze_similarity import calculate_similarity

    # ── 1. 解析新招标文件 ────────────────────────────

    tender_pdf = tender_path or "data/松江区机关事务管理局物业管理服务招标文件.pdf"
    if not os.path.exists(tender_pdf):
        print(f"[ERROR] 新招标文件不存在: {tender_pdf}")
        return

    print(f"\n[Phase1] 解析新招标文件: {tender_pdf}")
    tender_text = extract_text(tender_pdf, "output/phase1_raw/tender_text.txt")

    # 章节分割
    sections = extract_tender_sections(tender_text)
    for name, content in sections.items():
        print(f"  章节 {name}: {len(content)} 字符")

    # 表格提取
    print("\n  提取表格...")
    try:
        tables_meta = extract_tables(tender_pdf, "output/phase1_tender_tables")
        table_count = tables_meta.get("total_tables", 0)
        print(f"  共 {table_count} 个表格")
    except Exception as e:
        print(f"  [SKIP] 表格提取跳过: {e}")
        table_count = 0

    # 项目概况
    overview = extract_project_overview(tender_text)
    print(f"  项目概况: {overview.get('project_name', '未知')}")

    # 保存新招标解析
    new_tender_data = {
        "source_file": tender_pdf,
        "text_file": "output/phase1_raw/tender_text.txt",
        "total_chars": len(tender_text),
        "sections": {k: len(v) for k, v in sections.items()},
        "tables_count": table_count,
        "overview": overview,
    }
    os.makedirs("output", exist_ok=True)
    with open("output/phase1_new_tender.json", "w", encoding="utf-8") as f:
        json.dump(new_tender_data, f, ensure_ascii=False, indent=2)
    print("  [OK] 已保存: output/phase1_new_tender.json")

    # ── 2. 扫描历史数据 ─────────────────────────────

    history_dir = history_dir or "data/历史数据"
    if not os.path.isdir(history_dir):
        print(f"\n[Phase1] 历史数据目录不存在: {history_dir}")
        print("  将仅输出新招标解析结果")
        return

    groups = _scan_history_groups(history_dir)
    if not groups:
        print(f"\n[Phase1] 在 {history_dir} 下未找到历史数据")
        return

    print(f"\n[Phase1] 历史数据: 发现 {len(groups)} 组")
    for g in groups:
        print(f"  [{g['group_id']}] {g.get('name', '')}")

    # ── 3. 相似度计算 ───────────────────────────────

    print("\n[Phase1] 计算历史招标与新招标的相似度...")
    similarity_results = calculate_similarity(tender_text, groups, use_llm=True)

    print("\n  相似度排名:")
    for r in similarity_results:
        bar = "█" * int(r["similarity_score"] * 20) + "░" * (20 - int(r["similarity_score"] * 20))
        print(f"  {r['similarity_score']:.0%} {bar}  {r['name']} ({r['similarity_level']})")
        print(f"     理由: {r['similarity_reason'][:80]}")

    # ── 4. 输出历史汇总 ─────────────────────────────

    summary = {
        "new_tender": {
            "file": tender_pdf,
            "overview": overview,
            "text_file": "output/phase1_raw/tender_text.txt",
        },
        "historical_count": len(groups),
        "historical_data": similarity_results,
        "note": "每项含 similarity_score(0~1) 表示与新招标的相似度，weight 为归一化权重。"
                "相似度越高，对应的投标文件对结果影响越大。",
    }
    with open("output/phase1_historical_summary.json", "w", encoding="utf-8") as f:
        json.dump(summary, f, ensure_ascii=False, indent=2)
    print(f"\n[Phase1] 历史汇总已保存: output/phase1_historical_summary.json")


def _scan_history_groups(history_dir: str) -> list:
    """
    扫描历史数据目录。支持两种结构:

    结构1: 项目文件夹模式（推荐）
        history_dir/
        ├── 项目A/
        │   ├── 招标文件.pdf
        │   └── 投标文件.pdf
        ├── 项目B/
        │   ├── 招标文件.pdf
        │   └── 投标文件.pdf

    结构2: 平铺模式（自动配对）
        history_dir/
        ├── XX项目-招标文件.pdf
        ├── XX项目-投标文件.pdf
        ├── YY项目-招标文件.pdf
        └── YY项目-投标文件.pdf
    """
    from phase1_parsing.extract_pdf_text import extract_text

    groups = []
    seen = set()

    # 结构1: 子文件夹模式
    for sub_dir in sorted(glob.glob(os.path.join(history_dir, "*"))):
        if not os.path.isdir(sub_dir):
            continue
        tender_file = _find_file(sub_dir, "*招标*.pdf") or _find_file(sub_dir, "*tender*.pdf")
        bid_file = _find_file(sub_dir, "*投标*.pdf") or _find_file(sub_dir, "*bid*.pdf")
        if tender_file and bid_file:
            group_id = os.path.basename(sub_dir)
            print(f"  [扫描] {group_id}: 招标={os.path.basename(tender_file)}, 投标={os.path.basename(bid_file)}")
            tender_text = extract_text(tender_file)
            bid_text = extract_text(bid_file)
            groups.append({
                "group_id": group_id,
                "name": group_id,
                "tender_file": tender_file,
                "bid_file": bid_file,
                "tender_text": tender_text,
                "bid_text": bid_text,
            })
            seen.add(sub_dir)

    # 结构2: 平铺自动配对
    all_pdfs = sorted(glob.glob(os.path.join(history_dir, "*.pdf")))
    pending = []
    for fp in all_pdfs:
        fname = os.path.basename(fp)
        if fp in seen:
            continue
        if "招标" in fname or "tender" in fname.lower():
            pending.append(("tender", fp))
        elif "投标" in fname or "bid" in fname.lower():
            pending.append(("bid", fp))

    # 简单配对: 按顺序招标+投标为一组
    i = 0
    while i < len(pending) - 1:
        if pending[i][0] == "tender" and pending[i + 1][0] == "bid":
            tender_file = pending[i][1]
            bid_file = pending[i + 1][1]
            group_id = f"history_group_{len(groups) + 1}"
            print(f"  [扫描] {group_id}: 招标={os.path.basename(tender_file)}, 投标={os.path.basename(bid_file)}")
            tender_text = extract_text(tender_file)
            bid_text = extract_text(bid_file)
            groups.append({
                "group_id": group_id,
                "name": group_id,
                "tender_file": tender_file,
                "bid_file": bid_file,
                "tender_text": tender_text,
                "bid_text": bid_text,
            })
            i += 2
        else:
            i += 1

    return groups


def _find_file(directory: str, pattern: str) -> str:
    """在目录中匹配第一个文件"""
    files = glob.glob(os.path.join(directory, pattern))
    return files[0] if files else None


# ════════════════════════════════════════════════════════════
# Phase 2: 投标大纲生成
# ════════════════════════════════════════════════════════════

def _run_phase2():
    """读取 Phase1 输出 → 生成目录大纲（历史相似度高的优先参考）"""
    from phase2_outline.generate_outline import generate_outline, print_outline_preview

    new_tender_file = "output/phase1_new_tender.json"
    hist_file = "output/phase1_historical_summary.json"

    if not os.path.exists(new_tender_file):
        print(f"[ERROR] 请先运行 Phase 1: 未找到 {new_tender_file}")
        return

    # 读取新招标文本
    with open(new_tender_file, "r", encoding="utf-8") as f:
        new_tender = json.load(f)

    tender_text_file = new_tender.get("text_file", "output/phase1_raw/tender_text.txt")
    if not os.path.exists(tender_text_file):
        print(f"[ERROR] 招标文本不存在: {tender_text_file}")
        return

    with open(tender_text_file, "r", encoding="utf-8") as f:
        tender_text = f.read()

    # 读取历史汇总
    bid_toc = []
    if os.path.exists(hist_file):
        with open(hist_file, "r", encoding="utf-8") as f:
            hist_data = json.load(f)

        # 取相似度最高的历史投标结构作为参考
        hist_items = hist_data.get("historical_data", [])
        if hist_items:
            best = hist_items[0]
            bid_toc = best.get("bid_toc", [])
            print(f"\n[Phase2] 参考历史: {best.get('name', 'N/A')} "
                  f"(相似度 {best.get('similarity_score', 0):.0%}, 权重 {best.get('weight', 0):.0%})")

    print(f"\n[Phase2] 招标文本: {len(tender_text)} 字符")
    print(f"[Phase2] 历史投标目录: {len(bid_toc)} 行")

    outline = generate_outline(tender_text, bid_toc,
                               output_path="output/phase2_bid_outline.json")
    print_outline_preview(outline)


# ════════════════════════════════════════════════════════════
# Phase 3: 公司信息模板生成
# ════════════════════════════════════════════════════════════

def _run_phase3():
    from phase3_collection.generate_template import generate_template
    template = generate_template(output_path="output/phase3_company_template.json")
    items = template["投标公司信息收集表"]["信息项"]
    print(f"\n共 {len(items)} 项信息待补充:")
    for item in items:
        print(f"  □ {item['名称']}")


# ── CLI ──

def list_phases():
    print("\nPipeline 阶段:\n")
    for num in sorted(PHASES):
        info = PHASES[num]
        deps = f" (依赖: Phase {', '.join(str(d) for d in info['deps'])})" if info.get("deps") else ""
        print(f"  Phase {num}: {info['title']}{deps}")
        print(f"            {info['desc']}")
        for o in info["outputs"]:
            fp = os.path.join(BASE_DIR, o)
            status = "✓" if os.path.exists(fp) else " "
            print(f"            [{status}] {o}")
        print()


def main():
    import argparse
    parser = argparse.ArgumentParser(description="投标书生成 Pipeline")
    parser.add_argument("--phase", help="运行阶段: 1, 2, 1-3")
    parser.add_argument("--all", action="store_true", help="全流程")
    parser.add_argument("--list", action="store_true", help="查看阶段说明")
    parser.add_argument("--tender", default=None, help="新招标文件 PDF 路径")
    parser.add_argument("--history", default=None, help="历史数据目录（含多组招投标文件夹）")
    args = parser.parse_args()

    if args.list:
        list_phases()
        return

    phases_to_run = []
    if args.all:
        phases_to_run = sorted(PHASES.keys())
    elif args.phase:
        for part in args.phase.split(","):
            if "-" in part:
                s, e = part.split("-")
                phases_to_run.extend(range(int(s), int(e) + 1))
            else:
                phases_to_run.append(int(part))

    if not phases_to_run:
        parser.print_help()
        list_phases()
        return

    print("执行顺序:", " → ".join(f"Phase {p}" for p in phases_to_run))
    for p in phases_to_run:
        if p in PHASES:
            run_phase(p, tender=args.tender, history=args.history)
        else:
            print(f"[ERROR] 未知阶段: Phase {p}")


if __name__ == "__main__":
    main()
