#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""改工作台「课题组」Tab：挂上采购实据（金额/订单/货号/最近成交）+ 第二排 KPI。
两入口同改（工具/index.html、工具/app.html），改完 node --check 校验内联 JS。
"""
import io
import os
import re
import subprocess
import sys
import tempfile

ROOT = '/Users/liuxinyuan/Desktop/Hermes输出-工作类'
FILES = [os.path.join(ROOT, '工具/index.html'), os.path.join(ROOT, '工具/app.html')]

NEW = r"""function renderGroups(main) {
  var gd = (state.data || {}).lsGroups;
  if (!gd) { main.innerHTML = '<div class="error-box"><h3>⚠️ 课题组数据未加载</h3><p>数据源：MCP 商机视图 _rz-opbvg + ERP 生命科学销售订单</p></div>'; return; }

  var allGroups = gd.groups || [];
  var totalAll = gd.total || 0;
  var user = state.user || {};
  var isAdmin = user.role === 'admin' || user.role === 'gm';

  var groups = isAdmin ? allGroups : allGroups.filter(function(g) { return g.sales === user.name; });

  var statusCount = {}, amtSum = 0, paidCnt = 0, skuSet = {}, custSet = {}, inTalk = 0;
  groups.forEach(function(g) {
    if (g.status) { statusCount[g.status] = (statusCount[g.status] || 0) + 1; inTalk++; }
    var a = parseFloat(g.amt) || 0;
    amtSum += a;
    if (a > 0) paidCnt++;
    (g.top_skus || []).forEach(function(s) { if (s && s.sku) skuSet[s.sku] = 1; });
    (g.customers || []).forEach(function(c) { if (c) custSet[c] = 1; });
  });
  var skuCnt = Object.keys(skuSet).length, custCnt = Object.keys(custSet).length;
  if (isAdmin) {                       // 管理员看全量：用权威去重总数（避免各组 top5 重复计数）
    if (gd.skus_total) skuCnt = gd.skus_total;
    if (gd.customers_total) custCnt = gd.customers_total;
  }
  function wan(v) { return (v / 10000).toFixed(2); }
  function yuan(v) { return '¥' + (Math.round(v) || 0).toLocaleString('en-US'); }

  var html = '';
  html += '<div class="stats-grid">';
  html += '<div class="stat-card"><div class="value">' + groups.length + '</div><div class="label">🔬 课题组</div></div>';
  html += '<div class="stat-card"><div class="value">' + (statusCount['沟通需求确认'] || 0) + '</div><div class="label">🔄 需求沟通</div></div>';
  html += '<div class="stat-card"><div class="value">' + (statusCount['产品试用中'] || 0) + '</div><div class="label">🧪 产品试用</div></div>';
  html += '<div class="stat-card"><div class="value">' + ((statusCount['实现销售'] || 0) + (statusCount['复购'] || 0)) + '</div><div class="label">✅ 已成交</div></div>';
  html += '</div>';
  html += '<div class="stats-grid">';
  html += '<div class="stat-card"><div class="value">' + paidCnt + '</div><div class="label">💰 有采购记录</div></div>';
  html += '<div class="stat-card"><div class="value">' + wan(amtSum) + '<span style="font-size:13px">万</span></div><div class="label">💵 累计成交额</div></div>';
  html += '<div class="stat-card"><div class="value">' + skuCnt + '</div><div class="label">🧾 成交货号</div></div>';
  html += '<div class="stat-card"><div class="value">' + custCnt + '</div><div class="label">🏢 覆盖客户</div></div>';
  html += '</div>';
  html += '<div style="font-size:11px;color:var(--sub);margin-bottom:14px;line-height:1.7">'
       + '📡 课题组状态：MCP 商机视图（在谈 <b>' + inTalk + '</b> 个 / 全量 ' + totalAll + '）'
       + '　｜　采购实据：ERP 生命科学销售订单 · ' + esc(gd.order_period || '') + ' · ' + esc(gd.amt_caliber || '')
       + '　｜　按累计成交额降序' + (isAdmin ? '' : '（仅本人）') + '</div>';

  if (!groups.length) {
    html += '<div class="empty">暂无课题组</div>';
  } else {
    html += '<div class="card"><div class="card-header"><h3>🔬 课题组列表 (' + groups.length + '个)</h3></div>';
    html += '<div class="card-body" style="overflow-x:auto"><table class="data-table"><thead><tr>';
    html += '<th>课题组</th><th>状态</th><th>当前节点</th><th>销售员</th><th>区域</th>'
         + '<th style="text-align:right">累计成交额</th><th style="text-align:center">订单/货号</th><th>最近成交</th><th>客户</th><th></th></tr></thead><tbody>';
    groups.forEach(function(g) {
      var sc = (g.status === '实现销售' || g.status === '复购') ? 'tag-green' : (g.status === '产品试用中' ? 'tag-blue' : (g.status === '订单签订中' ? 'tag-purple' : 'tag-orange'));
      var a = parseFloat(g.amt) || 0;
      var custs = g.customers || [];
      html += '<tr><td>' + esc(g.name || '') + (g.owner_merged_from && g.owner_merged_from.length ? ' <span class="tag tag-orange" title="离职归并自 ' + esc(g.owner_merged_from.join('/')) + '">归并</span>' : '') + '</td>' +
        '<td>' + (g.status ? '<span class="tag ' + sc + '">' + esc(g.status) + '</span>' : '<span style="color:var(--sub)">—</span>') + '</td>' +
        '<td>' + esc(g.node || '—') + '</td><td>' + esc(g.sales || '') + '</td>' +
        '<td>' + esc(g.region || '—') + '</td>' +
        '<td style="text-align:right;font-weight:700;color:' + (a > 0 ? 'var(--pri)' : 'var(--sub)') + '">' + (a > 0 ? yuan(a) : '—') + '</td>' +
        '<td style="text-align:center">' + (g.orders ? g.orders + ' / ' + g.skus : '—') + '</td>' +
        '<td style="white-space:nowrap">' + esc(g.last_deal || g.last_any || '—') + '</td>' +
        '<td style="font-size:11px">' + esc(custs.slice(0, 2).join('、')) + (custs.length > 2 ? ' 等' + custs.length + '家' : '') + '</td>' +
        '<td>' + (g.id ? '<a href="' + FEISHU_URL + esc(g.id) + '" target="_blank">查看 →</a>' : '') + '</td></tr>';
    });
    html += '</tbody></table></div></div>';
  }
  main.innerHTML = html;
}
"""

old_txt = None
for path in FILES:
    s = io.open(path, encoding='utf-8').read()
    i = s.find('function renderGroups(main) {')
    assert i > 0, '未找到 renderGroups: %s' % path
    j = s.find('main.innerHTML = html;\n}', i)
    assert j > 0, '未找到函数尾: %s' % path
    j += len('main.innerHTML = html;\n}') + 1
    old = s[i:j]
    if old_txt is None:
        old_txt = old
    else:
        assert old == old_txt, '两入口 renderGroups 不一致（改前先对齐）: %s' % path
    s2 = s[:i] + NEW + s[j:]
    io.open(path, 'w', encoding='utf-8').write(s2)
    print('✅ 已改 %-22s 替换 %d → %d 字符' % (os.path.basename(path), len(old), len(NEW)))

# ── 语法校验（抽内联 script 逐个 node --check）──
print('\n── node --check ──')
bad = 0
for path in FILES:
    s = io.open(path, encoding='utf-8').read()
    blocks = re.findall(r'<script[^>]*>(.*?)</script>', s, re.S)
    fails = []
    for b in blocks:
        if not b.strip():
            continue
        fd, p = tempfile.mkstemp(suffix='.js')
        os.write(fd, b.encode('utf-8'))
        os.close(fd)
        r = subprocess.run(['node', '--check', p], capture_output=True, text=True)
        if r.returncode:
            fails.append(r.stderr.strip().splitlines()[-1][:120])
        os.unlink(p)
    print(('✅' if not fails else '❌'), '%-22s %d 块' % (os.path.basename(path), len(blocks)),
          ('全通过' if not fails else fails[:1]))
    bad += len(fails)

# ── 内容自检 ──
for path in FILES:
    s = io.open(path, encoding='utf-8').read()
    need = ['有采购记录', '累计成交额', '成交货号', '覆盖客户', 'order_period', 'owner_merged_from', '归并']
    miss = [k for k in need if k not in s]
    print(('✅' if not miss else '❌'), '%-22s 关键词%s' % (os.path.basename(path), '齐' if not miss else '缺 ' + str(miss)))
sys.exit(1 if bad else 0)
