#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""修 P1 拜访视图在 CDN 上「加载失败：Unexpected token '<'」。

根因：CDN 静态托管没有 /api 代理，相对路径 /api/* 会命中托管的 404 HTML。
修法：按工作台既有约定，走 AUTH_APIS 绝对基址 + 逐个回退 + 校验 Content-Type 是 JSON。
两处调用（拜访统计、活动详情）改为 wbReq()。
"""
import io
import os
import shutil
import sys
import time

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

WBREQ = r'''/* 工作台接口基址解析：CDN 页面上的相对 /api/* 会命中静态托管的 404 HTML，
   所以一律走 AUTH_APIS 的绝对基址，并逐个回退、校验响应确实是 JSON。 */
function wbBases() {
  var out = (typeof AUTH_APIS !== 'undefined' && AUTH_APIS.length) ? AUTH_APIS.slice() : [];
  if (out.indexOf('http://127.0.0.1:8765') < 0) out.push('http://127.0.0.1:8765');
  return out;
}
function wbReq(path, opts) {
  var bases = wbBases(), i = 0;
  function next() {
    if (i >= bases.length) throw new Error('所有接口地址均不可用（检查网络或登录态）');
    var base = bases[i++];
    return apiFetch(base + path, opts).then(function (r) {
      var ct = (r.headers.get('Content-Type') || '');
      if (ct.indexOf('application/json') < 0) throw new Error('not_json');
      return r.json();
    }).catch(function (e) {
      if (String((e && e.message) || e) === 'auth_expired') throw e;   // 别把登录失效吞掉
      return next();
    });
  }
  return next();
}

/* ---------- 拜访视图（P1）：当月线下拜访次数 / 线上跟进次数 ---------- */'''

A_OLD = '/* ---------- 拜访视图（P1）：当月线下拜访次数 / 线上跟进次数 ---------- */'

B_OLD = """  apiFetch('/api/visit/stats?month=' + encodeURIComponent(visitMonth), { cache: 'no-store' })
    .then(function (r) { return r.json(); })
    .then(function (j) { renderVisitBody(j); })"""
B_NEW = """  wbReq('/api/visit/stats?month=' + encodeURIComponent(visitMonth), { cache: 'no-store' })
    .then(function (j) { renderVisitBody(j); })"""

C_OLD = """  apiFetch('/api/activity/detail?id=' + encodeURIComponent(id), { cache: 'no-store' })
    .then(function (r) { return r.json(); })
    .then(function (j) {"""
C_NEW = """  wbReq('/api/activity/detail?id=' + encodeURIComponent(id), { cache: 'no-store' })
    .then(function (j) {"""

PAIRS = [('A 加 wbReq', A_OLD, WBREQ), ('B 拜访统计改 wbReq', B_OLD, B_NEW), ('C 活动详情改 wbReq', C_OLD, C_NEW)]


def main():
    apply = '--apply' in sys.argv
    ts = time.strftime('%Y%m%d-%H%M%S')
    bak = os.path.join(ROOT, '_bak_p1_baseurl_%s' % ts)
    ok_all = True
    print('拜访视图基址修复 —— %s\n' % ('APPLY' if apply else 'DRY-RUN'))
    for f in FILES:
        s = io.open(f, encoding='utf-8').read()
        print('=== %s ===' % os.path.basename(f))
        ok = True
        for label, old, new in PAIRS:
            n = s.count(old)
            if n != 1:
                ok = False
            print('  %s %-20s 命中 %d' % ('✅' if n == 1 else '❌', label, n))
            if n == 1:
                s = s.replace(old, new, 1)
        if not ok:
            ok_all = False
            print('  → 不落盘')
            continue
        if apply:
            os.makedirs(bak, exist_ok=True)
            shutil.copy2(f, os.path.join(bak, os.path.basename(f)))
            io.open(f, 'w', encoding='utf-8').write(s)
            rel = s.count("apiFetch('/api/")
            print('  已写（备份 %s）｜残留相对 apiFetch(\'/api/ 调用 %d 处' % (bak, rel))
    print('\n%s' % ('全部命中 ✅' if ok_all else '有未命中 ❌'))
    return 0 if ok_all else 1


sys.exit(main())
