/* ============================================================================
 * DrNick · INLINE home chat — React (Babel). Renders into #hm-chat-root.
 * A contained chat card (not full-screen). Reuses window.DrNickEngine +
 * window.renderMarkdown and the widget's dn-* message components.
 * ==========================================================================*/
const { useState, useRef, useEffect, useCallback } = React;

const HI = {
  send:  () => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>,
  clip:  () => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21.44 11.05 12.25 20.24a5 5 0 0 1-7.07-7.07l9.19-9.19a3.5 3.5 0 0 1 4.95 4.95l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg>,
  check: () => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M20 6 9 17l-5-5"/></svg>,
  shield:() => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10Z"/><path d="m9 12 2 2 4-4"/></svg>,
  chev:  () => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m9 18 6-6-6-6"/></svg>,
  doc:   () => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6M9 13h6M9 17h6"/></svg>,
  x:     () => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M18 6 6 18M6 6l12 12"/></svg>,
  plus:  () => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 5v14M5 12h14"/></svg>,
  delegate: () => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v12M8 11l4 4 4-4"/><path d="M5 21h14"/></svg>,
  yield: () => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M3 17 9 11l4 4 8-8"/><path d="M17 7h4v4"/></svg>,
  wallet: () => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M3 7h15a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h11"/><circle cx="16" cy="13" r="1.4" fill="currentColor" stroke="none"/></svg>,
  history: () => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M3 12a9 9 0 1 0 3-6.7L3 8"/><path d="M3 3v5h5"/><path d="M12 8v4l3 2"/></svg>,
};
const HQICON = { delegate: HI.delegate, yield: HI.yield, balance: HI.wallet, history: HI.history };
const HAVT = 'assets/avt-bot.png';

const hsleep = (ms) => new Promise((r) => setTimeout(r, ms));
function hfmtSize(b) { if (b < 1024) return b + ' B'; if (b < 1024 * 1024) return (b / 1024).toFixed(0) + ' KB'; return (b / 1024 / 1024).toFixed(1) + ' MB'; }

function HMarkdown({ md, streaming }) {
  return <div className="dn-bubble"><span dangerouslySetInnerHTML={{ __html: window.renderMarkdown(md || '') }} />{streaming && <span className="dn-caret" />}</div>;
}
function HToolRow({ item }) {
  const done = item.status === 'done';
  return <div className={'dn-tool' + (done ? ' done' : '')}><span className="spin">{done && <HI.check />}</span><span className="lbl">{item.label}{done ? '' : '…'}</span><span className="nm">{item.name}</span></div>;
}
function HConfirmCard({ item, onConfirm, onCancel }) {
  const c = item.card;
  if (item.status === 'confirmed') return <div className="dn-confirm resolved"><div className="dn-confirm-resolved-note ok"><HI.check /> Confirmed — executing {c.summary.toLowerCase()}</div></div>;
  if (item.status === 'cancelled') return <div className="dn-confirm resolved"><div className="dn-confirm-resolved-note cancel"><HI.x /> Cancelled. Nothing was executed.</div></div>;
  return (
    <div className="dn-confirm">
      <div className="dn-confirm-head"><span className="ttl"><HI.shield /> {c.title}</span><span className="onfa-badge pending">Action</span></div>
      <div className="dn-confirm-ttl-line">{c.summary}</div>
      <div className="dn-confirm-rows">{c.lines.map((l, i) => (<div className="dn-confirm-row" key={i}><span className="k">{l.k}</span><span className={'v' + (l.gold ? ' gold' : '')}>{l.v}</span></div>))}</div>
      <div className="dn-confirm-token"><span className="tk">token · <b>{c.confirm_token}</b></span><span className="ttl-timer"><span className="dot" />expires {c.ttl}</span></div>
      <div className="dn-confirm-actions"><button className="onfa-btn ghost" onClick={() => onCancel(item)}>Cancel</button><button className="onfa-btn primary" onClick={() => onConfirm(item)}>Confirm</button></div>
    </div>
  );
}
function HUserMsg({ item }) {
  return (
    <div className="dn-msg user"><div className="dn-bubble">
      {item.files && item.files.map((f, i) => (<div className="dn-msg-file" key={i}>{f.url ? <img src={f.url} alt="" /> : <span className="fic"><HI.doc /></span>}<span className="fmeta"><span className="fname">{f.name}</span><span className="fsize">{hfmtSize(f.size)}</span></span></div>))}
      {item.text && <span>{item.text}</span>}
    </div></div>
  );
}

function HomeChat() {
  const [messages, setMessages] = useState([]);
  const [busy, setBusy] = useState(false);
  const [input, setInput] = useState('');
  const [attachments, setAttachments] = useState([]);
  const [lang, setLang] = useState('VI');
  const idRef = useRef(0);
  const scrollRef = useRef(null);
  const fileRef = useRef(null);
  const taRef = useRef(null);

  const nid = () => 'm' + (++idRef.current);
  const addMsg = (m) => setMessages((cur) => [...cur, m]);
  const patch = (id, f) => setMessages((cur) => cur.map((m) => (m.id === id ? { ...m, ...f } : m)));
  const pendingTx = messages.some((m) => m.role === 'confirm' && m.status === 'pending');
  const inChat = messages.length > 0;

  useEffect(() => { const el = scrollRef.current; if (el) el.scrollTop = el.scrollHeight; }, [messages]);

  const streamInto = (id, full) => new Promise((resolve) => {
    const tokens = full.match(/\S+\s*|\s+/g) || [full];
    let i = 0, acc = '';
    const tick = () => { acc += tokens[i] || ''; i++; if (tokens[i]) { acc += tokens[i]; i++; } patch(id, { md: acc }); if (i < tokens.length) setTimeout(tick, 22); else resolve(); };
    tick();
  });

  const play = useCallback(async (steps) => {
    setBusy(true);
    for (const step of steps) {
      if (step.type === 'tool') {
        const id = nid(); addMsg({ id, role: 'tool', name: step.name, label: step.label, status: 'running' });
        await hsleep(step.ms); patch(id, { status: 'done' }); await hsleep(220);
      } else if (step.type === 'stream') {
        const id = nid(); addMsg({ id, role: 'bot', md: '', streaming: true });
        await hsleep(120); await streamInto(id, step.markdown); patch(id, { streaming: false }); await hsleep(140);
      } else if (step.type === 'confirm') {
        addMsg({ id: nid(), role: 'confirm', card: step, status: 'pending' }); setBusy(false); return;
      }
    }
    setBusy(false);
  }, []);

  const send = useCallback((text, files) => {
    const t = (text || '').trim(); const fs = files || [];
    if (!t && fs.length === 0) return;
    addMsg({ id: nid(), role: 'user', text: t, files: fs });
    setInput(''); setAttachments([]);
    if (taRef.current) taRef.current.style.height = 'auto';
    play(window.DrNickEngine.respond(t, fs.length > 0));
  }, [play]);

  const onConfirm = (item) => { patch(item.id, { status: 'confirmed' }); play(window.DrNickEngine.confirmResult(item.card)); };
  const onCancel = (item) => { patch(item.id, { status: 'cancelled' }); };
  const onQuick = (key) => { if (!busy && !pendingTx) play(window.DrNickEngine.quick(key)); };
  const reset = () => { setMessages([]); setInput(''); setAttachments([]); setBusy(false); };
  const onSubmit = () => { if (!busy) send(input, attachments); };
  const onKey = (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); onSubmit(); } };
  const onPickFiles = (e) => {
    const list = Array.from(e.target.files || []);
    const next = list.map((f) => ({ name: f.name, size: f.size, kind: f.type.startsWith('image/') ? 'image' : 'doc', url: f.type.startsWith('image/') ? URL.createObjectURL(f) : null }));
    setAttachments((cur) => [...cur, ...next]); e.target.value = '';
  };
  const removeAttach = (i) => setAttachments((cur) => cur.filter((_, idx) => idx !== i));
  const grow = (e) => { setInput(e.target.value); const el = e.target; el.style.height = 'auto'; el.style.height = Math.min(el.scrollHeight, 120) + 'px'; };

  const canSend = (input.trim().length > 0 || attachments.length > 0) && !busy;
  const quickDisabled = busy || pendingTx;
  const g = window.DrNickEngine.greeting;

  return (
    <div className="hm-chat dn-scope hm-chat-scope" data-theme="dark">
      <div className="hm-chat-head">
        <img className="av" src={HAVT} alt="" />
        <div className="meta">
          <div className="nm">Dr.Nick</div>
          <div className="st"><span className="dot" />{lang === 'VI' ? 'Cố vấn ONFA · Trực tuyến' : 'ONFA Advisor · Online'}</div>
        </div>
        <div className="acts">
          <div className="hm-seg" role="group" aria-label="Language">
            <button className={lang === 'VI' ? 'on' : ''} onClick={() => setLang('VI')}>VI</button>
            <button className={lang === 'EN' ? 'on' : ''} onClick={() => setLang('EN')}>EN</button>
          </div>
          {inChat && <button className="iconbtn" aria-label={lang === 'VI' ? 'Trò chuyện mới' : 'New chat'} title={lang === 'VI' ? 'Trò chuyện mới' : 'New chat'} onClick={reset}><HI.plus /></button>}
        </div>
      </div>

      <div className="hm-chat-scroll" ref={scrollRef}>
        {!inChat ? (
          <div className="hm-cw">
            <img className="hm-cw-av" src="assets/bot.png" alt="Dr.Nick" />
            <h3>{lang === 'VI' ? 'Bạn đang nghĩ đến điều gì?' : "What's on your mind today?"}</h3>
            <p>{lang === 'VI' ? 'Hỏi về số dư, chuyển đổi hay dự trữ — mọi giao dịch luôn xem trước.' : 'Ask about balance, swaps or reserves — actions always preview first.'}</p>
            <div className="hm-cw-chips">
              {g.chips.map((c, i) => (<button className="hm-cw-chip" key={i} onClick={() => send(c)}><span>{c}</span><HI.chev /></button>))}
            </div>
          </div>
        ) : (
          <div className="dn-thread">
            {messages.map((m) => {
              if (m.role === 'user') return <HUserMsg item={m} key={m.id} />;
              if (m.role === 'tool') return <HToolRow item={m} key={m.id} />;
              if (m.role === 'confirm') return <HConfirmCard item={m} key={m.id} onConfirm={onConfirm} onCancel={onCancel} />;
              return (<div className="dn-msg bot" key={m.id}><img className="dn-msg-av" src={HAVT} alt="" /><HMarkdown md={m.md} streaming={m.streaming} /></div>);
            })}
          </div>
        )}
      </div>

      <div className="hm-composer">
        <div className={'dn-quick' + (quickDisabled ? ' disabled' : '')} role="group" aria-label={lang === 'VI' ? 'Hành động nhanh' : 'Quick actions'}>
          {window.DrNickEngine.quickActions.map((a) => { const Ic = HQICON[a.key]; return (<button className="dn-qbtn" key={a.key} disabled={quickDisabled} onClick={() => onQuick(a.key)}><Ic /><span>{a.label}</span></button>); })}
        </div>
        {attachments.length > 0 && (
          <div className="dn-attach-row">
            {attachments.map((f, i) => (<div className="dn-attach-chip" key={i}>{f.url ? <img src={f.url} alt="" /> : <span className="fic"><HI.doc /></span>}<span className="nm">{f.name}</span><button className="x" aria-label="Remove" onClick={() => removeAttach(i)}><HI.x /></button></div>))}
          </div>
        )}
        <div className="dn-input-row">
          <input ref={fileRef} type="file" multiple accept="image/*,.pdf,.doc,.docx,.xls,.xlsx" style={{ display: 'none' }} onChange={onPickFiles} />
          <button className="dn-attach-btn" aria-label="Attach file" onClick={() => fileRef.current && fileRef.current.click()}><HI.clip /></button>
          <textarea ref={taRef} className="dn-textarea" rows="1" placeholder={lang === 'VI' ? 'Hỏi về số dư, chuyển đổi, dự trữ…' : 'Ask about balance, swaps, reserves…'} value={input} onChange={grow} onKeyDown={onKey} />
          <button className="dn-send" aria-label="Send" disabled={!canSend} onClick={onSubmit}><HI.send /></button>
        </div>
        <div className="dn-footnote">{lang === 'VI' ? <span>Xác thực phía máy chủ · <b>JWT</b> · giao dịch luôn xem trước</span> : <span>Server-verified · <b>JWT-authed</b> · actions preview first</span>}</div>
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('hm-chat-root')).render(<HomeChat />);
