// ─── Global search (⌘K) + live Home dashboard ────────────────

// ====== Global search ========================================
function searchAll(q) {
  const s = q.trim().toLowerCase();
  if (!s) return [];
  const out = [];
  scopeOwner(CRMStore.list('leads')).filter(l => (l.company + ' ' + l.person + ' ' + l.role + ' ' + l.city).toLowerCase().includes(s)).slice(0, 5)
    .forEach(l => out.push({ type:'lead', view:'leads', icon:'leads', title:l.company, sub:l.person + ' · ' + (LEAD_STATUS[l.status] || {}).label + ' · ' + l.id }));
  scopeOwner(CRMStore.list('accounts')).filter(a => (a.name + ' ' + a.ind + ' ' + a.city).toLowerCase().includes(s)).slice(0, 5)
    .forEach(a => out.push({ type:'account', view:'accounts', icon:'accounts', title:a.name, sub:(a.ind || '—') + ' · ' + (a.city || '') + ' · ' + a.id }));
  scopeOwner(CRMStore.list('opportunities')).filter(o => o.name.toLowerCase().includes(s)).slice(0, 5)
    .forEach(o => out.push({ type:'opp', view:'opps', icon:'opps', title:o.name, sub:fmtEUR(o.amount) + ' · ' + (STAGE_META[o.stage] || {}).label + ' · ' + o.id }));
  scopeOwner(CRMStore.list('quotes')).filter(qq => qq.title.toLowerCase().includes(s)).slice(0, 5)
    .forEach(qq => out.push({ type:'quote', view:'quotes', icon:'quotes', title:qq.title, sub:fmtEUR(quoteTotal(qq)) + ' · ' + (QUOTE_STATUS[qq.status] || {}).label + ' · ' + qq.id }));
  CRMStore.list('contacts').filter(c => c.name.toLowerCase().includes(s)).slice(0, 4)
    .forEach(c => { const a = CRMStore.get('accounts', c.accountId); out.push({ type:'contact', view:'accounts', icon:'accounts', title:c.name, sub:(c.role || '') + (a ? ' · ' + a.name : '') }); });
  scopeOwner(CRMStore.list('activities')).filter(a => a.subject.toLowerCase().includes(s)).slice(0, 4)
    .forEach(a => out.push({ type:'activity', view:'activities', icon:'activities', title:a.subject, sub:(ACT_KIND[a.kind] || {}).label + ' · ' + a.when }));
  return out;
}

const TYPE_LABEL = { lead:'Lead', account:'Account', opp:'Opportunity', quote:'Angebot', contact:'Kontakt', activity:'Aktivität' };

function GlobalSearch({ go }) {
  const [open, setOpen] = useS(false);
  const [q, setQ] = useS('');
  const [sel, setSel] = useS(0);
  const inputRef = React.useRef(null);

  useE(() => {
    const h = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') { e.preventDefault(); setOpen(true); }
      if (e.key === 'Escape') setOpen(false);
    };
    window.addEventListener('keydown', h);
    return () => window.removeEventListener('keydown', h);
  }, []);
  useE(() => { if (open && inputRef.current) inputRef.current.focus(); if (!open) { setQ(''); setSel(0); } }, [open]);

  const results = open ? searchAll(q) : [];
  const choose = (r) => { go(r.view); setOpen(false); toast(TYPE_LABEL[r.type] + ' geöffnet: ' + r.title); };

  const onKey = (e) => {
    if (e.key === 'ArrowDown') { e.preventDefault(); setSel(i => Math.min(i + 1, results.length - 1)); }
    if (e.key === 'ArrowUp') { e.preventDefault(); setSel(i => Math.max(i - 1, 0)); }
    if (e.key === 'Enter' && results[sel]) { e.preventDefault(); choose(results[sel]); }
  };

  return (
    <>
      <button className="hdr-search" onClick={() => setOpen(true)} title="Globale Suche (⌘K)">
        {Icons.search}<span>Suche …</span><kbd>⌘K</kbd>
      </button>
      {open && (
        <div className="gs-scrim" onMouseDown={() => setOpen(false)}>
          <div className="gs-panel" onMouseDown={e => e.stopPropagation()}>
            <div className="gs-input">
              {Icons.search}
              <input ref={inputRef} value={q} onChange={e => { setQ(e.target.value); setSel(0); }} onKeyDown={onKey}
                placeholder="Leads, Accounts, Opportunities, Angebote, Kontakte …" />
              <kbd>ESC</kbd>
            </div>
            <div className="gs-results">
              {q.trim() === '' && <div className="gs-hint">Tippen, um alle Module zu durchsuchen. ↑ ↓ zum Navigieren, ⏎ zum Öffnen.</div>}
              {q.trim() !== '' && results.length === 0 && <div className="gs-hint">Keine Treffer für „{q}".</div>}
              {results.map((r, i) => (
                <div key={i} className={"gs-item" + (i === sel ? " sel" : "")} onMouseEnter={() => setSel(i)} onClick={() => choose(r)}>
                  <span className="gs-ic">{Icons[r.icon]}</span>
                  <span className="gs-text"><b>{r.title}</b><span>{r.sub}</span></span>
                  <span className="gs-type">{TYPE_LABEL[r.type]}</span>
                </div>
              ))}
            </div>
          </div>
        </div>
      )}
    </>
  );
}

// ====== Live dashboard =======================================
function Dashboard({ go }) {
  const openOpps = scopeOwner(CRMStore.list('opportunities')).filter(o => !['won','lost'].includes(o.stage));
  const stages = ['qual','disc','prop','neg','close'];
  const byStage = stages.map(s => { const list = openOpps.filter(o => o.stage === s); return { s, count:list.length, sum:list.reduce((a, o) => a + (o.amount || 0), 0) }; });
  const maxSum = Math.max(1, ...byStage.map(x => x.sum));

  const leads = scopeOwner(CRMStore.list('leads'));
  const funnel = [
    { k:'new', label:'New', n:leads.filter(l => l.status === 'new').length },
    { k:'work', label:'Working', n:leads.filter(l => l.status === 'work').length },
    { k:'qual', label:'Qualified', n:leads.filter(l => l.status === 'qual').length },
    { k:'conv', label:'Converted', n:leads.filter(l => l.status === 'conv').length }
  ];
  const maxF = Math.max(1, ...funnel.map(f => f.n));

  const quotes = scopeOwner(CRMStore.list('quotes'));
  const qStat = [['draft','Entwurf'],['sent','Versendet'],['accepted','Angenommen']].map(([k, label]) => ({ k, label, n:quotes.filter(x => x.status === k).length }));

  return (
    <div className="dash-grid">
      <div className="dash-card" onClick={() => go('opps')}>
        <div className="dash-hd"><h3>Pipeline nach Phase</h3><span className="dash-link">Opportunities →</span></div>
        <div className="pipe">
          {byStage.map(x => (
            <div key={x.s} className="pipe-row">
              <span className="pipe-label"><span className={"stage-pill " + (STAGE_META[x.s] || {}).cls}><span className="dot"></span>{(STAGE_META[x.s] || {}).label}</span></span>
              <span className="pipe-track"><span className="pipe-fill" style={{ width: (x.sum / maxSum * 100) + '%' }}></span></span>
              <span className="pipe-val"><b>{fmtEUR(x.sum)}</b><small>{x.count}</small></span>
            </div>
          ))}
        </div>
      </div>

      <div className="dash-card" onClick={() => go('leads')}>
        <div className="dash-hd"><h3>Lead-Funnel</h3><span className="dash-link">Leads →</span></div>
        <div className="funnel">
          {funnel.map((f, i) => (
            <div key={f.k} className="funnel-row">
              <span className="funnel-label">{f.label}</span>
              <span className="funnel-track"><span className={"funnel-fill " + f.k} style={{ width: (f.n / maxF * 100) + '%' }}>{f.n > 0 && <b>{f.n}</b>}</span></span>
            </div>
          ))}
        </div>
        <div className="dash-foot">
          {qStat.map(s => <span key={s.k} className="qstat">{s.label}: <b>{s.n}</b></span>)}
        </div>
      </div>
    </div>
  );
}

// ====== Next Best Action (kiki AI mockup) ====================
function daysFromToday(dateStr) {
  if (!dateStr) return 999;
  const d = new Date(dateStr); if (isNaN(d)) return 999;
  return Math.round((d - new Date()) / 86400000);
}

function computeNBA() {
  const nba = [];
  const leads = scopeOwner(CRMStore.list('leads'));
  const opps = scopeOwner(CRMStore.list('opportunities'));
  const quotes = scopeOwner(CRMStore.list('quotes'));
  const accounts = scopeOwner(CRMStore.list('accounts'));

  leads.filter(l => l.status === 'new').sort((a, b) => b.score - a.score).slice(0, 1).forEach(l => {
    if (l.score >= 70) nba.push({ icon:'leads', conf: Math.min(95, 58 + Math.round(l.score / 3)), view:'leads', rec:l, action:'edit',
      title:'Sofort kontaktieren: ' + l.company,
      reason:'Hoher Lead-Score ' + l.score + '/100 · Quelle ' + ((SRC_META[l.src] || {}).label || '—') + ' · noch unbearbeitet. Reaktion < 24 h erhöht die Abschlusschance signifikant.',
      cta:'Lead öffnen' });
  });
  leads.filter(l => l.status === 'qual').slice(0, 1).forEach(l => {
    nba.push({ icon:'leads', conf:88, view:'leads', rec:l, action:'convert',
      title:'Lead konvertieren: ' + l.company,
      reason:'Bereits qualifiziert, aber noch kein Account/Opportunity. Konvertieren sichert den Vorgang in der Pipeline.',
      cta:'Konvertieren' });
  });
  opps.filter(o => o.stage === 'neg').map(o => ({ o, d: daysFromToday(o.close) })).sort((a, b) => a.d - b.d).slice(0, 1).forEach(({ o, d }) => {
    nba.push({ icon:'opps', conf:84, view:'opps', rec:o, action:'edit',
      title:'Abschluss vorbereiten: ' + o.name,
      reason:'In Verhandlung · ' + fmtEUR(o.amount) + (o.close ? ' · Close ' + o.close + (d >= 0 ? ' (in ' + d + ' Tagen)' : ' (überfällig)') : '') + '. ' + (o.next || 'Nächsten Schritt einleiten.'),
      cta:'Opportunity öffnen' });
  });
  quotes.filter(q => q.status === 'sent').slice(0, 1).forEach(q => {
    nba.push({ icon:'quotes', conf:77, view:'quotes', rec:q, action:'edit',
      title:'Angebot nachfassen: ' + q.title,
      reason:'Versendet · ' + fmtEUR(quoteTotal(q)) + ' · Kundenreaktion ausstehend. Aktives Nachfassen verkürzt den Sales-Cycle.',
      cta:'Angebot öffnen' });
  });
  opps.filter(o => o.stage === 'qual').sort((a, b) => a.prob - b.prob).slice(0, 1).forEach(o => {
    nba.push({ icon:'opps', conf:63, view:'opps', rec:o, action:'edit',
      title:'Reaktivieren: ' + o.name,
      reason:'Frühe Phase, geringe Wahrscheinlichkeit (' + o.prob + '%). ' + (o.next || 'Kontakt aufnehmen, um Stillstand zu vermeiden.'),
      cta:'Opportunity öffnen' });
  });
  accounts.filter(a => a.tier === 'A' && a.health !== 'g').slice(0, 1).forEach(a => {
    nba.push({ icon:'accounts', conf:60, view:'accounts', rec:a, action:'open',
      title:'Risiko-Account prüfen: ' + a.name,
      reason:'Key Account mit Status ' + (a.health === 'r' ? 'Risiko' : 'Beobachten') + '. Frühzeitige Pflege schützt Bestandsumsatz.',
      cta:'Account öffnen' });
  });

  return nba.sort((a, b) => b.conf - a.conf).slice(0, 4);
}

function NextBestAction({ onAct }) {
  const [ready, setReady] = useS(false);
  useE(() => { const t = setTimeout(() => setReady(true), 700); return () => clearTimeout(t); }, []);
  const items = computeNBA();

  return (
    <div className="nba">
      <div className="nba-hd">
        <span className="nba-badge">{Icons.ai} kiki</span>
        <span className="nba-title">Nächste beste Aktion</span>
        <span className="nba-sub">{ready ? items.length + ' Empfehlungen · priorisiert nach Wirkung' : 'analysiert Pipeline …'}</span>
      </div>
      {!ready ? (
        <div className="nba-loading">
          <span className="nba-shimmer"></span>
          <span className="nba-shimmer"></span>
          <span className="nba-shimmer"></span>
        </div>
      ) : (
        <div className="nba-list">
          {items.map((it, i) => (
            <div key={i} className="nba-item">
              <span className="nba-rank">{i + 1}</span>
              <span className="nba-ic">{Icons[it.icon]}</span>
              <div className="nba-body">
                <b>{it.title}</b>
                <p>{it.reason}</p>
              </div>
              <div className="nba-right">
                <span className="nba-conf" title="Konfidenz">
                  <span className="nba-conf-bar"><span style={{ width: it.conf + '%' }}></span></span>
                  {it.conf}%
                </span>
                <button className="nba-cta" onClick={() => onAct(it)}>{it.cta} →</button>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}
