#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
单校区开工闸门 / Campus Workflow Gate
=====================================
南通新东方租赁合同梳理——每开一个新校区，动手前必须先跑这个脚本。

为什么存在：防止"开新校区时凭上个校区的印象乱跑/跳步"。
这是物理闸门——脚本把【从头到尾的完整流程】+【单校区独立闭环纪律】打印出来，
逼自己逐条确认，不跑不准动手填表。

🔴 通读强制纪律（悦拾光0703教训，详见 references/fulltext-reading-discipline-0703.md）：
   Step2动作A法律审查必须 read_file 从第1行读到最后一行（每批500行），不得 grep 代替。
   I列按21/15固定类目逐项摘录原文（格式：· [类目] 原文（条款号））。
   建完表后跑 scripts/i-column-coverage-check.py 报警核查覆盖率。

用法：
    python3 campus-workflow-gate.py <校区名>
例：
    python3 campus-workflow-gate.py 人民中路

它会：
  1. 打印「单校区独立闭环纪律」——本校区从 Step0 从头做，不受其他校区影响
  2. 打印完整 Step 0→7 workflow + 三角色 + 交付物板块的强制清单
  3. 定位该校区在 Nextcloud 的源文件夹 + 汇总表应存放的位置（=校区自己的文件夹）
  4. 生成一份待打勾的 todo 文本，贴进 todo 工具
"""
import sys, os, subprocess

NC_CONTAINER = "nextcloud-nextcloud-1"
NC_BASE = "/var/www/html/data/admin/files/小Maggie协作区/南通新东方/履约期内非集采合同-综办/房租物业合同"
NC_DAV  = "小Maggie协作区/南通新东方/履约期内非集采合同-综办/房租物业合同"

def campus_dir_exists(campus):
    p = f"{NC_BASE}/{campus}"
    r = subprocess.run(["docker","exec",NC_CONTAINER,"test","-d",p],
                       capture_output=True)
    return r.returncode == 0

def list_campus_files(campus):
    p = f"{NC_BASE}/{campus}"
    r = subprocess.run(["docker","exec",NC_CONTAINER,"bash","-c",f'ls -la "{p}"'],
                       capture_output=True, text=True)
    return r.stdout

def main():
    if len(sys.argv) < 2:
        print("用法: python3 campus-workflow-gate.py <校区名>")
        print("例:   python3 campus-workflow-gate.py 人民中路")
        sys.exit(1)
    campus = sys.argv[1].strip()

    bar = "=" * 70
    print(bar)
    print(f"  单校区开工闸门 · 校区 = 【{campus}】")
    print(bar)

    # ---- 第一道：独立闭环纪律 + 地基四铁律 ----
    print("""
🔴🔴 单校区独立闭环纪律（Maggie 2026-06-23 立，开工前默念）🔴🔴
  1. 本校区从 Step 0 从头做到 Step 6 独立跑一遍(Step 7 总览是全部校区定稿后的全局收尾)。
  2. 绝不受其他校区影响——不拿"上个校区做过/世茂悦拾光是这样"的印象代替
     本校区的逐字通读、逐条审查、回 07 原件比对。每个校区都是第一次。
  3. 别的校区的结论、定级、措辞，统统不假设适用于本校区；一切回本校区原文。
  4. 这是一次"全新合同全面审"，不是"套上一份的模子"。

🔴🔴 地基四铁律（Maggie 2026-06-26 重申，优先级最高）🔴🔴
  1. 逐字逐句：亲自读完整篇OCR，一字不跳。OCR乱码停→vision核实，不准跳过猜值。
     🔴 Step1完成后必跑 ocr-garble-detect.py 扫全文乱码，高危行逐条vision消灭（教训：
     凤凰文化10.2乱码未核实→整段"初年年租金20%违约金"丢失→审查结论反转→返工）
  2. 整体理解：通读全文后再逐条审，先建立全文结构认知。
  3. 上下文联系：每读一条问"这条被别处限定/修改了吗？"
  4. 逻辑分析：数字、比例、日期、主体用逻辑推一遍——合理吗？自洽吗？
""")

    # ---- 第二道：完整流程强制清单 ----
    print("""———— 完整 WORKFLOW（缺一步不交付）————
 Step 0  文件盘点归类：按文件夹结构（房租/扩租/物业），含空目录，不跨夹重排
 Step 1  取 PDF + OCR→.md（大文件后台跑；纯扫描件文字层=0 必 OCR）
 Step 2  承办（四眼分离前半）【并行,不串行】：
          ⚡ 开工第一动作 = 立刻 delegate_task 发动作B 到后台,发出的同一秒自己开读动作A
          · 动作B 提取分析 = subagent(后台先发)：OCR要素+模版比对+退租敞口+填表初稿
          · 动作A 法律审查 = 小Maggie本人主审(B发出后立即开读)，亲自 read_file 逐字通读全文，
            八维框架，当全新合同审（独立法律审查框架）—— 两件事同时跑,绝不先做完A再做B
          · 🔴 模版比对必须回 07-房屋租赁合同.docx 原件逐条核（subagent context 带原件路径）
 Step 3  写 Excel：12 列（K=法律风险/L=模版差异，物理分列）；
          按文件夹分板块；末尾必有「整体风险分析与建议」段
          · 各列规则详见 references/column-rules-0701.md（Maggie校准版，优先级最高）
          · H列四检：①条款号 ②月租换算 ③付款推算 ④❗标注。缺一不过，不过不交付。
          · 需客户核实内容整条标红（富文本红是最后一步→WPS另存/sharedStrings XML层）
 Step 4  三角色校对：法律校对 ‖ 格式校对（六维清单）→ 闭环复核
 Step 5  小Maggie终审：合并法律风险栏、回07原件复核L列、确认问题闭环、最后把关
          · 🔴 K/L 分工自检(必跑)：K列 grep "模版|07模版|07-房屋"=0(独立审查不引模版,
            匹配"07模版"而非裸07防误命中金额数字)；L列 grep "风险|建议|不利|详见"=0(纯客观不下判断)。
            任一非0即回去拆分。判据=遮模版测试：把"模版怎么写"遮住,K列风险论述仍完整成立才算独立。
 Step 6  交付前自查+存档：x2t渲染PDF + pdftotext拍平grep验文字 + vision验视觉(图先压<400KB)
          → 汇总表存本校区文件夹 + files:scan + 清OO缓存 → 发Maggie核
 〔全部校区定稿后〕Step 7  整合总览sheet（全局收尾，非单校区步骤）
———— 交付物必含板块（验收必查）————
  逐条风险(🔴🟡🟢分级,标条款号) + 整体风险分析与建议段 + L列模版差异(回07原件)
""")

    # ---- 第三道：存放纪律 + 定位 ----
    print(bar)
    print("  📁 汇总表存放纪律（Maggie 2026-06-23 立）")
    print(bar)
    exists = campus_dir_exists(campus)
    if exists:
        print(f"✅ 校区源文件夹已定位：")
        print(f"   容器路径: {NC_BASE}/{campus}/")
        print(f"   WebDAV  : {NC_DAV}/{campus}/")
        print(f"\n   本校区文件清单：")
        for line in list_campus_files(campus).splitlines():
            if line.strip() and not line.startswith("total"):
                print(f"     {line}")
    else:
        print(f"⚠️  未在标准路径找到校区目录【{campus}】。请先核对校区名，或确认目录是否在别处：")
        print(f"   预期: {NC_BASE}/{campus}/")
        print(f"   （17 个校区均在 房租物业合同/ 下，标准名单：")
        print(f"     万达、世茂、人民中路、凤凰文化、北翼玖玖、南通大厦、小石桥晏园、悦拾光、")
        print(f"     星月、桃坞路、解放中路、跃龙路、通大、通大附、通州金鹰、金飞达、龙信）")
    print(f"""
🔴 本校区汇总表【必须】存到本校区自己的文件夹下，不放别处、不放公共目录：
   存放路径: {NC_DAV}/{campus}/
   命名规则: {campus}-梳理-MJ-YYYYMMDD.xlsx （当事人/项目名+文件名+修改人+日期）
   —— 每个校区的汇总表归到各自校区文件夹，与该校区合同放一起，便于客户对照查阅。
""")

    # ---- 第四道：吐出 todo 文本 ----
    print(bar)
    print("  ⬇️ 把下面这份 todo 贴进 todo 工具，逐项打勾（缺一项不交付）")
    print(bar)
    todos = [
        f"[{campus}] Step0 文件盘点归类(含空目录,不跨夹重排;多租赁物先按租赁物分类再按签约时间排列;详细K/L/I放最早签约那份行里后续写同上)",
        f"[{campus}] Step1 取PDF+OCR→.md(纯扫描件必OCR)+保存.md到同目录 → 跑 ocr-garble-detect.py 扫乱码 → 高危乱码每处vision核实消灭 → 全灭才进Step2",
        f"[{campus}] Step2 承办【并行,不串行】⚡开工第一动作=立刻 delegate_task 发动作B(模版比对回07原件,仅租赁合同需比对,物业等其他合同不需要)到后台 → 发出的同一秒自己开读动作A(本人逐字通读全文+八维当全新合同审)。两件事同时跑,绝不先做完A再做B",
        f"[{campus}] Step3 写12列Excel(K法律风险/L模版差异分列)+H列四检+整体风险分析段+标红。🔴必须用 templates/single-campus-builder.py 照抄改值，禁裸写 openpyxl。🔴建L列前必read_file subagent比对文件，从里面逐条摘差异。🔴各列规则见 references/column-rules-0701.md（多合同时详细K/L放最早签约那份行里，后续行写同上）",
        f"[{campus}] Step4 三角色校对(法律‖格式)闭环复核",
        f"[{campus}] Step5 终审:合并法律风险+回07原件复核L列+K/L分工自检(K列grep'模版|07'=0,L列grep'风险|建议|不利|详见'=0)+确认闭环",
        f"[{campus}] Step6 交付自查(x2t渲染+pdftotext验文字+vision验视觉)+存本校区文件夹",
        f"[{campus}] 存档:汇总表存到本校区文件夹 {campus}/ + files:scan + 清OO缓存",
    ]
    for i, t in enumerate(todos, 1):
        print(f"  {i}. {t}")
    print()

    # ---- 🔴 第五道：物理卡口（防跳步）----
    print(bar)
    print("  🔴🔴 物理卡口（以下两条不做到 = 返工，不交付）🔴🔴")
    print(bar)
    print("""
  卡口① 格式强制：Step3 写表必须用模板脚本
    → 路径：~/.hermes/skills/legal/contract-portfolio-analysis/templates/single-campus-builder.py
    → 方法：cp 到工作目录，改 TODO 标记的值（标题、项目信息、D5..L5、D8..L8、整体段、输出路径）
    → 禁止：自己 openpyxl 裸写样式、自创颜色、改列头措辞
    → 自检：交付前打开文件，和人民中路定稿并排对比——标题酒红底白字？段标题红底？行2灰底？
      K列头="法律风险（站乙方立场）"？L列头="与07标准模版差异"？冻结A5？行高30/76/409.5？

  卡口② 模版比对强制：Step2 动作B 必须 delegate_task subagent
    → 不能：自己读07模版后手写L列差异（会漏、会简略、会凭印象）
    → 做法：OCR完成后立即 delegate_task，context 含 07模版路径 + 两份合同OCR路径
    → 🔴 建表前必做：read_file 读 subagent 比对文件全文，L列从里面逐条摘、不从脑子里摘
    → 自检①：subagent 返回的差异清单是否 ≥ 20 条？
    → 自检②：L列每条差异是否都能在 subagent 比对文件里找到原文对应？
      "甲方制式格式，与07模版不同"这种一句话概括 = 没读 subagent 文件 = 返工
      subagent 抓到的差异（如举报邮箱新增、供电功率矛盾、首期期间变更）
      你在 L 列里没写 = 没读 subagent 文件 = 返工

  卡口③ 交付前格式自检（跑脚本，不凭眼）：
    → python3 scripts/kl-separation-check.py <out.xlsx>  # K列零模版、L列零判断词
    → python3 -c "import openpyxl; wb=openpyxl.load_workbook('<out.xlsx>');
      ws=wb[wb.sheetnames[0]];
      assert ws.cell(1,1).fill.start_color.rgb=='FF8B1A2B','标题不是酒红底';
      assert ws.cell(3,1).fill.start_color.rgb=='FFC0504D','段标题不是红底';
      assert ws.cell(4,11).value=='法律风险（站乙方立场）','K列头不对';
      assert ws.cell(4,12).value=='与07标准模版差异','L列头不对';
      print('OK')"
""")
    print("提醒：开工前默念独立闭环纪律——本校区从头做，不受其他校区影响。")

if __name__ == "__main__":
    main()
