// ─── Shared helpers for the functional CRM app ───────────────
// Loaded first. Defines top-level constants/components used by the
// leads / accounts / opps view files and the shell.

const { useState: useS, useEffect: useE, useMemo: useM } = React;

// Re-render on any store change
function useStore() {
  const [, force] = useS(0);
  useE(() => CRMStore.subscribe(() => force(n => n + 1)), []);
  useE(() => ViewerStore.sub(() => force(n => n + 1)), []);
}

// ─── Viewer / role scope ──────────────────────────────────────
const VIEWERS = [
  { id:'boss', label:'Vertriebsleitung — alle Datensätze', boss:true },
  { id:'JS', label:'Julia Schmidt', boss:false },
  { id:'TR', label:'Tobias Reinhardt', boss:false },
  { id:'SK', label:'Sarah Kohl', boss:false }
];
const ViewerStore = {
  id: 'boss', subs: new Set(),
  isBoss() { return this.id === 'boss'; },
  set(v) { this.id = v; this.subs.forEach(f => f()); },
  sub(fn) { this.subs.add(fn); return () => this.subs.delete(fn); }
};
window.ViewerStore = ViewerStore;
// Filter a list to the active viewer (boss sees all; reps see only their own)
function scopeOwner(list) { return ViewerStore.id === 'boss' ? list : list.filter(r => r.owner === ViewerStore.id); }

const OWNERS = {
  JS: 'Julia Schmidt',
  TR: 'Tobias Reinhardt',
  SK: 'Sarah Kohl'
};
const OWNER_OPTS = [['JS','Julia Schmidt'],['TR','Tobias Reinhardt'],['SK','Sarah Kohl']];

const STAGE_META = {
  qual:  { label:'Qualify',   cls:'qual'  },
  disc:  { label:'Discover',  cls:'qual'  },
  prop:  { label:'Propose',   cls:'prop'  },
  neg:   { label:'Negotiate', cls:'neg'   },
  close: { label:'Closing',   cls:'neg'   },
  won:   { label:'Won',       cls:'close' },
  lost:  { label:'Lost',      cls:'lost'  }
};
const STAGE_OPTS = [['qual','Qualify · 20%'],['disc','Discover · 40%'],['prop','Propose · 60%'],['neg','Negotiate · 80%'],['close','Closing · 95%'],['won','Won · 100%'],['lost','Lost']];

const SRC_META = {
  snap: { label:'snapADDY',     cls:'snap' },
  sv:   { label:'Salesviewer',  cls:'sv'   },
  web:  { label:'Web-Formular', cls:'web'  },
  ref:  { label:'Empfehlung',   cls:'web'  },
  field:{ label:'Außendienst',  cls:'web'  },
  cold: { label:'Kaltakquise',  cls:'web'  }
};
const LEAD_SRC_OPTS = [['snap','snapADDY (Messe)'],['sv','Salesviewer (Web-Tracking)'],['web','Web-Formular'],['ref','Empfehlung'],['cold','Kaltakquise']];

const LEAD_STATUS = {
  new:  { label:'New',       cls:'new'  },
  work: { label:'Working',   cls:'work' },
  qual: { label:'Qualified', cls:'qual' },
  conv: { label:'Converted', cls:'conv' }
};

function fmtEUR(n) {
  const v = Number(n) || 0;
  if (v >= 1000) return '€ ' + Math.round(v / 1000) + 'k';
  return '€ ' + v.toLocaleString('de-DE');
}
function fmtEURfull(n) { return '€ ' + (Number(n) || 0).toLocaleString('de-DE'); }
function initials(s) { return (s || '?').trim().slice(0, 2).toUpperCase(); }

// ─── Modal shell ──────────────────────────────────────────────
function Modal({ title, sub, onClose, children, footer, wide }) {
  useE(() => {
    const h = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', h);
    return () => window.removeEventListener('keydown', h);
  }, []);
  return (
    <div className="cmodal-scrim" onMouseDown={onClose}>
      <div className={"cmodal" + (wide ? " wide" : "")} onMouseDown={e => e.stopPropagation()}>
        <div className="cmodal-hd">
          <div>
            <h2>{title}</h2>
            {sub && <p>{sub}</p>}
          </div>
          <button className="cmodal-x" onClick={onClose} aria-label="Schließen">✕</button>
        </div>
        <div className="cmodal-body">{children}</div>
        {footer && <div className="cmodal-foot">{footer}</div>}
      </div>
    </div>
  );
}

// ─── Form primitives ──────────────────────────────────────────
function Field({ label, hint, req, full, children }) {
  return (
    <div className={"form-field" + (full ? " full" : "")}>
      <label className="form-label">{label} {req && <span className="req" />} {hint && <span className="hint">{hint}</span>}</label>
      {children}
    </div>
  );
}
function TextInput({ value, onChange, placeholder, type }) {
  return <input className="form-input" type={type || 'text'} value={value || ''} placeholder={placeholder || ''} onChange={e => onChange(e.target.value)} />;
}
function Select({ value, onChange, options }) {
  return (
    <select className="form-select" value={value} onChange={e => onChange(e.target.value)}>
      {options.map(o => <option key={o[0]} value={o[0]}>{o[1]}</option>)}
    </select>
  );
}
function TextArea({ value, onChange, placeholder }) {
  return <textarea className="form-textarea" value={value || ''} placeholder={placeholder || ''} onChange={e => onChange(e.target.value)} />;
}

// ─── Confirm dialog ───────────────────────────────────────────
function Confirm({ text, confirmLabel, danger, onConfirm, onCancel }) {
  return (
    <Modal title="Bestätigen" onClose={onCancel}
      footer={<>
        <button className="btn ghost" onClick={onCancel}>Abbrechen</button>
        <button className={"btn" + (danger ? " danger" : "")} onClick={onConfirm}>{confirmLabel || 'OK'}</button>
      </>}>
      <p style={{margin:0, fontSize:14, lineHeight:1.55, color:'var(--ink-2)'}}>{text}</p>
    </Modal>
  );
}

// ─── List toolbar (search + tabs) ─────────────────────────────
function Toolbar({ q, onQ, placeholder, tabs, tab, onTab, right }) {
  return (
    <div className="lv-toolbar">
      <div className="lv-search">{Icons.search}<input placeholder={placeholder} value={q} onChange={e => onQ(e.target.value)} /></div>
      {tabs && (
        <div className="lv-tabs">
          {tabs.map(t => (
            <button key={t[0]} className={"lv-tab" + (tab === t[0] ? " active" : "")} onClick={() => onTab(t[0])}>{t[1]}<span className="c">{t[2]}</span></button>
          ))}
        </div>
      )}
      {right}
    </div>
  );
}

// ─── Toast (lightweight, self-dismissing) ─────────────────────
let __toastSet = null;
function ToastHost() {
  const [msg, setMsg] = useS(null);
  __toastSet = setMsg;
  useE(() => {
    if (!msg) return;
    const t = setTimeout(() => setMsg(null), 3200);
    return () => clearTimeout(t);
  }, [msg]);
  if (!msg) return null;
  return <div className="ctoast">{Icons.check2 || '✓'} <span>{msg}</span></div>;
}
function toast(m) { if (__toastSet) __toastSet(m); }

// ─── Sortable table helpers ───────────────────────────────────
function applySort(rows, sort, valOf) {
  if (!sort || !sort.key) return rows;
  return rows.slice().sort((a, b) => { const va = valOf(a, sort.key), vb = valOf(b, sort.key); return (va < vb ? -1 : va > vb ? 1 : 0) * sort.dir; });
}
function SortTh({ k, label, cls, sort, setSort }) {
  return <th className={cls} style={{ cursor:'pointer', whiteSpace:'nowrap' }} onClick={() => setSort(s => s.key === k ? { key:k, dir:-s.dir } : { key:k, dir:1 })}>{label}{sort.key === k ? (sort.dir === 1 ? ' ▲' : ' ▼') : ''}</th>;
}
