#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""历史成交价页（下单.html）诊断与加固：
1) 聚焦即展示候选（空输入也列前 40 个可见客户）
2) 登录态缺失 / 401 / 接口不可达 → 明确提示 + 禁用输入 + 重试，不再静默空列表
3) 客户列表加载成功后提示“已加载 N 个可见客户”
4) 接口请求 8s 超时，避免桥接不可达时无限等待
"""
import io
import re

P = '/Users/liuxinyuan/Desktop/Hermes输出-工作类/工具/下单.html'
s = io.open(P, encoding='utf-8').read()

# ① 聚焦即开列表
old_focus = "  inp.addEventListener('focus', function(){ if (inp.value) open(); });"
new_focus = "  inp.addEventListener('focus', function(){ open(); });  /* 2026-10-20：空输入也列候选，避免“点了没反应” */"
assert old_focus in s, 'focus 行未命中'
s = s.replace(old_focus, new_focus, 1)

# ② 请求超时
old_fetch = """function apiFetch(base, path, opts){
  opts = opts || {}; opts.headers = opts.headers || {};
  if (TOKEN) opts.headers['Authorization'] = 'Bearer ' + TOKEN;
  return fetch(base + path, opts);
}"""
new_fetch = """function apiFetch(base, path, opts){
  opts = opts || {}; opts.headers = opts.headers || {};
  if (TOKEN) opts.headers['Authorization'] = 'Bearer ' + TOKEN;
  /* 2026-10-20：8s 超时。接口桥接不可达时旧版会一直等，页面停在“空列表”且无提示 */
  if (typeof AbortController !== 'undefined' && !opts.signal) {
    var ctrl = new AbortController();
    var timer = setTimeout(function(){ try { ctrl.abort(); } catch(e){} }, 8000);
    opts.signal = ctrl.signal;
    return fetch(base + path, opts).then(function(r){ clearTimeout(timer); return r; },
                                         function(e){ clearTimeout(timer); throw e; });
  }
  return fetch(base + path, opts);
}"""
assert old_fetch in s, 'apiFetch 未命中'
s = s.replace(old_fetch, new_fetch, 1)

# ③ 重写 init：错误可见化 + loadOptions 可重试
m = re.search(r"function init\(\)\{.*?\n\}\n\nfunction bindEvents\(\)\{", s, re.S)
assert m, 'init 块未命中'
new_init = """var _BOUND = false;
function priceFatal(msg){
  var box = $('msgBox'); if (box) { box.innerHTML = msg; box.className = 'msg err'; }
  var h = $('pqCustHint');
  if (h) h.innerHTML = '<span style="color:#B42318;font-weight:700">' + esc(msg) + '</span>'
        + ' <a href="javascript:location.reload()" style="color:#1852B6;text-decoration:underline">重新加载</a>';
  var i = $('pqCust'); if (i) { i.disabled = true; i.placeholder = '客户列表未加载'; }
  var b = $('pqBox'); if (b) b.innerHTML = '<div class="leftbar">' + esc(msg) + '</div>';
}
function loadOptions(){
  return probeApi().then(function(){
    return apiGet('/api/order/options', {});
  }).then(function(d){
    if (!d || !d.ok) {
      var why = (d && d._status === 401)
        ? '登录已过期：请退出工作台重新登录后再进入本页'
        : ('接口不可用：' + ((d && d.error) || '未知错误'));
      priceFatal(why);
      return;
    }
    OPT.customers = d.customers || [];
    OPT.carriers = d.carriers || OPT.carriers;
    OPT.modes = d.modes || OPT.modes;
    OPT.isApprover = !!d.is_approver;
    OPT.myAuthz = d.my_authz || {};
    OPT.termsOptions = d.terms_options || OPT.termsOptions;
    OPT.defaults = d.defaults || {};
    var az = $('myAz'); if (az) az.textContent = (OPT.myAuthz.terms_label || OPT.defaults.terms_label || '7个工作日')
      + (OPT.myAuthz.configured ? '' : '（默认）');
    if ($('termsSel')) $('termsSel').innerHTML = OPT.termsOptions.map(function(t){ return '<option value="'+t+'">'+t+'</option>'; }).join('');
    if ($('carrierSel')) $('carrierSel').innerHTML = OPT.carriers.map(function(t){ return '<option value="'+t+'">'+t+'</option>'; }).join('');
    if ($('modeSel')) $('modeSel').innerHTML = OPT.modes.map(function(t){ return '<option value="'+t+'">'+t+'</option>'; }).join('');
    if ($('termsSel')) $('termsSel').value = '预付款';
    var ci = $('pqCust'); if (ci) { ci.disabled = false; ci.placeholder = '输入客户名检索…（点一下可看全部）'; }
    var h = $('pqCustHint');
    if (h) h.innerHTML = '已加载 <b>' + (OPT.customers || []).length + '</b> 个可见客户；输入客户名或点输入框选人';
    if (!_BOUND) { bindEvents(); _BOUND = true; }
    renderNav(0);
    if (OPT.isApprover) refreshPending();
    msg('请先选择客户', '');
  }).catch(function(e){
    priceFatal('加载失败：' + ((e && e.message) || e) + '（网络或接口桥接异常）');
  });
}
function init(){
  if (!TOKEN || !USER || !USER.name) {
    priceFatal('未检测到登录态：请从销售工作台重新进入本页（或先登录工作台）');
    return;
  }
  var ttl = document.querySelector('.topbar .ttl');
  if (ttl) ttl.textContent = FEATURES.order ? '销售下单' : '历史成交价查询';
  $('whoBox').innerHTML = '<b>'+esc(USER.name)+'</b> · '+esc(USER.dept||USER.line||'')
    + (FEATURES.order ? ('<br>我的账期授权 <span class="az" id="myAz">—</span>') : '');
  loadOptions();
}

function bindEvents(){"""
s = s[:m.start()] + new_init + s[m.end():]

io.open(P, 'w', encoding='utf-8').write(s)
print('✅ patched', len(s), 'chars')
