"""
Phase 2: 投标大纲生成

基于招标文件关键章节 + 历史投标文件目录，使用 LLM 生成结构化投标目录大纲。

用法:
    python -m phase2_outline.generate_outline

    或:
    from phase2_outline.generate_outline import generate_outline
    outline = generate_outline(tender_text, bid_toc)
"""

import sys
import os
import json

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from llm.llm_utils import LLM


# ── 提取招标关键章节 ─────────────────────────────────

def collect_tender_key_sections(tender_text: str) -> str:
    """提取招标文件中与大纲生成最相关的章节（格式要求、评分标准、需求）"""
    parts = []
    markers = [
        ("第六章  投标文件有关格式", 8000),
        ("第五章  评标方法与程序", 6000),
        ("附件：项目采购需求", 10000),
        ("第四章  招标需求", 6000),
        ("第一章  投标邀请", 4000),
    ]
    for keyword, length in markers:
        idx = tender_text.find(keyword)
        if idx != -1:
            parts.append(f"\n【{keyword.strip()}】\n{tender_text[idx:idx+length]}")
    return "\n".join(parts) if parts else tender_text[:20000]


def format_bid_toc(bid_toc: list) -> str:
    """将历史投标文件目录列表格式化为可读文本"""
    lines = []
    for item in bid_toc[:80]:  # 取前80行
        indent = "  " * (item.get("level", 1) - 1)
        page_str = f" (p.{item['page']})" if item.get("page") else ""
        lines.append(f"{indent}- {item['title']}{page_str}")
    return "\n".join(lines)


# ── LLM 调用 ────────────────────────────────────────

def build_prompt(tender_sections: str, bid_toc_text: str) -> tuple:
    """构造 LLM 提示词"""

    system = (
        "你是一个投标文件架构师。你的任务是基于招标文件的要求和格式规定，"
        "参考历史投标文件的结构，生成完整的投标文件目录大纲。\n\n"
        "输出 JSON 格式:\n"
        "{\n"
        '  "bid_title": "投标文件标题",\n'
        '  "packages": ["包件列表"],\n'
        '  "outline": [\n'
        "    {\n"
        '      "title": "章节标题",\n'
        '      "level": 1-6,\n'
        '      "source": {\n'
        '        "tender_section": "招标文件对应章节",\n'
        '        "bid_reference": "历史投标文件对应章节"\n'
        "      },\n"
        '      "needs_company_info": false,\n'
        '      "children": []\n'
        "    }\n"
        "  ]\n"
        "}\n\n"
        "要求:\n"
        "1. 必须覆盖招标文件第六章要求的所有格式表格\n"
        "2. 必须覆盖第五章评分标准的所有评分项\n"
        "3. 参考历史投标文件的章节划分方式\n"
        "4. 每项标明参考来源\n"
        '5. 需要投标公司提供材料的节点 needs_company_info=true\n'
        "6. 只输出 JSON，不要额外的说明文字"
    )

    user = (
        "请生成投标文件目录大纲。\n\n"
        "===== 招标文件关键内容 =====\n"
        f"{tender_sections[:25000]}\n\n"
        "===== 历史投标文件目录（参考） =====\n"
        f"{bid_toc_text[:15000]}\n\n"
        "项目背景: 松江区机关事务管理局物业管理服务（SJJCZB2025026）\n"
        "标项: 包件一（办公中心, 1739.51万） + 包件二（中山中路38号院, 1427.86万）\n"
        "服务期: 2026.1.1-2027.12.31 | 评标: 综合评分法 | 价格分10%\n"
        "大纲需包含: 商务响应文件 + 技术响应文件两卷。"
    )
    return system, user


def generate_outline(tender_text: str, bid_toc: list, output_path: str = None) -> dict:
    """
    生成投标目录大纲。

    Args:
        tender_text: 招标文件全文文本
        bid_toc: extract_bid_toc() 返回的目录列表
        output_path: 可选，保存路径

    Returns:
        大纲 JSON 字典
    """
    llm = LLM()
    tender_sections = collect_tender_key_sections(tender_text)
    bid_toc_text = format_bid_toc(bid_toc)

    print(f"[Phase2] 招标关键章节: {len(tender_sections)} 字符")
    print(f"[Phase2] 历史投标目录: {len(bid_toc)} 行, {len(bid_toc_text)} 字符")

    system, user = build_prompt(tender_sections, bid_toc_text)
    result_str = llm._call(system, user, max_tokens=16384, temperature=0.2,
                           response_format={"type": "json_object"})
    outline = json.loads(result_str)

    outline["_phase"] = "phase2_outline"
    outline["_generated_by"] = "generate_outline.py"

    if output_path:
        os.makedirs(os.path.dirname(output_path) or ".", exist_ok=True)
        with open(output_path, "w", encoding="utf-8") as f:
            json.dump(outline, f, ensure_ascii=False, indent=2)
        print(f"[Phase2] 大纲已保存: {output_path}")

    return outline


def print_outline_preview(outline: dict):
    """打印大纲预览"""
    def print_nodes(nodes, indent=0):
        for n in nodes:
            prefix = "  " * indent
            src = n.get("source", {})
            src_str = ""
            if isinstance(src, dict) and src.get("tender_section"):
                src_str = "  <- " + src["tender_section"]
            if n.get("needs_company_info"):
                src_str += " [需公司信息]"
            print(f"{prefix}{'-' if indent > 0 else ''} {n['title']}{src_str}")
            if n.get("children"):
                print_nodes(n["children"], indent + 1)

    for vol in outline.get("outline", []):
        print(f"\n{vol['title']}  <- {vol.get('source', {}).get('tender_section','')}")
        if vol.get("children"):
            print_nodes(vol["children"], 1)


# ── CLI ──────────────────────────────────────────────

if __name__ == "__main__":
    import sys
    sys.stdout.reconfigure(encoding="utf-8")

    base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    tender_file = os.path.join(base_dir, "松江区机关事务管理局物业管理服务招标文件_extracted.txt")
    bid_file = os.path.join(base_dir, "松江区机关事务管理局物业管理服务项目投标文件_extracted.txt")

    if not os.path.exists(tender_file):
        print("[Phase2] 未找到提取文本，先运行 Phase1 提取")
        sys.exit(1)

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

    from phase1_parsing.extract_bid_toc import extract_toc
    with open(bid_file, "r", encoding="utf-8") as f:
        bid_text = f.read()
    bid_toc = extract_toc(bid_text)

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