/* ════════════════════════════════════════════════════════════
   Notion-style block toggle + signature canvas + slash menu
   ════════════════════════════════════════════════════════════ */

const { useState: nb_s, useEffect: nb_e, useRef: nb_r } = React;

/* ─── P5-4 · Foldable section (Notion toggle) ──────────────── */
function FoldSection({ title, children, defaultOpen = true, kicker }) {
  const [open, setOpen] = nb_s(defaultOpen);
  return (
    <div className={'fold-section' + (open ? ' open' : '')}>
      <button className="fold-head" onClick={() => { setOpen(!open); window.haptic?.selection(); }} aria-expanded={open}>
        <span className={'nb-toggle' + (open ? ' open' : '')}>▸</span>
        {kicker && <span className="fold-kicker">{kicker}</span>}
        <span className="fold-title">{title}</span>
      </button>
      <div className="fold-body" style={{
        maxHeight: open ? '5000px' : '0',
        opacity: open ? 1 : 0,
      }}>
        {children}
      </div>
    </div>
  );
}
window.FoldSection = FoldSection;

/* ─── P5-3 · Apple Pencil-style signature canvas ──────────── */
function SignaturePad({ onChange, height = 120 }) {
  const ref = nb_r(null);
  const drawing = nb_r(false);
  const last = nb_r({ x: 0, y: 0, t: 0 });
  const [empty, setEmpty] = nb_s(true);
  const lang = window.__LANG || 'zh';

  nb_e(() => {
    const c = ref.current;
    if (!c) return;
    const dpr = window.devicePixelRatio || 1;
    const rect = c.getBoundingClientRect();
    c.width  = rect.width * dpr;
    c.height = rect.height * dpr;
    const ctx = c.getContext('2d');
    ctx.scale(dpr, dpr);
    ctx.lineCap = 'round';
    ctx.lineJoin = 'round';
    ctx.strokeStyle = getComputedStyle(c).getPropertyValue('--text-1') || '#fff';
  }, []);

  const getXY = (e) => {
    const r = ref.current.getBoundingClientRect();
    return { x: e.clientX - r.left, y: e.clientY - r.top, t: performance.now() };
  };

  const onDown = (e) => {
    drawing.current = true;
    last.current = getXY(e);
    ref.current.setPointerCapture?.(e.pointerId);
    setEmpty(false);
  };

  const onMove = (e) => {
    if (!drawing.current) return;
    const p = getXY(e);
    const ctx = ref.current.getContext('2d');
    const dt = Math.max(1, p.t - last.current.t);
    const dist = Math.hypot(p.x - last.current.x, p.y - last.current.y);
    const speed = dist / dt;
    // Pressure-like: slower = thicker (Apple Pencil simulation)
    const w = Math.max(0.8, Math.min(2.6, 2.6 - speed * 6));
    ctx.lineWidth = w;
    ctx.beginPath();
    ctx.moveTo(last.current.x, last.current.y);
    ctx.lineTo(p.x, p.y);
    ctx.stroke();
    last.current = p;
  };

  const onUp = (e) => {
    drawing.current = false;
    try { ref.current.releasePointerCapture?.(e.pointerId); } catch (er) {}
    if (!empty) {
      onChange?.(ref.current.toDataURL('image/png'));
      window.haptic?.light();
    }
  };

  const clear = () => {
    const c = ref.current;
    const ctx = c.getContext('2d');
    ctx.clearRect(0, 0, c.width, c.height);
    setEmpty(true);
    onChange?.(null);
  };

  return (
    <div className="sig-pad-wrap">
      <canvas ref={ref} className="sig-pad" style={{ height }}
        onPointerDown={onDown} onPointerMove={onMove}
        onPointerUp={onUp} onPointerCancel={onUp}/>
      <div className="sig-foot">
        <span className="sig-x">×</span>
        <span className="sig-line">{lang==='zh'?'在此处签名':'Sign here'}</span>
        <button className="sig-clear" onClick={clear} data-haptic="light">{lang==='zh'?'清除':'Clear'}</button>
      </div>
    </div>
  );
}
window.SignaturePad = SignaturePad;

/* ─── Sign modal — uses SignaturePad with full contract ───── */
function SignModal({ rec, onClose }) {
  const [sig, setSig] = nb_s(null);
  const [stamping, setStamping] = nb_s(false);
  const [done, setDone] = nb_s(false);
  const lang = window.__LANG || 'zh';
  const dateStr = new Date().toLocaleDateString(lang==='zh'?'zh-CN':'en-US', { year:'numeric', month:'long', day:'numeric' });

  const commit = () => {
    if (!sig) { window.haptic?.error(); return; }
    setStamping(true);
    window.felix?.stamp_sfx?.();
    window.announce?.(lang==='zh'?'已签署承诺书':'Contract signed');
    setTimeout(() => {
      window.LS?.set?.('sig.' + rec.symbol, { t: Date.now(), img: sig });
      try { localStorage.setItem('sig.' + rec.symbol, JSON.stringify({ t: Date.now(), img: sig })); } catch (e) {}
      setDone(true);
      window.toast?.({ msg: lang==='zh'?`已签署 · ${rec.symbol} 承诺书已存档`:`Signed · ${rec.symbol} acknowledgement filed`, kind: 'success' });
      setTimeout(() => onClose(), 1100);
    }, 380);
  };

  return (
    <div className="sign-modal-bg" onClick={onClose}>
      <div className="sign-modal" onClick={(e) => e.stopPropagation()} role="dialog" aria-modal="true">
        <div className="sm-mast">
          <span className="sm-fileno">FILE NO. {rec.symbol}-{new Date().getFullYear()}</span>
          <span className="sm-title">{lang==='zh'?'承诺书 · ACKNOWLEDGEMENT':'ACKNOWLEDGEMENT OF RISK'}</span>
          <button className="sm-close" onClick={onClose} aria-label="close">×</button>
        </div>

        <div className="sm-body">
          <p className="sm-clause">
            <span className="sm-cnum">§I.</span>{' '}
            {lang==='zh'
              ? <>本人确认知悉 <b>{rec.symbol}</b> 当前估值具有高度不确定性,亏损概率为 <b style={{color:'var(--down-strong)'}}>{Math.round(rec.risk.loss_probability*100)}%</b>,最大回撤可能达 <b style={{color:'var(--down-strong)'}}>−{rec.risk.max_drawdown_pct.toFixed(1)}%</b>。</>
              : <>I acknowledge that <b>{rec.symbol}</b> carries substantial uncertainty, with a loss probability of <b style={{color:'var(--down-strong)'}}>{Math.round(rec.risk.loss_probability*100)}%</b> and a possible drawdown of <b style={{color:'var(--down-strong)'}}>−{rec.risk.max_drawdown_pct.toFixed(1)}%</b>.</>}
          </p>
          <p className="sm-clause">
            <span className="sm-cnum">§II.</span>{' '}
            {lang==='zh'
              ? <>本推荐基于历史数据 (n = <b>{rec.backtest.sample_size}</b>),不构成必然预测。市场或反向运动,本人愿意自行承担后果。</>
              : <>This pick is based on historical data (n = <b>{rec.backtest.sample_size}</b>) and is not a guarantee. Markets may reverse; I accept the outcome.</>}
          </p>
          <p className="sm-clause">
            <span className="sm-cnum">§III.</span>{' '}
            {lang==='zh'
              ? <>若触发止损 <b>{rec.recommendation.stop_loss}</b>,本人承诺将依约离场,不情绪化加仓。</>
              : <>If the stop-loss at <b>{rec.recommendation.stop_loss}</b> triggers, I commit to exit per protocol — no emotional averaging-down.</>}
          </p>
        </div>

        <div className="sm-sign">
          <div className="sm-sign-lab">{lang==='zh'?'签名 · Signature':'Signature'}</div>
          <window.SignaturePad onChange={setSig} height={130} />
          <div className="sm-date">{lang==='zh'?'日期':'Date'} · <span>{dateStr}</span></div>
        </div>

        <div className="sm-foot">
          <button className="act-btn" onClick={onClose}>{lang==='zh'?'取消':'Cancel'}</button>
          <button className={'act-btn primary' + (!sig ? ' disabled' : '') + (stamping ? ' stamping' : '')}
                  disabled={!sig || stamping} onClick={commit}>
            {done ? (lang==='zh'?'已存档 ✓':'Filed ✓')
                  : stamping ? (lang==='zh'?'盖章中…':'Stamping…')
                             : (lang==='zh'?'确认签署 & 盖章':'Sign & Stamp')}
          </button>
        </div>

        {stamping && <div className={'sm-stamp' + (done ? ' on' : '')}>SIGNED</div>}
      </div>
    </div>
  );
}

window.openSignModal = (rec) => {
  const host = document.createElement('div');
  document.body.appendChild(host);
  const root = ReactDOM.createRoot(host);
  const close = () => { root.unmount(); host.remove(); };
  root.render(<SignModal rec={rec} onClose={close} />);
};
