// ============================================================================
//  Global Contact Database — matching engine + Returning Customer Alert card
//  Stores = showrooms; the cross-showroom set IS the global directory.
//  Store users never browse it; it is queried silently on search / new contact / new lead.
//  The summary card is READ-ONLY and shows NO financial values.
// ============================================================================

// --- fuzzy helpers ---
function _lev(a, b) {
  a = a || ''; b = b || '';
  const m = a.length, n = b.length;
  if (!m) return n; if (!n) return m;
  let prev = Array.from({ length: n + 1 }, (_, i) => i);
  for (let i = 1; i <= m; i++) {
    const cur = [i];
    for (let j = 1; j <= n; j++) {
      cur[j] = Math.min(prev[j] + 1, cur[j - 1] + 1, prev[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1));
    }
    prev = cur;
  }
  return prev[n];
}
function _sim(a, b) {
  if (!a || !b) return 0;
  return 1 - _lev(a, b) / Math.max(a.length, b.length);
}
function _normPhone(p) { return (p || '').toString().replace(/\D/g, '').replace(/^61/, '0'); }
function _normAddr(s) {
  return (s || '').toLowerCase()
    .replace(/\b(unit|apt|apartment|street|st|road|rd|avenue|ave|drive|dr|court|ct|lane|ln|place|pl|terrace|tce)\b/g, ' ')
    .replace(/[^a-z0-9 ]/g, ' ').replace(/\s+/g, ' ').trim();
}
function _addrSim(a, b) {
  const ta = a.split(' ').filter(Boolean);
  const tb = new Set(b.split(' ').filter(Boolean));
  if (!ta.length || !tb.size) return 0;
  const inter = ta.filter(t => tb.has(t)).length;
  return inter / Math.max(ta.length, tb.size);
}

// Weighted match against the global directory.
// phone: exact (100%) · email: 80% fuzzy · address: 60% partial · name: 40% fuzzy.
// A phone match alone is sufficient; otherwise ≥2 fields must meet their thresholds.
window.matchGlobalContacts = function (allContacts, q, excludeId) {
  const name = (q.name || '').toLowerCase().trim();
  const phone = _normPhone(q.phone);
  const email = (q.email || '').toLowerCase().trim();
  const address = _normAddr(q.address);
  if (!name && !phone && !email && !address) return [];

  const out = [];
  for (const c of (allContacts || [])) {
    if (excludeId && c.id === excludeId) continue;
    const cName = (c.name || '').toLowerCase().trim();
    const cPhone = _normPhone(c.phone);
    const cEmail = (c.email || '').toLowerCase().trim();
    const cAddr = _normAddr(c.address);

    const f = {}; // matched field → normalized confidence (0..1)
    if (phone && cPhone && phone.length >= 8 && phone === cPhone) f.phone = 1;
    if (email && cEmail) { const s = _sim(email, cEmail); if (s >= 0.8) f.email = s; }
    if (address && cAddr) { const s = _addrSim(address, cAddr); if (s >= 0.6) f.address = s; }
    if (name && cName) {
      const s = _sim(name, cName);
      const sLast = name.split(' ').slice(-1)[0], cLast = cName.split(' ').slice(-1)[0];
      const surnameHit = sLast.length > 2 && sLast === cLast;
      if (s >= 0.4 || surnameHit) f.name = Math.max(s, surnameHit ? 0.5 : 0);
    }

    const matched = Object.keys(f);
    const ok = f.phone === 1 || matched.length >= 2; // phone alone OR ≥2 fields
    if (!ok) continue;
    const confidence = f.phone === 1
      ? 100
      : Math.round(matched.reduce((s, k) => s + f[k], 0) / matched.length * 100);
    out.push({ contact: c, fields: f, matched, confidence });
  }
  return out.sort((a, b) => b.confidence - a.confidence).slice(0, 4);
};

// Build a NO-FINANCIALS interaction history for the summary card.
window.contactInteractions = function (c, allDeals, showrooms) {
  const deals = (allDeals || []).filter(d => (c.dealIds || []).includes(d.id));
  const storeName = (id) => (showrooms || []).find(s => s.id === id)?.name || id;
  const items = [];
  // Initial network contact
  if (c.firstContact) items.push({ type: 'Contact Only', store: storeName(c.homeShowroom), date: c.firstContact });
  deals.forEach(d => {
    const type = d.stage === 'sold' ? 'Completed Job' : 'Quote';
    items.push({ type, store: storeName(d.showroom), date: d.created || d.lastActivity || '' });
  });
  items.sort((a, b) => (a.date || '').localeCompare(b.date || ''));
  const stores = [...new Set(items.map(i => i.store).filter(Boolean))];
  return {
    items,
    first: items[0]?.date || c.firstContact || '',
    recent: items.length ? items[items.length - 1].date : (c.lastContact || ''),
    count: items.length,
    stores,
  };
};

// Returning Customer Alert — read-only summary card(s). No dollar values anywhere.
function CustomerLookup({ allContacts, allDeals, showrooms, name, phone, email, address, onMerge, excludeId }) {
  const matches = React.useMemo(
    () => window.matchGlobalContacts(allContacts, { name, phone, email, address }, excludeId),
    [allContacts, name, phone, email, address, excludeId]
  );
  if (matches.length === 0) return null;

  const fmtD = (d) => d ? (window.fmt ? fmt.shortDate(d) : d) : '—';
  const typeColor = { 'Completed Job': 'var(--won)', 'Quote': 'var(--accent)', 'Contact Only': 'var(--ink-3)' };

  return (
    <div style={{
      background: 'var(--surface)', border: '1.5px solid var(--accent)', borderRadius: 'var(--r-lg)',
      marginTop: 12, overflow: 'hidden', boxShadow: 'var(--shadow-md)',
    }}>
      <div style={{ background: 'var(--accent-soft)', padding: '9px 13px', display: 'flex', alignItems: 'center', gap: 8 }}>
        <Icon name="alert" size={14} color="var(--accent-ink)"/>
        <span style={{ fontSize: 12, fontWeight: 600, color: 'var(--accent-ink)' }}>
          Returning Customer Alert — this customer has existing records in the network
        </span>
      </div>

      <div style={{ padding: '4px 0' }}>
        {matches.map(m => {
          const c = m.contact;
          const ix = window.contactInteractions(c, allDeals, showrooms);
          return (
            <div key={c.id} style={{ padding: '12px 14px', borderBottom: '1px solid var(--border)' }}>
              <div style={{ display: 'flex', alignItems: 'flex-start', gap: 10 }}>
                <Avatar name={c.name} sz="sm"/>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                    <span style={{ fontWeight: 600, fontSize: 13 }}>{c.name}</span>
                    <span style={{
                      fontSize: 10.5, fontWeight: 600, padding: '1px 6px', borderRadius: 4,
                      background: m.confidence >= 100 ? 'var(--won-soft)' : 'var(--surface-3)',
                      color: m.confidence >= 100 ? 'oklch(0.35 0.1 155)' : 'var(--ink-2)',
                    }}>
                      {m.confidence}% match · {m.matched.join(', ')}
                    </span>
                  </div>
                  <div style={{ fontSize: 11.5, color: 'var(--ink-3)', marginTop: 2, display: 'flex', gap: 12, flexWrap: 'wrap' }} className="mono">
                    {c.phone && <span>{c.phone}</span>}
                    {c.email && <span>{c.email}</span>}
                  </div>

                  {/* Allowed fields only — NO financials */}
                  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '6px 12px', marginTop: 9 }}>
                    <Field label="First seen" value={fmtD(ix.first)}/>
                    <Field label="Most recent" value={fmtD(ix.recent)}/>
                    <Field label="Interactions" value={String(ix.count)}/>
                  </div>

                  <div style={{ marginTop: 9 }}>
                    <div style={{ fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.06em', color: 'var(--ink-3)', fontWeight: 600, marginBottom: 5 }}>Network history</div>
                    <div style={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
                      {ix.items.slice(-5).map((it, i) => (
                        <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 11.5 }}>
                          <span style={{ width: 6, height: 6, borderRadius: 3, background: typeColor[it.type] || 'var(--ink-3)', flexShrink: 0 }}></span>
                          <span style={{ fontWeight: 500, minWidth: 92 }}>{it.type}</span>
                          <span style={{ color: 'var(--ink-3)' }}>{it.store}</span>
                          <span style={{ color: 'var(--ink-4)', marginLeft: 'auto' }} className="mono">{fmtD(it.date)}</span>
                        </div>
                      ))}
                    </div>
                  </div>

                  {onMerge && (
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 11 }}>
                      <span style={{ fontSize: 11, color: 'var(--ink-3)' }}>Is this the same person?</span>
                      <button className="btn sm primary" style={{ marginLeft: 'auto' }} onClick={(e) => { e.preventDefault(); onMerge(c); }}>
                        <Icon name="check" size={11}/> Yes — use these details
                      </button>
                    </div>
                  )}
                </div>
              </div>
            </div>
          );
        })}
      </div>

      <div style={{ padding: '7px 13px', fontSize: 10, color: 'var(--ink-3)', fontStyle: 'italic', background: 'var(--surface-2)' }}>
        Read-only summary from the global directory · no account or financial data shown · confirm before proceeding
      </div>
    </div>
  );
}

function Field({ label, value }) {
  return (
    <div>
      <div style={{ fontSize: 9.5, textTransform: 'uppercase', letterSpacing: '0.05em', color: 'var(--ink-3)', fontWeight: 600 }}>{label}</div>
      <div style={{ fontSize: 12.5, fontWeight: 500, marginTop: 1 }}>{value}</div>
    </div>
  );
}

window.CustomerLookup = CustomerLookup;
