/* WPSiteBeam Scanner — External Organizations Tab (ISSUE 7)
   Dealers / partners / suppliers / distributors / where-to-buy that a site
   LISTS as their own pages — NOT the scanned business's own locations (those
   live in the Contact tab). The API (`data.external_orgs`) has already filtered
   out anything matching the scanned business, and named the collection from the
   site's OWN vocabulary (label). This tab renders a left-rail entry list ->
   detail panel, with an honest "listed on this site" note so a viewer is never
   misled into thinking these are the business's offices.

   v1.0.0 — 2026-06-18: initial. Left-rail list + detail; site-vocab label;
   honest note; type filter when >1 type; CSV/JSON export; analytics
   (external_orgs.viewed on mount, .entry_viewed on select, .exported on export).
   CSS var() tokens only; WCAG 2.1 AA (tablist/tab roles, aria-selected, focus). */
(function () {
  'use strict';
  const Icon = window.Icon;
  const { useState, useEffect, useMemo } = React;

  function track(eventType, detail) {
    try {
      const token = window.WPSB && window.WPSB.getToken && window.WPSB.getToken();
      if (!token) return;
      const base = (window.WPSBD && window.WPSBD.apiBase) || 'https://api.wpsitebeam.io';
      /* fire-and-forget — analytics must never block or break the surface */
      fetch(base + '/events/track', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + token },
        body: JSON.stringify({ event_type: eventType, detail: detail || {} }),
      }).catch(function () {});
    } catch (_) { /* swallow */ }
  }

  function fullAddress(a) {
    if (!a) return '';
    if (a.full) return a.full;
    const cityState = [a.city, a.state].filter(Boolean).join(', ');
    return [a.street, cityState, a.zip].filter(Boolean).join(' ').replace(/\s+,/g, ',').trim();
  }

  function buildCsv(label, entries) {
    const rows = [['name', 'type', 'street', 'city', 'state', 'zip', 'phones', 'email', 'source_url']];
    entries.forEach(function (e) {
      const a = e.address || {};
      rows.push([
        e.name || '', e.type || label || '', a.street || '', a.city || '', a.state || '', a.zip || '',
        (e.phones || []).join(' / '), e.email || '', e.source_url || '',
      ]);
    });
    return rows.map(function (r) {
      return r.map(function (c) { return '"' + String(c).replace(/"/g, '""') + '"'; }).join(',');
    }).join('\n');
  }

  function ScannerExternalOrgsTab({ data }) {
    const eo = data && data.external_orgs;
    const entries = (eo && Array.isArray(eo.entries)) ? eo.entries : [];
    const label = (eo && eo.label) || 'Partners & Dealers';
    const types = (eo && Array.isArray(eo.types) && eo.types.length > 1) ? eo.types : null;
    const site = (data && data.site) || (data && data.domain) || 'this site';

    const [typeFilter, setTypeFilter] = useState('all');
    const [selectedId, setSelectedId] = useState(entries.length ? entries[0].id : null);

    useEffect(function () {
      track('external_orgs.viewed', { surface: 'scan-report', tab: 'external-orgs', count: entries.length, label: label });
    }, []);

    const shown = useMemo(function () {
      if (!types || typeFilter === 'all') return entries;
      return entries.filter(function (e) { return e.type === typeFilter; });
    }, [typeFilter, entries, types]);

    /* Defensive empty state — the tab is only registered when entries exist. */
    if (!entries.length) {
      return (
        <div style={{ padding: '40px 24px', maxWidth: 600, margin: '0 auto', textAlign: 'center' }}>
          <div style={{ fontSize: '2rem', marginBottom: 12, opacity: .4 }}>🏢</div>
          <div style={{ fontWeight: 700, color: 'var(--text)', marginBottom: 8, fontSize: '.9rem' }}>No external organizations found</div>
          <div style={{ fontSize: '.8rem', color: 'var(--dim)', lineHeight: 1.6 }}>
            This site doesn't appear to list external dealers, partners, suppliers, or distributors as their own pages.
          </div>
        </div>
      );
    }

    const selected = shown.find(function (e) { return e.id === selectedId; }) || shown[0] || null;

    return (
      <div style={{ padding: '4px 2px' }}>
        {/* Header — site-vocabulary label + honest note + count + export */}
        <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap', marginBottom: 12 }}>
          <div style={{ minWidth: 0 }}>
            <div style={{ fontSize: '1rem', fontWeight: 700, color: 'var(--text)' }}>{label}</div>
            <div style={{ fontSize: '.74rem', color: 'var(--dim)', lineHeight: 1.5, marginTop: 4, maxWidth: 560 }}>
              {(eo && eo.note) || ('These are organizations listed on ' + site + ' (not the business own offices).')}
            </div>
            <div style={{ fontSize: '.68rem', color: 'var(--dim)', fontFamily: 'var(--font-mono)', marginTop: 4 }}>
              {entries.length} organization{entries.length !== 1 ? 's' : ''} listed
            </div>
          </div>
          <div style={{ display: 'flex', gap: 6 }}>
            <button className="btn btn-ghost btn-sm"
              onClick={function () { window.wpsbDownload(site + '-external-orgs.csv', buildCsv(label, entries), 'text/csv'); track('external_orgs.exported', { format: 'csv', count: entries.length }); }}>
              {Icon ? <Icon name="download" size={12} /> : null} CSV
            </button>
            <button className="btn btn-ghost btn-sm"
              onClick={function () { window.wpsbDownload(site + '-external-orgs.json', JSON.stringify(entries, null, 2), 'application/json'); track('external_orgs.exported', { format: 'json', count: entries.length }); }}>
              {Icon ? <Icon name="download" size={12} /> : null} JSON
            </button>
          </div>
        </div>

        {/* Type filter — only when the site distinguishes >1 type */}
        {types ? (
          <div role="tablist" aria-label="Organization type filter" style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginBottom: 12 }}>
            {['all'].concat(types).map(function (t) {
              const active = typeFilter === t;
              return (
                <button key={t} role="tab" aria-selected={active} onClick={function () { setTypeFilter(t); }}
                  style={{ all: 'unset', cursor: 'pointer', padding: '5px 12px', borderRadius: 6, fontSize: '.72rem', fontWeight: active ? 600 : 400, color: active ? 'var(--text)' : 'var(--dim)', background: active ? 'var(--beam-dim)' : 'rgba(0,0,0,.15)', border: '1px solid var(--border)' }}>
                  {t === 'all' ? 'All' : t}
                </button>
              );
            })}
          </div>
        ) : null}

        {/* Left rail list + right detail (mirrors the Contact tab pattern) */}
        <div style={{ display: 'flex', gap: 12, alignItems: 'stretch', minHeight: 220 }}>
          <div role="tablist" aria-label="External organizations" style={{ display: 'flex', flexDirection: 'column', gap: 2, minWidth: 170, maxWidth: 230, borderRight: '1px solid var(--border)', paddingRight: 8, maxHeight: 520, overflowY: 'auto' }}>
            {shown.map(function (e) {
              const active = selected && e.id === selected.id;
              const a = e.address || {};
              const sub = [a.city, a.state].filter(Boolean).join(', ') || (e.type || '');
              return (
                <button key={e.id} role="tab" aria-selected={!!active} tabIndex={active ? 0 : -1}
                  onClick={function () { setSelectedId(e.id); track('external_orgs.entry_viewed', { org_id: e.id, org_type: e.type || null }); }}
                  style={{ all: 'unset', cursor: 'pointer', padding: '8px 10px', borderRadius: 5, borderLeft: '2px solid ' + (active ? 'var(--beam, #00C2D1)' : 'transparent'), background: active ? 'var(--beam-dim)' : 'transparent' }}>
                  <div style={{ fontSize: '.76rem', fontWeight: active ? 600 : 500, color: 'var(--text)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{e.name || 'Unnamed organization'}</div>
                  <div style={{ fontSize: '.66rem', color: 'var(--dim)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{sub}</div>
                </button>
              );
            })}
          </div>

          <div style={{ flex: 1, minWidth: 0 }}>
            {selected ? (
              <div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 10, paddingBottom: 8, marginBottom: 10, borderBottom: '1px solid var(--border)' }}>
                  {selected.logo ? <img src={selected.logo} alt={(selected.name || 'organization') + ' logo'} style={{ width: 40, height: 40, objectFit: 'contain', borderRadius: 4, background: 'rgba(0,0,0,.15)' }} /> : null}
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontSize: '.95rem', fontWeight: 700, color: 'var(--text)' }}>{selected.name || 'Unnamed organization'}</div>
                    {selected.type ? <div style={{ fontSize: '.66rem', color: 'var(--dim)', fontFamily: 'var(--font-mono)' }}>{selected.type}</div> : null}
                  </div>
                </div>
                <dl style={{ margin: 0, display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '6px 14px', fontSize: '.78rem', alignItems: 'start' }}>
                  {fullAddress(selected.address) ? [
                    <dt key="ad" style={{ color: 'var(--dim)' }}>Address</dt>,
                    <dd key="av" style={{ margin: 0, color: 'var(--text)' }}>{fullAddress(selected.address)}</dd>,
                  ] : null}
                  {(selected.phones && selected.phones.length) ? [
                    <dt key="pd" style={{ color: 'var(--dim)' }}>Phone</dt>,
                    <dd key="pv" style={{ margin: 0, color: 'var(--text)' }}>{selected.phones.map(function (p, i) { return <span key={i}><a href={'tel:' + p} style={{ color: 'var(--beam, #00C2D1)' }}>{p}</a>{i < selected.phones.length - 1 ? ', ' : ''}</span>; })}</dd>,
                  ] : null}
                  {selected.email ? [
                    <dt key="ed" style={{ color: 'var(--dim)' }}>Email</dt>,
                    <dd key="ev" style={{ margin: 0 }}><a href={'mailto:' + selected.email} style={{ color: 'var(--beam, #00C2D1)' }}>{selected.email}</a></dd>,
                  ] : null}
                  {(selected.geo && typeof selected.geo.lat === 'number') ? [
                    <dt key="gd" style={{ color: 'var(--dim)' }}>Map</dt>,
                    <dd key="gv" style={{ margin: 0 }}><a href={'https://www.google.com/maps?q=' + selected.geo.lat + ',' + selected.geo.lng} target="_blank" rel="noopener noreferrer" style={{ color: 'var(--beam, #00C2D1)' }}>{selected.geo.lat.toFixed(5)}, {selected.geo.lng.toFixed(5)}</a></dd>,
                  ] : null}
                  {selected.source_url ? [
                    <dt key="sd" style={{ color: 'var(--dim)' }}>Source</dt>,
                    <dd key="sv" style={{ margin: 0, overflow: 'hidden' }}><a href={selected.source_url} target="_blank" rel="noopener noreferrer" style={{ color: 'var(--beam, #00C2D1)', wordBreak: 'break-all' }}>{selected.source_url}</a></dd>,
                  ] : null}
                </dl>
              </div>
            ) : null}
          </div>
        </div>
      </div>
    );
  }

  window.ScannerExternalOrgsTab = ScannerExternalOrgsTab;
})();
