#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""给工作台外壳 index.html / app.html 注入可拖拽/收起/隐藏的全局侧边栏 + 顶栏隐藏。"""
import pathlib, re, shutil, subprocess

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

CSS = r'''
/* ===== WB-CHROME-V1: 工作台外壳导航（拖拽/收起/隐藏） ===== */
:root{--wb-nav-min:180px;--wb-nav-max:360px;--wb-nav-icon:64px}
.app-sidebar{transition:width .15s ease}
.side-tools{display:flex;align-items:center;gap:4px;padding:0 0 8px;margin-bottom:8px;border-bottom:1px solid var(--border);flex:0 0 auto}
.side-title{font-size:10px;font-weight:800;letter-spacing:.08em;color:#94a3b8;flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.side-actions{display:flex;gap:2px}
.side-tools button{width:22px;height:22px;border:1px solid transparent;background:transparent;border-radius:6px;color:#6b7a8f;font-size:13px;line-height:1;cursor:pointer;padding:0}
.side-tools button:hover{background:#eef4fc;border-color:#c8daf5;color:var(--pri)}
.side-resizer{position:fixed;top:var(--header-h);bottom:0;left:calc(var(--sidebar-w) - 4px);width:8px;z-index:95;cursor:col-resize;touch-action:none}
.side-resizer::after{content:"";position:absolute;top:12px;bottom:12px;left:3px;width:2px;border-radius:2px;background:transparent}
.side-resizer:hover::after,.wb-resizing .side-resizer::after{background:#9bbdf0}
body.wb-resizing{user-select:none;cursor:col-resize}
body.wb-resizing .app-sidebar{transition:none}
.wb-side-collapsed .app-sidebar{width:var(--wb-nav-icon);padding:10px 6px}
.wb-side-collapsed .nav-label,.wb-side-collapsed .nav-group,.wb-side-collapsed .side-title,.wb-side-collapsed .nav-divider{display:none}
.wb-side-collapsed .nav-item{justify-content:center;padding:11px 0;gap:0}
.wb-side-collapsed .nav-item .nav-icon{font-size:19px}
.wb-side-collapsed .side-tools{padding-bottom:6px;margin-bottom:6px;justify-content:center}
.wb-side-collapsed .side-actions{justify-content:center}
.wb-side-collapsed .side-resizer{display:none}
.wb-side-hidden .app-sidebar{display:none}
.wb-side-hidden .app-main,.wb-side-hidden #custToolbar{margin-left:0}
.wb-side-show{display:none;position:fixed;left:10px;top:calc(var(--header-h) + 8px);z-index:130;width:34px;height:34px;align-items:center;justify-content:center;border:1px solid #c8daf5;background:#fff;color:var(--pri);border-radius:9px;box-shadow:0 4px 14px rgba(18,64,145,.18);font-size:16px;cursor:pointer}
.wb-side-show.on{display:flex}
.wb-header-show{display:none;position:fixed;left:50%;top:8px;transform:translateX(-50%);z-index:140;align-items:center;gap:4px;border:1px solid #c8daf5;background:#fff;color:var(--pri);border-radius:999px;padding:5px 11px;box-shadow:0 4px 14px rgba(18,64,145,.18);font-size:11px;font-weight:800;cursor:pointer;white-space:nowrap}
.wb-header-show.on{display:flex}
.wb-header-hidden .app-header{display:none}
.wb-header-hidden .app-main{margin-top:0;min-height:100vh}
.wb-header-hidden .app-sidebar{top:0}
.wb-header-hidden #custToolbar{margin-top:0}
.wb-header-hidden .wb-side-show{top:8px}
@media(max-width:640px){.side-tools,.side-resizer,.wb-side-show,.wb-nav-ctl{display:none!important}}
'''

HEADER_BTNS = ('<button class="btn-icon wb-nav-ctl" id="wbSideToggle" title="收起/展开导航" '
               'aria-label="收起或展开侧边栏" onclick="wbToggleSidebar()">☰</button>'
               '<button class="btn-icon wb-nav-ctl" id="wbHeaderHide" title="隐藏顶栏" '
               'aria-label="隐藏顶栏" onclick="wbHideHeader()">⌃</button>')

SHOW_BTNS = ('<button type="button" class="wb-side-show" id="wbSideShow" title="打开导航栏" '
             'aria-label="打开导航栏" onclick="wbShowSidebar()">☰</button>'
             '<button type="button" class="wb-header-show" id="wbHeaderShow" title="显示顶栏" '
             'aria-label="显示顶栏" onclick="wbShowHeader()">⌄ 显示顶栏</button>')

JS = r'''
<script>
/* ===== WB-CHROME-V1: 工作台外壳导航 ===== */
(function(){
  var KEY='bior_workbench_chrome_v1';
  var NAV={w:230,collapsed:false,hidden:false,headerHidden:false};
  try{var d=JSON.parse(localStorage.getItem(KEY)||'null');if(d&&typeof d==='object'){NAV.w=Math.max(180,Math.min(360,parseInt(d.w,10)||230));NAV.collapsed=!!d.collapsed;NAV.hidden=!!d.hidden;NAV.headerHidden=!!d.headerHidden;}}catch(e){}
  function save(){try{localStorage.setItem(KEY,JSON.stringify(NAV));}catch(e){}}
  function apply(){
    var w=NAV.hidden?0:(NAV.collapsed?64:NAV.w);
    document.documentElement.style.setProperty('--sidebar-w',w+'px');
    document.body.classList.toggle('wb-side-collapsed',!NAV.hidden&&NAV.collapsed);
    document.body.classList.toggle('wb-side-hidden',NAV.hidden);
    document.body.classList.toggle('wb-header-hidden',NAV.headerHidden);
    var ss=document.getElementById('wbSideShow');if(ss)ss.classList.toggle('on',NAV.hidden);
    var hs=document.getElementById('wbHeaderShow');if(hs)hs.classList.toggle('on',NAV.headerHidden);
    var t=document.getElementById('wbSideToggle');
    if(t){t.title=NAV.hidden?'打开导航栏':(NAV.collapsed?'展开导航（显示文字）':'收起为仅图标');t.setAttribute('aria-label',t.title);}
  }
  window.wbToggleSidebar=function(){
    if(NAV.hidden){NAV.hidden=false;}else{NAV.collapsed=!NAV.collapsed;}
    save();apply();if(window.renderNav)window.renderNav();
  };
  window.wbHideSidebar=function(){NAV.hidden=true;save();apply();};
  window.wbShowSidebar=function(){NAV.hidden=false;save();apply();if(window.renderNav)window.renderNav();};
  window.wbHideHeader=function(){NAV.headerHidden=true;save();apply();};
  window.wbShowHeader=function(){NAV.headerHidden=false;save();apply();};
  window.wbSideToolsHtml=function(){
    return '<div class="side-tools"><span class="side-title">导航</span><span class="side-actions">'+
      '<button type="button" title="'+(NAV.collapsed?'展开导航':'收起为仅图标')+'" onclick="wbToggleSidebar()">'+(NAV.collapsed?'⟩':'⟨')+'</button>'+
      '<button type="button" title="隐藏导航栏" onclick="wbHideSidebar()">✕</button></span></div>';
  };
  var drag=false,startX=0,startW=0;
  function move(e){
    if(!drag)return;
    var x=(e.touches&&e.touches[0])?e.touches[0].clientX:e.clientX;
    NAV.w=Math.max(180,Math.min(360,startW+(x-startX)));NAV.collapsed=false;NAV.hidden=false;apply();e.preventDefault();
  }
  function up(){if(!drag)return;drag=false;document.body.classList.remove('wb-resizing');save();window.removeEventListener('pointermove',move);window.removeEventListener('pointerup',up);window.removeEventListener('touchmove',move);window.removeEventListener('touchend',up);}
  function down(e){
    if(drag)return;if(window.innerWidth<=640)return;
    var r=document.getElementById('wbSideResizer');if(!r)return;
    drag=true;startX=(e.touches&&e.touches[0])?e.touches[0].clientX:e.clientX;startW=NAV.w;
    document.body.classList.add('wb-resizing');
    window.addEventListener('pointermove',move,{passive:false});window.addEventListener('pointerup',up,{once:true});
    window.addEventListener('touchmove',move,{passive:false});window.addEventListener('touchend',up,{once:true});
    e.preventDefault();
  }
  function init(){
    var r=document.getElementById('wbSideResizer');
    if(r){r.addEventListener('pointerdown',down);r.addEventListener('touchstart',down,{passive:false});r.addEventListener('dblclick',function(){NAV.w=230;NAV.collapsed=false;NAV.hidden=false;save();apply();if(window.renderNav)window.renderNav();});}
    apply();if(window.renderNav)window.renderNav();
  }
  if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',init);else init();
})();
</script>
'''

def transform(path):
    s = path.read_text(encoding='utf-8')
    bak = path.with_name(path.stem + '_backup_wbchrome_20261101' + path.suffix)
    if not bak.exists():
        shutil.copy2(path, bak)
    if 'WB-CHROME-V1' in s:
        print('already patched', path)
        return
    # CSS before first </style>
    idx = s.find('</style>')
    assert idx > 0, path
    s = s[:idx] + CSS + '\n' + s[idx:]
    # header buttons
    s = s.replace('<header class="app-header">', '<header class="app-header">' + HEADER_BTNS, 1)
    # show buttons after app open
    s = s.replace('<div class="app" id="app">', '<div class="app" id="app">' + SHOW_BTNS, 1)
    # resizer after sidebar
    s = s.replace('<aside class="app-sidebar" id="sidebar"></aside>',
                  '<aside class="app-sidebar" id="sidebar"></aside>\n  <div class="side-resizer" id="wbSideResizer" role="separator" aria-orientation="vertical" aria-label="拖拽调整导航宽度" title="拖拽调整导航宽度；双击恢复默认 230px"></div>', 1)
    # renderNav tools
    s = s.replace('sidebar.innerHTML = _grp.map',
                  'var _wbTools = (window.wbSideToolsHtml ? window.wbSideToolsHtml() : "");\n  sidebar.innerHTML = _wbTools + _grp.map', 1)
    # JS before body close
    s = s.replace('</body>', JS + '\n</body>', 1)
    path.write_text(s, encoding='utf-8')
    print('patched', path, len(s))

for f in FILES:
    transform(f)

# 语法检查：抽出最后一个 script 中新增函数做 node --check
for f in FILES:
    s = f.read_text(encoding='utf-8')
    m = re.search(r'/\* ===== WB-CHROME-V1.*?</script>', s, re.S)
    if m:
        js = m.group(0).replace('</script>', '')
        chk = pathlib.Path('/Users/liuxinyuan/.hermes/profiles/zone-b/cache/scratch/wbchrome_check.js')
        chk.write_text(js, encoding='utf-8')
        r = subprocess.run(['node', '--check', str(chk)], capture_output=True, text=True)
        print('node', f.name, r.returncode, r.stderr[-300:])
