/* ===================================================================
   KabelFlux — AI Tools panel (views-ai-tools.jsx)
   Exposes window.AIToolsPanel. One card hosting the read-only AI helpers:
   narrate, parts intelligence, continuity, change-impact, standards Q&A.
   ES2015-safe (no object-rest, no {...} literals).
   =================================================================== */
const AIToolsPanel = ({ pid }) => {
  const { useState } = React;
  const [importWires, setImportWires] = useState([]);
  const [tool, setTool] = useState('narrate');
  const [failure, setFailure] = useState('');
  const [change, setChange] = useState('');
  const [question, setQuestion] = useState('');
  const [excerpt, setExcerpt] = useState('');
  const [email, setEmail] = useState('');
  const [out, setOut] = useState('');
  const [busy, setBusy] = useState(false);

  const TOOLS = [
    { k: 'narrate', l: 'Narrate harness' },
    { k: 'parts', l: 'Parts intelligence' },
    { k: 'continuity', l: 'Continuity troubleshooter' },
    { k: 'change', l: 'Change impact' },
    { k: 'standards', l: 'Standards Q&A' },
    { k: 'wire-sizing', l: 'Wire sizing' },
    { k: 'quote', l: 'Quote estimate' },
    { k: 'build', l: 'Build instructions' },
    { k: 'rfq', l: 'RFQ triage' },
    { k: 'anomaly', l: 'Anomaly check' },
    { k: 'estimates', l: 'Estimates (length/bundle)' },
    { k: 'det-quote', l: 'Quote (deterministic)' },
    { k: 'import', l: 'Smart import (CSV)' },
    { k: 'import-netlist', l: 'Netlist / KBL import' },
  ];

  async function run() {
    if (busy || !pid) return;
    setOut('');
    setBusy(true);
    let acc = '';
    const onEv = function (ev) {
      if (ev.type === 'text') { acc += ev.text; setOut(acc); }
      else if (ev.type === 'error') { setOut(ev.message || 'AI request failed.'); }
    };
    if (tool === 'narrate') await window.kfxAiNarrateStream(pid, onEv);
    else if (tool === 'parts') await window.kfxAiPartsStream(pid, onEv);
    else if (tool === 'continuity') await window.kfxAiContinuityStream(pid, failure, onEv);
    else if (tool === 'change') await window.kfxAiChangeImpactStream(pid, change, onEv);
    else if (tool === 'standards') await window.kfxAiStandardsStream(pid, question, excerpt, onEv);
    else if (tool === 'wire-sizing') await window.kfxAiWireSizingStream(pid, onEv);
    else if (tool === 'quote') await window.kfxAiQuoteStream(pid, onEv);
    else if (tool === 'build') await window.kfxAiBuildInstructionsStream(pid, onEv);
    else if (tool === 'rfq') await window.kfxAiRfqStream(pid, email, onEv);
    else if (tool === 'anomaly') await window.kfxAiAnomalyStream(pid, onEv);
    else if (tool === 'det-quote') {
      try {
        const q = await window.kfxQuote(pid);
        const lines = ['Deterministic quote (margin ' + q.margin_pct + '%):', ''];
        (q.breaks || []).forEach(function (b) {
          lines.push('Qty ' + b.qty + ': unit ' + b.unit_price + ' (cost ' + b.unit_cost + '), extended ' + b.extended_price + ', lead ' + b.lead_time_days + 'd');
          if ((b.long_lead_parts || []).length) lines.push('  Long-lead: ' + b.long_lead_parts.join(', '));
        });
        if ((q.unpriced_parts || []).length) { lines.push(''); lines.push('UNPRICED: ' + q.unpriced_parts.join(', ') + ' — import supplier prices in Settings'); }
        lines.push(''); lines.push('Download: use the quote XLSX export for the customer-facing sheet.');
        setOut(lines.join('\n'));
      } catch (e) { setOut('Quote failed: ' + (e && e.message ? e.message : e)); }
    }
    else if (tool === 'estimates') {
      try {
        const d = await window.kfxGetEstimates(pid);
        const lines = ['Wire lengths (estimated, mm):'];
        (d.lengths || []).forEach(function (l) { lines.push('  #' + l.id + ': ' + l.length_mm + ' mm'); });
        lines.push('');
        lines.push('Bundles (estimated OD):');
        (d.bundles || []).forEach(function (b) { lines.push('  ' + b.group + ': ' + b.wire_count + ' wires, ~' + b.bundle_od_mm + ' mm'); });
        if (d.cost) {
          lines.push('');
          lines.push('Labour (' + d.cost.labour.total_minutes + ' min @ ' + d.cost.labour_rate + '/hr = ' + d.cost.labour_cost + '):');
          (d.cost.labour.breakdown || []).forEach(function (i) { lines.push('  ' + i.op + ': ' + i.minutes + ' min'); });
          lines.push('Material: wire ' + d.cost.material.wire_cost + ' + consumables ' + d.cost.material.consumable_cost + ' + connectors ' + d.cost.material.connector_cost + ' = ' + d.cost.material.total);
          if ((d.cost.material.unpriced_parts || []).length) lines.push('  Unpriced: ' + d.cost.material.unpriced_parts.join(', '));
          lines.push('Overhead (' + d.cost.overhead_pct + '%): ' + d.cost.overhead_cost);
          lines.push('TOTAL: ' + d.cost.total);
        }
        setOut(lines.join('\n'));
      } catch (e) { setOut('Estimate failed: ' + (e && e.message ? e.message : e)); }
    }
    setBusy(false);
  }

  return (
    <div className="card" style={{ marginTop: 12, flexShrink: 0 }}>
      <div className="card-head"><h3>AI tools</h3></div>
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, padding: '0 0 8px' }}>
        {TOOLS.map(function (t) {
          return (
            <button key={t.k} onClick={function () { setTool(t.k); setOut(''); }} style={aitChip(tool === t.k)}>
              {t.l}
            </button>
          );
        })}
      </div>
      {tool === 'continuity' && (
        <input value={failure} onChange={function (e) { setFailure(e.target.value); }}
          placeholder="e.g. pins 4-7 open on J3" style={aitInp()} />
      )}
      {tool === 'change' && (
        <input value={change} onChange={function (e) { setChange(e.target.value); }}
          placeholder="e.g. swap J5 from DB9 to DB15" style={aitInp()} />
      )}
      {tool === 'standards' && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          <input value={question} onChange={function (e) { setQuestion(e.target.value); }}
            placeholder="Standards question (e.g. shield termination, IPC-620 Class 3?)" style={aitInp()} />
          <textarea value={excerpt} onChange={function (e) { setExcerpt(e.target.value); }}
            placeholder="Optional: paste the licensed standard excerpt to ground the answer with citations"
            style={Object.assign({}, aitInp(), { minHeight: 60, resize: 'vertical' })} />
        </div>
      )}
      {tool === 'rfq' && (
        <textarea value={email} onChange={function (e) { setEmail(e.target.value); }}
          placeholder="Paste the customer RFQ email text"
          style={Object.assign({}, aitInp(), { minHeight: 80, resize: 'vertical' })} />
      )}
      {(tool === 'import' || tool === 'import-netlist') && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          <input type="file" accept={tool === 'import-netlist' ? '.net,.xml,.kbl,.txt,text/plain' : '.csv,text/csv'} style={aitInp()}
            onChange={async function (e) {
              const f = e.target.files && e.target.files[0]; e.target.value = '';
              if (!f) return;
              setOut('Mapping…'); setImportWires([]);
              try {
                const mapper = tool === 'import-netlist' ? window.kfxAiImportNetlist : window.kfxAiImportMap;
                const d = await mapper(pid, f);
                setImportWires(d.wires || []);
                setOut((d.notes ? d.notes + '\n\n' : '') + 'Proposed ' + (d.count || 0) + ' wires:\n'
                  + JSON.stringify(d.wires || [], null, 2));
              } catch (err) { setOut('Import map failed: ' + (err && err.message ? err.message : err)); }
            }} />
          {importWires.length > 0 && (
            <button style={aitRun()} onClick={async function () {
              try {
                const n = await window.kfxImportWires(pid, importWires);
                setOut('Imported ' + n + ' wires — open the Wires tab to review.');
                setImportWires([]);
              } catch (err) { setOut('Import failed: ' + (err && err.message ? err.message : err)); }
            }}>{'Import ' + importWires.length + ' wires'}</button>
          )}
        </div>
      )}
      {tool !== 'import' && tool !== 'import-netlist' && (
        <div style={{ marginTop: 8 }}>
          <button onClick={run} disabled={busy} style={aitRun()}>{busy ? 'Running…' : 'Run'}</button>
        </div>
      )}
      {out && (
        <div style={{ marginTop: 10 }}>
          <div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: 6 }}>
            <button onClick={function () { window.kfxExportMarkdownPdf && window.kfxExportMarkdownPdf('AI — ' + tool, out); }}
              style={{ padding: '4px 10px', borderRadius: 6, border: '1px solid var(--line)', background: 'transparent',
                color: 'var(--t-1)', fontSize: 11, fontWeight: 700, cursor: 'pointer' }}>Export PDF</button>
          </div>
          <div style={{ padding: 12, background: 'var(--bg-2)', border: '1px solid var(--line)',
            borderRadius: 8, fontSize: 12, color: 'var(--t-1)', lineHeight: 1.5 }}
            dangerouslySetInnerHTML={{ __html: window.mdToHtml ? window.mdToHtml(out) : out }} />
        </div>
      )}
    </div>
  );
};

function aitChip(active) {
  return { padding: '5px 10px', borderRadius: 'var(--r-pill)', border: '1px solid var(--line)',
    cursor: 'pointer', fontSize: 11, fontWeight: 600, color: active ? '#fff' : 'var(--t-2)',
    background: active ? 'var(--accent)' : 'transparent' };
}
function aitInp() {
  return { width: '100%', padding: '8px 10px', borderRadius: 6, border: '1px solid var(--line)',
    background: 'var(--bg-2)', color: 'var(--t-1)', fontSize: 12, boxSizing: 'border-box' };
}
function aitRun() {
  return { padding: '6px 14px', borderRadius: 6, border: 'none', cursor: 'pointer',
    fontSize: 12, fontWeight: 700, color: '#fff', background: 'var(--accent)' };
}

window.AIToolsPanel = AIToolsPanel;
