#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""生成《技能开放勾选清单》交互式 HTML（给刘新元勾选用）。

数据来源：zone-b profile 的 skills/.usage.json（真实使用次数 + 最近使用时间）
用法：打开后勾选 → 点「复制勾选结果」→ 把文本发回来 → 据此生成销售助手使用手册
"""
import json
import os
import sys
from datetime import datetime

sys.path.insert(0, os.path.expanduser('~/Desktop/Hermes输出-工作类/脚本'))
import brand_kit as BK  # noqa: E402

USAGE = os.path.expanduser('~/.hermes/profiles/zone-b/skills/.usage.json')
HER = os.path.expanduser('~/.hermes/profiles/baorui-sales/skills')
OUT = '/Users/liuxinyuan/Desktop/Hermes输出-工作类/内部管理/技能开放勾选清单.html'

# 分类：(技能名, 用途一句话, 建议)  建议：ok=建议开 / careful=谨慎 / no=不建议
CATS = [
    ('A · 客户与销售日常', [
        ('baorui-customer-project-sku-lookup', '查某客户/项目用什么货号、采购与发货记录', 'ok'),
        ('baorui-erp-sku-trace', '给一个货号，反查它是什么、哪个项目、谁在买', 'ok'),
        ('baoyu-product-sku-decoding', '货号定制尾缀解码、客户归属溯源', 'ok'),
        ('baoyu-customer-identity', '客户名识别与数据匹配（别名/集团归并）', 'ok'),
        ('customer-project-history-briefing', '把一个客户的项目来龙去脉重建时间线', 'ok'),
        ('baoyu-customer-analysis', '客户采购趋势/主销货号/同比分析', 'ok'),
        ('baoyu-customer-profile', '客户 360 档案卡（交互式 HTML）', 'ok'),
        ('baoyu-visit-card', '拜访卡：访前准备/访中记录/访后跟进', 'ok'),
        ('baoyu-life-science-visit-card', '生命科学课题组访前作战卡（PI/方向/组织架构）', 'ok'),
        ('baoyu-visit-minutes', '拜访纪要：手写笔记拍照→识别→可编辑 HTML', 'ok'),
        ('baoyu-activity-trend-analysis', '一段时间内客户沟通与需求趋势汇总', 'ok'),
        ('sku-customer-evidence-ledger', '一批货号在某批客户处的测试/采购/客诉台账', 'ok'),
        ('baoyu-test-feedback-analysis', '测试反馈提取洞察并对账', 'ok'),
    ]),
    ('B · 产品与技术', [
        ('baoyu-tech-evidence-qa', '技术问题取证作答（本地语料优先、给依据）', 'ok'),
        ('baoyu-technical-literature-deepdive', '技术文献深挖与缺口分析', 'ok'),
        ('baoyu-product-fact-lookup', '查货号全名、客户实测案例、体系选型取证', 'ok'),
        ('baoyu-product-selection-answer', '客户发来检测需求→选型推荐货号', 'ok'),
        ('baoyu-product-benchmarking', '宝锐 vs 竞品 参数横向对比（效期/稳定性/酶活等）', 'ok'),
        ('baoyu-product-price-analysis', '官方报价、成交价、每单位价、是否踩线', 'ok'),
        ('baoyu-product-recommendation', '诊断原料产品推荐清单（按月更新）', 'ok'),
        ('pcr-additives-advisory', '辅助蛋白/添加剂的作用与是否要加', 'ok'),
        ('qpcr-signal-troubleshooting', '客户报 qPCR 曲线/信号异常时的分诊与排查', 'ok'),
        ('baoyu-lyophilization-advisory', '冻干保护剂搭配、冻干形态、外包承接', 'ok'),
        ('molecular-resistance-site-panels', '耐药/突变检测位点与能否荧光 PCR 多重', 'ok'),
        ('baoyu-mrna-circrna-product', 'mRNA/circRNA 科研产品线宣讲与推荐', 'ok'),
        ('baoyu-product-intro-card', '产品/服务简介卡片（暗色 HTML）', 'ok'),
        ('baoyu-erp-product-catalog', '从订单数据提取/总结全量产品清单', 'careful'),
        ('baoyu-product-selling-points', '产品竞争力库/卖点库（偏维护写入）', 'careful'),
    ]),
    ('C · 市场与竞品', [
        ('baoyu-competitor-analysis', '某产品线的竞品梳理与竞争格局', 'ok'),
        ('baoyu-market-analysis-report', '行业纵深市场分析报告', 'ok'),
        ('baoyu-market-research-card', '客户所在终端赛道的竞争格局卡片', 'ok'),
        ('visit-industry-intel-brief', '拜访前的行业热点/技术前沿/话题清单', 'ok'),
        ('competitor-news-monitor', '盯指定竞品的重大动态，出带出处的摘要', 'ok'),
        ('baoyu-literature-access', '拿不到全文时找合法开放版', 'ok'),
        ('literature-research-pipeline', '系统文献调研（检索→全文→证据表→综述）', 'ok'),
        ('arxiv', 'arXiv 论文检索', 'ok'),
        ('tianyancha-cn', '企业工商信息/背景查询', 'ok'),
    ]),
    ('D · 材料与交付（做东西）', [
        ('baoyu-brand-standard', '品牌规范：Logo+slogan 注入与自检（产出必须合规）', 'ok'),
        ('baoyu-selfcontained-html-delivery', '零依赖自包含 HTML 单页交付', 'ok'),
        ('self-contained-html-dashboard', '表格→可筛选排序的 HTML 看板', 'ok'),
        ('editable-html-deliverables', '可编辑 HTML 交付物', 'ok'),
        ('baoyu-presentation', 'PPT 汇报材料（含演讲者备注）', 'ok'),
        ('baoyu-training-material', '培训教材/使用说明 + 可交互沙盒', 'ok'),
        ('pptx-full-transcription', 'PPTX 完整转写为 Markdown', 'ok'),
        ('baoyu-doc-transcription-fidelity', 'DOCX/PPTX/PDF 保真转写', 'ok'),
        ('excel-to-html-dashboard', 'Excel→HTML 仪表盘', 'ok'),
        ('html-dashboard-from-excel', 'Excel→交互式 HTML 看板', 'ok'),
        ('xlsx', 'Excel/CSV 读写编辑', 'ok'),
        ('html-ppt', 'HTML 载体幻灯片（16:9）', 'ok'),
        ('document-to-mindmap', '文档→思维导图', 'ok'),
        ('xmind-mindmap', 'XMind 思维导图读写', 'ok'),
        ('handwriting-ocr', '手写体识别（拍照笔记/便签）', 'ok'),
        ('chinese-image-ocr', '图片文章/公众号截图的文字提取', 'ok'),
        ('whisper-audio-transcription', '录音转文字（拜访录音/会议）', 'ok'),
        ('baoyu-outbound-material', '对外物料规范（宣讲单页/彩页/海报）', 'careful'),
        ('baoyu-promotional-flyer', 'A4 促销彩页（含价格与二维码）', 'careful'),
        ('baoyu-promo-poster-template', '科研促销海报（朋友圈竖版）', 'careful'),
        ('baoyu-image-material-pipeline', '图片物料渲染与验收（方图/长图）', 'careful'),
        ('smart-illustrator', '配图与 PPT 信息图生成', 'ok'),
        ('baoyu-article-illustrator', '文章配图（类型×风格×配色一致性）', 'ok'),
    ]),
    ('E · 其他可能用得上的', [
        ('sf-express-tracking', '顺丰快递物流轨迹与签收状态', 'ok'),
        ('baoyu-expense-assistant', '报销助手：票据解析、发票台账', 'careful'),
        ('baoyu-order-entry', '销售下单页（三合一+账期授权+审批）', 'no'),
        ('baoyu-gift-order-system', '礼品订单系统', 'no'),
        ('baoyu-social-like-campaign', '朋友圈集赞裂变活动策划', 'no'),
        ('baoyu-social-media-launch', '社媒起号方案（小红书/视频号）', 'no'),
    ]),
]

# 明确不建议（管理/绩效/财务/基础设施）—— 列出便于你核对，默认不勾
NO_LIST = [
    ('工作台建设与运维', 'baoyu-workbench-feature-increment 57、baoyu-workbench-mcp-pipeline 49、'
     'baoyu-workbench-page-acceptance 22、baoyu-workbench-data-pipeline 17、baoyu-workbench-frontend-pitfalls 16、'
     'baoyu-workbench-data-lineage 13、baoyu-workbench-health-check 13、baoyu-workbench-ops 7、'
     'baoyu-workbench-patterns、baoyu-workbench-theming、baoyu-cloudbase-deployment 等'),
    ('Hermes/系统运维', 'hermes-pitfalls-learned 17、hermes-gateway-lifecycle-ops 16、hermes-multi-zone 10、'
     'hermes-model-provider-ops 8、hermes-gateway-binding 7、hermes-profile-config-ops 6、hermes-self-update、'
     'hermes-skill-market、skill-library-governance 7、agent-skill-authoring 5 等'),
    ('绩效/人事/财务口径', 'baoyu-kpi-scorecard、baoyu-kpi-progress-lookup、baoyu-perf-review-email、'
     'baoyu-performance-score-email、baoyu-resignation-handover-analysis、baoyu-work-report-analysis、'
     'baoyu-monthly-report、baoyu-overdue-analysis、baoyu-sales-deep-analysis、sales-analysis-caliber、'
     'sales-data-reconciliation、sales-data-isolation（隔离机制本身）等'),
    ('全公司/跨部门口径', 'baoyu-sales-attribution-rollup 30、baoyu-customer-group-rollup 17、'
     'baoyu-quarterly-report-pack 10、baoyu-erp-crossref-backfill、baoyu-data-refresh-integrity 等'),
    ('本机/网络/部署', 'local-tool-hosting、tailscale-http-server、macos-* 系列、desktop-read-wedge-triage、'
     'cn-holiday-push-guard、print-material-build-pipeline、deployed-artifact-verification 等'),
]


def main():
    usage = json.load(open(USAGE, encoding='utf-8'))
    installed = set()
    for root, _dirs, files in os.walk(HER):
        if 'SKILL.md' in files:
            installed.add(os.path.basename(root))

    def meta(name):
        m = usage.get(name) or {}
        return int(m.get('use_count') or 0), (m.get('last_used_at') or '')[:10]

    rows, n = [], 0
    for cat, items in CATS:
        cards = []
        for name, desc, rec in items:
            n += 1
            c, last = meta(name)
            badge = {'ok': '<span class="b ok">建议开</span>',
                     'careful': '<span class="b ca">谨慎</span>',
                     'no': '<span class="b no">不建议</span>'}[rec]
            cards.append(
                '<label class="it" data-rec="%s"><input type="checkbox" data-name="%s" data-no="%d">'
                '<div class="body"><div class="t"><span class="num">%d</span> <b>%s</b> %s%s</div>'
                '<div class="d">%s</div>'
                '<div class="m">我用过 <b>%d</b> 次 · 最近 %s</div></div></label>'
                % (rec, name, n, n, name, badge, ' <span class="al">已装</span>' if name in installed else '',
                   desc, c, last or '—'))
        rows.append('<h2>%s</h2><div class="grid">%s</div>' % (cat, ''.join(cards)))

    nohtml = ''.join('<tr><td class="lb">%s</td><td>%s</td></tr>' % (a, b) for a, b in NO_LIST)
    html = """<!DOCTYPE html><html lang="zh-CN"><head><meta charset="utf-8">
<title>技能开放勾选清单</title><style>
:root{--blue:#0b5fa5;--blue2:#1e88e5;--ink:#16202b;--muted:#5f6b78;--line:#e4ebf2;--bg:#f6f9fc}
*{box-sizing:border-box}body{margin:0;font:14.5px/1.7 -apple-system,"PingFang SC",sans-serif;color:var(--ink);background:var(--bg)}
main{max-width:1080px;margin:0 auto;padding:24px 20px 90px}
h1{font-size:24px;margin:0 0 6px}h2{font-size:17px;margin:26px 0 10px;padding-left:10px;border-left:4px solid var(--blue)}
.lead{color:var(--muted);margin-bottom:14px}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(330px,1fr));gap:9px}
.it{display:flex;gap:10px;background:#fff;border:1px solid var(--line);border-radius:10px;padding:10px 12px;cursor:pointer}
.it:hover{border-color:#bcd7ee}.it input{margin-top:4px;flex:0 0 auto;width:16px;height:16px}
.body{flex:1;min-width:0}.t{font-size:14px;word-break:break-all}
.num{display:inline-block;min-width:22px;color:#9db2c6;font-variant-numeric:tabular-nums}
.d{color:var(--muted);font-size:12.5px;margin-top:2px}
.m{color:#9aa7b4;font-size:11.5px;margin-top:3px}
.b{font-size:11px;border-radius:5px;padding:1px 6px;margin-left:4px}
.b.ok{background:#e6f4ea;color:#1a7f45}.b.ca{background:#fff5e0;color:#9a6b00}.b.no{background:#fdeaea;color:#a33}
.al{font-size:11px;background:#e8f0fb;color:#1a5fb4;border-radius:5px;padding:1px 6px}
table{border-collapse:collapse;width:100%;background:#fff;border:1px solid var(--line);border-radius:10px;overflow:hidden}
td{padding:9px 12px;border-top:1px solid var(--line);font-size:13px;vertical-align:top}
td.lb{white-space:nowrap;color:var(--blue);font-weight:600;width:150px}
.bar{position:fixed;left:0;right:0;bottom:0;background:#0d2a52;color:#fff;padding:11px 18px;display:flex;gap:12px;align-items:center;flex-wrap:wrap}
.bar button{background:#1e88e5;color:#fff;border:0;border-radius:8px;padding:8px 14px;font-size:13.5px;cursor:pointer}
.bar button.g{background:#3d5a7a}.bar .cnt{font-weight:700}
</style></head><body><main>
<h1>技能开放勾选清单</h1>
<div class="lead">下面是<b>我实际在用</b>的技能（次数来自真实调用账本），按用途分了组，每条都标了「建议开 / 谨慎 / 不建议」。
<b>勾你要给她用的</b>，点底部「复制勾选结果」把文本发我，我据此出一份对应的《使用手册》。已标注「已装」的是当前已经在她那里的。</div>
""" + ''.join(rows) + """
<h2>附录 · 我明确不建议开给她的（默认不勾，供你核对）</h2>
<table>""" + nohtml + """</table>
</main>
<div class="bar">
  <button onclick="selRec('ok')">全选「建议开」</button>
  <button onclick="selRec('none')">清空</button>
  <button class="g" onclick="copySel()">复制勾选结果</button>
  <button class="g" onclick="dl()">下载结果.txt</button>
  <span class="cnt"><span id="n">0</span> 项已选</span>
  <span id="hint" style="opacity:.75"></span>
  <textarea id="out" readonly style="display:none;flex:1 1 100%;height:60px;border-radius:6px;border:0;padding:6px 8px;font:12px/1.5 monospace"></textarea>
</div>
<script>
function boxes(){return [...document.querySelectorAll('input[data-name]')]}
function refresh(){document.getElementById('n').textContent=boxes().filter(b=>b.checked).length}
function persist(){
  boxes().forEach(b=>{ if(b.checked) b.setAttribute('checked',''); else b.removeAttribute('checked'); });
  const sel=boxes().filter(b=>b.checked).map(b=>b.dataset.name);
  document.title = (sel.length? '已勾选'+sel.length+'项 | ' : '未勾选 | ') + sel.join(',');
  try{ localStorage.setItem('skill_pick', JSON.stringify(sel)); }catch(e){}
  const out=document.getElementById('out'); if(out) out.value = sel.join(String.fromCharCode(10));
}
function restore(){
  let saved=[]; try{ saved=JSON.parse(localStorage.getItem('skill_pick')||'[]'); }catch(e){}
  if(saved.length){ boxes().forEach(b=>{ if(saved.indexOf(b.dataset.name)>=0) b.checked=true; }); }
}
boxes().forEach(b=>b.addEventListener('change',function(){refresh();persist();}));
restore(); refresh();
function selRec(mode){boxes().forEach(b=>{b.checked = mode==='ok' ? b.closest('.it').dataset.rec==='ok' : false});refresh();persist()}
function dl(){
  persist();
  const sel=boxes().filter(b=>b.checked).map(b=>b.dataset.name).join(String.fromCharCode(10));
  const n=boxes().filter(b=>b.checked).length, NL=String.fromCharCode(10);
  const head='已勾选技能 '+n+' 项'+String.fromCharCode(10,10);
  const blob=new Blob([head+sel], {type:'text/plain'});
  const a=document.createElement('a'); a.href=URL.createObjectURL(blob); a.download='技能勾选结果.txt'; a.click();
}
function copySel(){
  persist();
  const sel=boxes().filter(b=>b.checked);
  const txt = sel.length? sel.map(b=>b.dataset.name).join(String.fromCharCode(10)) : '（未勾选）';
  const out=document.getElementById('out');
  out.value=txt; out.style.display='block'; out.focus(); out.select();
  let copied=false;
  try{ copied=document.execCommand('copy'); }catch(e){}
  if(!copied && navigator.clipboard){ navigator.clipboard.writeText(txt).then(()=>{},()=>{}); copied=true; }
  document.getElementById('hint').textContent = copied
    ? ('已复制 '+sel.length+' 项，直接粘给我即可')
    : ('已生成 '+sel.length+' 项，请手动复制下方文本');
  if(!copied){ try{ out.setSelectionRange(0, txt.length); }catch(e){} }
}
refresh();
</script></body></html>"""
    html = BK.inject(html, theme='light', tag='内部管理 · 技能开放决策',
                     footer_extra='勾选清单 · ' + datetime.now().strftime('%Y-%m-%d'))
    v = BK.verify(html)
    assert all(v.values()), v
    # 抹掉品牌注释里的内部路径
    import re
    html = re.sub(r'/\*\s*=+\s*bior-brand-v1.*?\*/', '/* bior-brand-v1 · 宝锐品牌样式 */', html, flags=re.S)
    os.makedirs(os.path.dirname(OUT), exist_ok=True)
    open(OUT, 'w', encoding='utf-8').write(html)
    print('品牌自检:', v)
    print('可选技能 %d 项 ｜ 已装 %d 项' % (n, len(installed)))
    print('→ %s（%.1f KB）' % (OUT, os.path.getsize(OUT) / 1024.0))


if __name__ == '__main__':
    main()
