#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""升级「已生成的 HTML」里的旧版可编辑图层 → 链接可点版（2026-09-23）

背景：旧版 `html_editable_layer.py` 的 boot() 写死 setEditable(true)（默认编辑态），
      且 setEditable() 只给 .editbar/button/input/textarea/select/.bx 设 contenteditable=false，
      **漏了 <a>** → contenteditable 区域里点链接只落光标、不跳转（日报的客诉/飞书原文就是这样失效的）。

本脚本对**已经生成好、不方便重新生成**的文件做原地手术（幂等）：
  1) 注入 `var EDIT_DEFAULT=false;`（阅读优先）
  2) boot() 改为 `restore();protectLinks();setEditable(EDIT_DEFAULT);`
  3) 注入 protectLinks()（给所有 <a href> 标 contenteditable=false）+ 编辑模式下点击兜底 window.open
  4) 在 `<div class="warnbox">` 前插入阅读模式提示（可选）

只处理「含 setEditable、缺 protectLinks、且至少 1 个 http 外链」的文件 ——
纯表单页（0 外链，如信息收集表/分派表）不动，保持开箱即可填。

用法：python3 脚本/upgrade_generated_edit_layer.py [文件或目录 ...] [--deploy]
      不带参数默认扫 数据/daily_briefs/*.html 与 工具/*.html
"""
import os, re, sys, io, glob, subprocess

ROOT = os.path.expanduser('~/Desktop/Hermes输出-工作类')
ENV = 'bier-sales-d0gatbvlx288724e9'
CDN = 'https://bier-sales-d0gatbvlx288724e9-1458438710.tcloudbaseapp.com'
DEPLOY = '--deploy' in sys.argv
args = [a for a in sys.argv[1:] if not a.startswith('--')]
if not args:
    args = [os.path.join(ROOT, '数据/daily_briefs/*.html'), os.path.join(ROOT, '工具/*.html')]

LINK_JS = r"""/* 🔗 链接保护：contenteditable 区域里点 <a> 只会落光标、不会跳转 */
function protectLinks(){
 var as=document.querySelectorAll('a[href]');
 for(var i=0;i<as.length;i++){as[i].setAttribute('contenteditable','false');}
}
document.addEventListener('click',function(ev){
 if(!window.EDIT)return;
 var el=ev.target;
 while(el&&el.tagName!=='A'){el=el.parentNode;}
 if(!el||el.tagName!=='A')return;
 var href=el.getAttribute('href')||'';
 if(!/^(https?:|mailto:)/i.test(href))return;
 ev.preventDefault();ev.stopPropagation();
 window.open(href,'_blank','noopener');
},true);
"""

HINT = ('<div class="edithint">📖 <b>本页默认为阅读模式</b>：链接可直接点击跳转，不受编辑层影响。'
        '需要批注 / 改动时点右下角「<b>✏️ 编辑</b>」解锁；改完点「<b>⬇ 导出 HTML</b>」生成带数据的独立文件，'
        '「🖨 打印 / PDF」出纸质版。</div>')


def upgrade(path):
    h = io.open(path, encoding='utf-8').read()
    if 'setEditable' not in h:
        return 'skip: 无编辑层'
    if 'protectLinks' in h:
        return 'skip: 已是新版'
    if not re.search(r'href="https?://', h):
        return 'skip: 无外链（表单页保持可编辑）'
    orig = h

    # 1) EDIT_DEFAULT 常量
    if 'var EDIT_DEFAULT' not in h:
        h = re.sub(r"(var CONT_SEL='[^']*';\n)", r"\1var EDIT_DEFAULT=false;\n", h, count=1)
    # 2) boot
    h = h.replace('function boot(){restore();setEditable(true);}',
                  'function boot(){restore();protectLinks();setEditable(EDIT_DEFAULT);}')
    # 3) 链接保护 JS（插在 setEditable 定义前）
    if 'function protectLinks' not in h and 'function setEditable' in h:
        h = h.replace('function setEditable(', LINK_JS + 'function setEditable(', 1)
    # 4) 阅读模式提示
    if '本页默认为阅读模式' not in h and '<div class="warnbox">' in h:
        h = h.replace('<div class="warnbox">', HINT + '<div class="warnbox">', 1)

    if h == orig:
        return 'skip: 无可替换点'
    io.open(path, 'w', encoding='utf-8').write(h)
    n = len(re.findall(r'href="https?://', h))
    return '✅ 已升级（%d 个外链现在可点）' % n


def deploy_one(path):
    """按文件位置推到 CDN 对应目录

    ⚠️ 日报的 CDN 路径是 **ASCII 日期名**（`/daily/2026-09-17.html`），不是本地中文文件名
    （`宝锐销售日报_2026-09-17.html`）——按 basename 推会写到一个无人访问的平行路径，
    deploy 照样报 successful，线上却永远是旧版（2026-09-23 实际踩过）。
    """
    rel = os.path.relpath(path, ROOT)
    bn = os.path.basename(path)
    if rel.startswith('数据/daily_briefs/'):
        m = re.search(r'(\d{4}-\d{2}-\d{2})', bn)
        if not m:
            return 'FAIL 文件名里没有日期'
        dst = '/daily/%s.html' % m.group(1)
    elif rel.startswith('工具/'):
        dst = '/工具/' + bn
    else:
        return None
    p = subprocess.run(['tcb', 'hosting', 'deploy', path, dst, '-e', ENV],
                       capture_output=True, text=True, timeout=180)
    return dst if p.returncode == 0 else 'FAIL rc=%d %s' % (p.returncode, p.stderr[:120])


if __name__ == '__main__':
    files = []
    for a in args:
        files += sorted(glob.glob(a)) if any(c in a for c in '*?') else [a]
    done, skipped = 0, 0
    for f in files:
        if not f.endswith('.html') or not os.path.exists(f):
            continue
        r = upgrade(f)
        print('%-52s %s' % (os.path.relpath(f, ROOT)[-52:], r))
        if r.startswith('✅'):
            done += 1
            if DEPLOY:
                d = deploy_one(f)
                print('   └─ deploy → %s' % (d or '（不在可部署目录）'))
        else:
            skipped += 1
    print('\n升级 %d 个 ｜ 跳过 %d 个%s' % (done, skipped, '（含部署）' if DEPLOY else ''))
