from __future__ import annotations

import csv
import hashlib
import html
import shutil
from datetime import datetime
from pathlib import Path

from docx import Document
from docx.enum.section import WD_SECTION
from docx.enum.table import WD_TABLE_ALIGNMENT, WD_CELL_VERTICAL_ALIGNMENT
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.shared import Cm, Inches, Pt, RGBColor
from openpyxl import load_workbook
from openpyxl.styles import Alignment, Font, PatternFill, Border, Side


ROOT = Path("/Users/jack/code/010-cpt/008-zhct/zhctprompt")
OUT = ROOT / "work/2026-05-25-team-meal-monthly-report-polish"
SOURCES = OUT / "sources"
OUTPUTS = OUT / "outputs"
DOC_SRC = Path("/Users/jack/Desktop/团餐业务中心5月月度报告_2026.docx")
XLSX_SRC = Path(
    "/Users/jack/Library/Containers/com.tencent.WeWorkMac/Data/Documents/Profiles/"
    "A74DF84611CC2ED79C4C206E40B5D80E/Caches/Files/2026-05/"
    "96ce2e79f5704c3f7a4e97b9262c11e1/XX项目汇报模版.xlsx"
)


def sha256(path: Path) -> str:
    h = hashlib.sha256()
    with path.open("rb") as f:
        for chunk in iter(lambda: f.read(1024 * 1024), b""):
            h.update(chunk)
    return h.hexdigest()


def set_cell_shading(cell, fill: str) -> None:
    tc_pr = cell._tc.get_or_add_tcPr()
    shd = tc_pr.find(qn("w:shd"))
    if shd is None:
        shd = OxmlElement("w:shd")
        tc_pr.append(shd)
    shd.set(qn("w:fill"), fill)


def set_cell_text(cell, text: str, bold: bool = False, color: str | None = None) -> None:
    cell.text = ""
    p = cell.paragraphs[0]
    run = p.add_run(text)
    run.font.name = "Microsoft YaHei"
    run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
    run.font.size = Pt(9)
    run.bold = bold
    if color:
        run.font.color.rgb = RGBColor.from_string(color)
    cell.vertical_alignment = WD_CELL_VERTICAL_ALIGNMENT.CENTER


def add_table(doc: Document, headers: list[str], rows: list[list[str]], widths: list[float] | None = None):
    table = doc.add_table(rows=1, cols=len(headers))
    table.alignment = WD_TABLE_ALIGNMENT.CENTER
    table.style = "Table Grid"
    hdr = table.rows[0].cells
    for i, header in enumerate(headers):
        set_cell_text(hdr[i], header, bold=True, color="FFFFFF")
        set_cell_shading(hdr[i], "1F4E79")
        hdr[i].paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.CENTER
    for row in rows:
        cells = table.add_row().cells
        for i, value in enumerate(row):
            set_cell_text(cells[i], value)
            cells[i].paragraphs[0].alignment = WD_ALIGN_PARAGRAPH.LEFT
    if widths:
        for row in table.rows:
            for idx, width in enumerate(widths):
                row.cells[idx].width = Cm(width)
    doc.add_paragraph()
    return table


def set_doc_styles(doc: Document) -> None:
    section = doc.sections[0]
    section.top_margin = Cm(1.6)
    section.bottom_margin = Cm(1.6)
    section.left_margin = Cm(1.7)
    section.right_margin = Cm(1.7)
    styles = doc.styles
    normal = styles["Normal"]
    normal.font.name = "Microsoft YaHei"
    normal._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
    normal.font.size = Pt(10.5)
    normal.paragraph_format.line_spacing = 1.18
    normal.paragraph_format.space_after = Pt(4)
    for name, size, color in [("Heading 1", 15, "1F4E79"), ("Heading 2", 12, "2F5597")]:
        style = styles[name]
        style.font.name = "Microsoft YaHei"
        style._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
        style.font.size = Pt(size)
        style.font.bold = True
        style.font.color.rgb = RGBColor.from_string(color)
        style.paragraph_format.space_before = Pt(9)
        style.paragraph_format.space_after = Pt(5)


def para(doc: Document, text: str, style: str | None = None, bold_prefix: str | None = None):
    p = doc.add_paragraph(style=style)
    if bold_prefix and text.startswith(bold_prefix):
        r1 = p.add_run(bold_prefix)
        r1.bold = True
        r1.font.name = "Microsoft YaHei"
        r1._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
        r2 = p.add_run(text[len(bold_prefix):])
        r2.font.name = "Microsoft YaHei"
        r2._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
    else:
        run = p.add_run(text)
        run.font.name = "Microsoft YaHei"
        run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
    return p


def bullet(doc: Document, text: str) -> None:
    p = doc.add_paragraph(style="List Bullet")
    run = p.add_run(text)
    run.font.name = "Microsoft YaHei"
    run._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
    run.font.size = Pt(10)


def build_docx() -> Path:
    doc = Document()
    set_doc_styles(doc)

    title = doc.add_paragraph()
    title.alignment = WD_ALIGN_PARAGRAPH.CENTER
    r = title.add_run("团餐业务中心 5 月月度经营与项目汇报（完善版）")
    r.font.name = "Microsoft YaHei"
    r._element.rPr.rFonts.set(qn("w:eastAsia"), "Microsoft YaHei")
    r.font.size = Pt(18)
    r.bold = True
    r.font.color.rgb = RGBColor.from_string("1F4E79")
    meta = doc.add_paragraph()
    meta.alignment = WD_ALIGN_PARAGRAPH.CENTER
    meta.add_run("汇报部门：团餐业务中心    汇报人：边磊    版本：2026-05-25 改稿").font.size = Pt(9)

    para(
        doc,
        "本版将原稿从“项目流水汇总”调整为“经营结果、项目池质量、渠道打法、产品控标能力、6月冲刺动作”五条线。"
        "所有金额沿用原稿；利润、毛利率、同期数据和回款状态没有来源时统一标为待财务确认，不做推测。",
    )

    doc.add_heading("一、5 月经营结论", level=1)
    add_table(
        doc,
        ["指标", "5月目标", "5月预计达成", "达成率", "年度目标", "年度累计", "累计达成率"],
        [["确收（万元）", "96", "54", "56%", "1200", "167", "14%"]],
        [2.3, 2.0, 2.2, 1.8, 2.0, 2.0, 2.0],
    )
    bullet(doc, "结果判断：5 月确收未达成，短板不是单一项目执行问题，而是项目池厚度、渠道转化和确收节奏尚未形成稳定滚动。")
    bullet(doc, "积极变化：本月完成签约项目 8 个，签约金额 141.5 万元；预计确收项目 7 个，确收 54 万元；新增北京区 8 个、江苏区 6 个客户线索。")
    bullet(doc, "经营含义：6 月不能只追单点签约，需要把高优先级项目、核心渠道、控标参数和验收回款放到同一张经营表里滚动管理。")

    doc.add_heading("二、5 月核心业务进展", level=1)
    doc.add_heading("2.1 签约项目", level=2)
    add_table(
        doc,
        ["项目名称", "合作类型", "产品配置", "金额（万元）"],
        [
            ["副中心项目", "直营项目", "营养管理", "72.5"],
            ["重庆环卫", "系统集成渠道", "营养结算 + 食安监管 + 进销存", "25"],
            ["河北石家庄园区项目", "厨具渠道", "AI营养结算", "3"],
            ["建林中学项目", "系统集成渠道", "基础结算", "0.5"],
            ["首都机场增订项目", "系统集成渠道", "基础结算", "3"],
            ["荣海中学项目", "系统集成渠道", "基础结算", "2.5"],
            ["人大附中项目", "直营项目", "电子菜单系统", "5"],
            ["三全项目（软件）", "系统集成渠道", "营养结算 + 食安监管 + 进销存", "30"],
            ["合计", "", "", "141.5"],
        ],
        [4.1, 3.0, 6.2, 2.0],
    )
    doc.add_heading("2.2 确收项目", level=2)
    add_table(
        doc,
        ["项目名称", "合作类型", "产品配置", "确收金额（万元）"],
        [
            ["重庆环卫项目（软件）", "系统集成渠道", "营养结算 + 食安监管 + 进销存", "10"],
            ["河北石家庄园区项目", "厨具渠道", "AI营养结算", "3"],
            ["建林中学项目", "系统集成渠道", "基础结算", "0.5"],
            ["首都机场增订项目", "系统集成渠道", "基础结算", "3"],
            ["荣海中学项目", "系统集成渠道", "基础结算", "2.5"],
            ["人大附中项目", "直营项目", "电子菜单系统", "5"],
            ["三全项目（软件）", "系统集成渠道", "营养结算 + 食安监管 + 进销存", "30"],
            ["合计", "", "", "54"],
        ],
        [4.1, 3.0, 6.2, 2.0],
    )

    doc.add_heading("三、项目池与渠道判断", level=1)
    para(doc, "5 月新增储备项目已经能支撑 6 月冲刺，但项目池质量仍需分层管理：高优先级项目抓签约和确收，中优先级项目抓决策链、预算阶段和下一次客户动作。")
    add_table(
        doc,
        ["优先级", "项目", "当前进展", "成交概率", "6月管理动作"],
        [
            ["高", "大兴区政府", "客户启动立项申请，配合渠道提供资料", "70%", "锁定预算、决策链、采购路径和确收节点"],
            ["高", "国康医院", "已完成调价洽谈，力争 6 月签约", "60%", "明确合同版本、产品配置和验收口径"],
            ["高", "内蒙古保康中学", "深度跟进，核心需求明确", "60%", "补齐食安/进销存/营养结算方案和报价边界"],
            ["中", "滨州健康科技职业学院", "50 台称重设备需求明确，计划 8 月上线", "50%", "安排来司考察后的标准方案、控标参数和设备清单"],
            ["中", "淮北市委餐厅 / 机关事务局", "完成前期对接", "40%", "推进方案汇报，确认采购时点"],
            ["中", "秦皇岛物业园区、张家口中煤等", "完成方案沟通或现场需求沟通", "30%", "沉淀客户画像和下一步拜访计划"],
        ],
        [1.3, 3.2, 5.4, 1.5, 5.2],
    )

    doc.add_heading("四、问题分析与改进策略", level=1)
    add_table(
        doc,
        ["问题", "对经营的影响", "6月改进策略", "验收口径"],
        [
            ["项目池底子薄，月度确收波动大", "签约和验收无法形成滚动雪球，月度目标依赖少数项目", "项目池不低于 30 个，按高/中/低概率滚动；每周复盘预算、决策链、阻塞和下一动作", "每周更新项目池表，重点项目有责任人和下次客户动作"],
            ["优质渠道开拓慢，存量渠道转化不足 5%", "线索多但有效商机少，渠道投入产出不可判断", "集中深耕 5-8 家核心渠道，低质渠道仅常规维护；厨具渠道作为 6 月攻坚方向", "核心渠道清单、拜访记录、商机转化率、实际订单产出"],
            ["销售自主拓新弱，过度依赖分配线索", "新增客户来源不稳定，团队能力难复制", "每人每周新增 2 家新渠道、20 个有效客户电话；把无效拜访从日报中剔除", "有效客户定义、跟进记录、转商机数量"],
            ["控标能力弱，营养健康优势没有转成招标门槛", "产品差异无法进入评分项，容易被普通智慧食堂厂商同质化竞争", "按企业资质、产品资质、软件功能、硬件设备四类补控标参数和证据链", "重点项目投标前完成控标参数清单和证据附件"],
        ],
        [3.4, 4.0, 5.6, 4.0],
    )

    doc.add_heading("五、6 月经营规划", level=1)
    add_table(
        doc,
        ["目标类型", "目标值", "管理口径"],
        [
            ["签约", "完成月度签约目标", "重点落地三全集团、重庆环卫、国康医院、保康中学、大兴区政府等核心项目"],
            ["确收", "底线 147 万；冲刺 200 万；半年度确收 400 万", "147 万来自明确预计确收清单；200 万属于冲刺目标，需补新增确收来源"],
            ["渠道", "新增 3-5 家优质核心渠道，渠道商机转化率提升至 10% 以上", "聚焦系统集成、厨具和餐饮渠道，不再平均撒网"],
            ["团队", "至少 1 名新销售入职，2 次专项培训", "以实战项目、客户反馈和控标材料使用情况判断人员能力"],
            ["投标/产品", "重点项目控标率提升至 80% 以上，投标响应零差错", "投标前置介入，控标参数和证据链由产品/售前共同把关"],
        ],
        [3.0, 4.2, 8.0],
    )
    doc.add_heading("6 月预计确收清单", level=2)
    add_table(
        doc,
        ["项目名称", "合作类型", "产品配置", "预计确收（万元）"],
        [
            ["大兴区政府", "系统集成渠道", "营养结算", "50"],
            ["保康中学", "系统集成渠道", "营养结算 + 食安监管 + 进销存", "20"],
            ["三全项目（硬件）", "系统集成渠道", "营养结算 + 食安监管 + 进销存", "40"],
            ["重庆环卫（硬件）", "系统集成渠道", "食安监管 + 进销存", "15"],
            ["金斯瑞新需求", "餐饮渠道", "开发需求", "5"],
            ["国康医院", "直营项目", "营养结算", "17"],
            ["合计", "", "", "147"],
        ],
        [4.0, 3.0, 6.4, 2.0],
    )

    doc.add_heading("六、需要产品与交付协同的重点事项", level=1)
    bullet(doc, "产品控标：把营养健康、食安监管、进销存和智能硬件拆成可写入招标文件的具体参数，不再停留在“有营养师、有案例”的泛化表达。")
    bullet(doc, "售前工具：优先准备营养周报、带量食谱分析、电子菜牌演示、小程序试用、体脂秤/手环等轻量体验工具，用低成本试用推进客户进入商机。")
    bullet(doc, "交付证据：金斯瑞、江西 206、首都机场、人大附中等项目要补上线截图、验收确认、设备清单、售后边界和可复用模块，避免小单只形成一次性收入。")
    bullet(doc, "经营数据：利润、毛利率、同期数据、回款状态、交付工时和复用模块数仍缺口明显，建议 6 月纳入项目周表。")

    doc.add_heading("七、需管理层确认", level=1)
    add_table(
        doc,
        ["确认事项", "为什么现在要确认", "建议结论"],
        [
            ["6 月确收口径", "当前明确清单为 147 万，原稿同时提出冲刺 200 万", "对外/管理层汇报用“底线 147、冲刺 200”，并要求补 53 万来源"],
            ["核心渠道资源投入", "渠道拓展已从广撒网转向深耕核心渠道", "确认 5-8 家核心渠道名单和每家月度目标"],
            ["产品控标牵头机制", "控标能力直接影响重点项目中标率", "由产品/售前牵头四类参数库，销售提供客户与竞品输入"],
            ["财务经营字段", "利润、毛利、同期数据和回款影响管理层判断", "财务补齐利润、毛利率、回款和同期对比口径"],
        ],
        [4.0, 5.4, 5.0],
    )

    out = OUTPUTS / "团餐业务中心5月月度报告_2026_完善版.docx"
    doc.save(out)
    return out


def fill_template_xlsx() -> Path:
    wb = load_workbook(XLSX_SRC)
    ws = wb["项目"]

    fill_blue = PatternFill("solid", fgColor="D9EAF7")
    fill_yellow = PatternFill("solid", fgColor="FFF2CC")
    thin = Side(style="thin", color="BFBFBF")
    border = Border(left=thin, right=thin, top=thin, bottom=thin)

    values = {
        "A1": "团餐业务中心5月月度汇报",
        "A2": "汇报人：边磊    部门：团餐业务中心    版本：2026-05-25 完善版",
        "C5": 96,
        "E5": "待财务确认",
        "C6": 54,
        "E6": "待财务确认",
        "E7": "待财务确认",
        "C8": "待确认",
        "E8": "待确认",
        "C9": "待确认",
        "E9": "待确认",
        "C11": 1200,
        "E11": "待财务确认",
        "C12": 167,
        "E12": "待财务确认",
        "E13": "待财务确认",
        "C14": "待确认",
        "E14": "待确认",
        "B18": "项目池底子薄，无法形成稳定签约和验收滚动，月度确收波动大",
        "D18": "项目池不低于30个，按高/中/低概率滚动；每周复盘预算、决策链、阻塞和下一动作",
        "B19": "优质渠道开拓进展慢，存量渠道转化不足5%，多数渠道停留在初步建联",
        "D19": "聚焦5-8家核心渠道，厨具渠道作为6月攻坚方向；用拜访记录、商机转化率和订单产出考核",
        "B20": "控标能力弱，营养健康优势没有充分转成投标参数和评分项",
        "D20": "按企业资质、产品资质、软件功能、硬件设备四类补控标参数和证据链",
        "C23": 150,
        "D23": "待确认",
        "E23": "待确认",
        "C24": "待财务确认",
        "C25": "待财务确认",
        "D25": "待确认",
        "E25": "待确认",
        "B28": "项目签约攻坚",
        "C28": "三全集团、重庆环卫、国康医院、保康中学、大兴区政府",
        "E28": "锁预算、决策链、合同版本、验收口径和确收节点",
        "B29": "验收回款推进",
        "C29": "江西206、中央国债、荣海小学、机场等项目收尾",
        "E29": "补上线截图、验收确认、售后边界和回款状态",
        "B30": "渠道深耕拓展",
        "C30": "系统集成、厨具、餐饮渠道",
        "E30": "每人新增2个核心渠道，渠道商机转化率目标10%以上",
        "B31": "产品与投标优化",
        "C31": "营养健康差异化、控标参数、轻量售前工具",
        "E31": "重点项目投标前完成四类参数和证据附件",
        "A35": "核心渠道拜访与出差",
        "C35": "待确认",
        "D35": "内蒙古、山西、河南等重点渠道拜访，产出核心渠道清单",
        "A36": "售前演示与样张",
        "C36": "待确认",
        "D36": "营养周报、带量食谱分析、电子菜牌、小程序试用",
        "A37": "投标控标材料",
        "C37": "待确认",
        "D37": "四类控标参数、证据附件、竞品对标材料",
        "A38": "团队专项培训",
        "C38": "待确认",
        "D38": "谈单、控标、渠道开发、项目复盘培训",
        "C39": "待确认",
        "C41": "产品端补充控标参数库：企业资质、产品资质、软件功能、硬件设备四类参数，6月用于重点项目投标前置介入。",
        "C42": "卖点从泛化营养服务转为具体功能：热量显示、带量食谱、AI排菜、营养报告、健康设备对接、食安监管证据链。",
        "C43": "降本重点不是压缩交付，而是把小单沉淀为标准配置、验收清单、操作手册和售后边界，降低重复沟通成本。",
        "C45": "市场内容建议按企业/机关、学校/教委、医院/园区三个版本输出场景话术和案例样张。",
        "C46": "6月需补同期收入、利润、毛利率、回款周期、渠道转化率、项目交付工时等经营字段。",
        "C47": "定价策略需区分项目型收入、产品型收入和持续服务收入；当前所有利润口径待财务确认。",
        "C48": "产品策略聚焦企业/机关标准包、学校/教委监管包、食安+进销存+硬件证据链包。",
    }
    for cell, value in values.items():
        ws[cell] = value
        ws[cell].alignment = Alignment(wrap_text=True, vertical="center")
        if cell.startswith(("C", "E")):
            ws[cell].fill = fill_yellow

    for row in ws.iter_rows(min_row=1, max_row=48, min_col=1, max_col=6):
        for cell in row:
            cell.border = border
            cell.alignment = Alignment(wrap_text=True, vertical="center")
            if cell.row in [3, 10, 16, 21, 26, 33, 40, 44]:
                cell.font = Font(name="Microsoft YaHei", bold=True, color="FFFFFF", size=11)
                cell.fill = PatternFill("solid", fgColor="1F4E79")
            else:
                cell.font = Font(name="Microsoft YaHei", size=10)
    for col, width in {"A": 18, "B": 22, "C": 24, "D": 20, "E": 24, "F": 24}.items():
        ws.column_dimensions[col].width = width
    for row in range(1, 49):
        ws.row_dimensions[row].height = 28
    if ws.max_column > 6:
        ws.delete_cols(7, ws.max_column - 6)
    ws.print_area = "A1:F48"
    ws.sheet_properties.pageSetUpPr.fitToPage = True
    ws.page_setup.fitToWidth = 1
    ws.page_setup.fitToHeight = 2
    ws.freeze_panes = "A4"

    out = OUTPUTS / "团餐业务中心5月项目汇报模板_填报版.xlsx"
    wb.save(out)
    return out


def write_markdown_and_html(docx_out: Path, xlsx_out: Path) -> None:
    source_rows = [
        ["SRC-01", str(DOC_SRC), "A/B", "用户提供的原始 Word 月报，金额、项目清单和问题清单直接来源"],
        ["SRC-02", str(XLSX_SRC), "B", "用户提供的项目汇报 Excel 模板，作为结构填报口径"],
        ["SRC-03", "work/2026-05-22-monthly-summary-june-plan/monthly-summary-and-plan.md", "B/D", "数科业务月度总结和产品标准化口径"],
        ["SRC-04", "standards-stack/product-strategy/smart-canteen/bid-parameter-library/product-differentiation-score-model-v0.3.md", "B/D", "产品差异性和控标参数四类口径"],
        ["SRC-05", "work/2026-05-25-delivery-ops-weekly-template-pack/outputs/project_delivery_one_table.csv", "B/D", "项目交付一张表字段和重点项目证据缺口"],
    ]
    with (OUT / "source-index.csv").open("w", encoding="utf-8", newline="") as f:
        writer = csv.writer(f)
        writer.writerow(["id", "source", "evidence_level", "usage"])
        writer.writerows(source_rows)

    summary = f"""# 团餐业务中心 5 月月度报告完善说明

- 生成时间：{datetime.now().strftime("%Y-%m-%d %H:%M:%S %z")}
- 原始 Word：`{DOC_SRC}`
- Excel 模板：`{XLSX_SRC}`
- 输出 Word：`{docx_out}`
- 输出 Excel：`{xlsx_out}`

## 目标

把原始月报从“项目清单 + 目标动作”完善为更适合管理层审阅的经营汇报：

1. 先讲 5 月经营结果和差距。
2. 再讲项目池、渠道、签约、确收和 6 月冲刺关系。
3. 把问题分析改成“问题 - 经营影响 - 改进策略 - 验收口径”。
4. 把产品控标、营养健康差异化、交付证据补齐纳入 6 月协同事项。
5. 对缺少来源的利润、毛利率、同期数据、回款状态标注 `待财务确认`。

## 核心改动

- 保留原稿金额：5 月目标 96 万、预计确收 54 万、达成率 56%、年度累计 167 万、签约 141.5 万、6 月预计确收 147 万。
- 将“6 月确收 200 万突破”和“预计清单 147 万”拆成：底线 147 万、冲刺 200 万、需补 53 万新增来源。
- 强化 6 月管理动作：核心渠道 5-8 家、渠道转化率 10% 以上、每人每周新增 2 家新渠道/20 个有效电话、重点项目控标率 80% 以上。
- 增加管理层确认事项：6 月确收口径、核心渠道名单、产品控标牵头机制、财务经营字段。

## 证据边界

- 原稿中没有利润、毛利率、同期数据、回款状态和交付工时，因此本版不推测。
- 数科业务第二增长曲线、可复制收入和投资人视角只作为经营分析框架，不写成已证明事实。
- 控标参数库和产品差异性模型为内部工作台口径，正式投标材料前仍需产品、售前、商务和法务核验。

## 人审建议

- 财务补齐利润、毛利率、同期收入/利润和回款状态。
- 团餐业务中心确认 6 月冲刺 200 万的新增 53 万来源。
- 销售负责人确认 5-8 家核心渠道名单和每家渠道目标。
- 产品/售前确认四类控标参数是否可进入重点项目投标前置材料。
"""
    (OUT / "summary.md").write_text(summary, encoding="utf-8")

    html_rows = "".join(
        f"<tr><td>{html.escape(r[0])}</td><td>{html.escape(r[1])}</td><td>{html.escape(r[2])}</td><td>{html.escape(r[3])}</td></tr>"
        for r in source_rows
    )
    review = f"""<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>团餐业务中心5月月度报告完善版 Review</title>
<style>
body{{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Microsoft YaHei",sans-serif;margin:0;background:#f6f8fb;color:#1f2937;line-height:1.65}}
.wrap{{max-width:1120px;margin:0 auto;padding:36px 28px 56px}}
.hero{{background:#123a5f;color:#fff;border-radius:12px;padding:28px 32px;margin-bottom:22px}}
.hero h1{{margin:0 0 8px;font-size:28px}}
.grid{{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin:18px 0}}
.kpi{{background:#fff;border:1px solid #d7e1ea;border-radius:10px;padding:16px}}
.kpi b{{display:block;color:#123a5f;font-size:24px}}
section{{background:#fff;border:1px solid #d7e1ea;border-radius:10px;padding:22px 24px;margin:16px 0}}
h2{{margin:0 0 10px;color:#123a5f}}
table{{border-collapse:collapse;width:100%;font-size:14px}}
th,td{{border:1px solid #d7e1ea;padding:9px 10px;vertical-align:top}}
th{{background:#e8f1f8;color:#123a5f;text-align:left}}
.tag{{display:inline-block;background:#fff2cc;color:#6b4b00;border:1px solid #ecd27b;border-radius:999px;padding:2px 9px;margin-right:6px}}
a{{color:#0f5ea8}}
ul{{margin:8px 0 0 20px}}
</style>
</head>
<body>
<div class="wrap">
  <div class="hero">
    <h1>团餐业务中心 5 月月度报告完善版</h1>
    <div>定位：经营汇报 + 项目池复盘 + 6 月冲刺计划 + 产品控标协同</div>
  </div>
  <div class="grid">
    <div class="kpi"><span>5月确收</span><b>54 万</b><small>目标 96 万，达成 56%</small></div>
    <div class="kpi"><span>年度累计</span><b>167 万</b><small>年度目标 1200 万，达成 14%</small></div>
    <div class="kpi"><span>5月签约</span><b>141.5 万</b><small>8 个签约项目</small></div>
    <div class="kpi"><span>6月确收</span><b>147 / 200 万</b><small>底线 147，冲刺 200</small></div>
  </div>
  <section>
    <h2>本版解决的问题</h2>
    <ul>
      <li>把原稿中“147 万预计确收”和“200 万冲刺”拆成底线与冲刺口径。</li>
      <li>把问题分析从原因罗列改为可执行的验收口径。</li>
      <li>补入渠道深耕、控标参数、售前工具、交付证据和财务字段缺口。</li>
      <li>明确未提供来源的数据不推测，统一标为 <span class="tag">待财务确认</span> 或 <span class="tag">待确认</span>。</li>
    </ul>
  </section>
  <section>
    <h2>交付文件</h2>
    <table>
      <tr><th>文件</th><th>用途</th></tr>
      <tr><td><a href="outputs/{docx_out.name}">{docx_out.name}</a></td><td>可直接打开和继续编辑的 Word 完善版。</td></tr>
      <tr><td><a href="outputs/{xlsx_out.name}">{xlsx_out.name}</a></td><td>按用户给的 Excel 模板填好的经营/问题/6月策略版。</td></tr>
      <tr><td><a href="summary.md">summary.md</a></td><td>AI 可读改稿说明。</td></tr>
      <tr><td><a href="source-index.csv">source-index.csv</a></td><td>来源、证据等级和使用方式。</td></tr>
    </table>
  </section>
  <section>
    <h2>人审 Checklist</h2>
    <ul>
      <li>财务是否能补利润、毛利率、同期数据、回款状态。</li>
      <li>6 月冲刺 200 万是否有新增 53 万来源。</li>
      <li>核心渠道 5-8 家名单是否已经确定。</li>
      <li>控标参数是否由产品/售前统一审核后再进入重点项目投标材料。</li>
    </ul>
  </section>
  <section>
    <h2>来源索引</h2>
    <table><tr><th>ID</th><th>来源</th><th>证据等级</th><th>用途</th></tr>{html_rows}</table>
  </section>
</div>
</body>
</html>
"""
    (OUT / "review.html").write_text(review, encoding="utf-8")


def main() -> None:
    SOURCES.mkdir(parents=True, exist_ok=True)
    OUTPUTS.mkdir(parents=True, exist_ok=True)
    shutil.copy2(DOC_SRC, SOURCES / DOC_SRC.name)
    shutil.copy2(XLSX_SRC, SOURCES / XLSX_SRC.name)
    docx_out = build_docx()
    xlsx_out = fill_template_xlsx()
    write_markdown_and_html(docx_out, xlsx_out)
    print(docx_out)
    print(xlsx_out)
    print("doc_sha256", sha256(docx_out))
    print("xlsx_sha256", sha256(xlsx_out))


if __name__ == "__main__":
    main()
