/*
 * GeoVisibility.jsx — GEO / AI-Visibility PROPOSAL SNAPSHOT block (P0, surface 1).
 * _GEO-VISIBILITY-ENGINE-SPEC.md Section 6 — the proposal-surface UX.
 *
 * v1.0.0 — 2026-06-18 (P0 proposal snapshot; tracker upsell is a later slice).
 * v1.0.1 — 2026-06-18 (503 GEO_SOURCE_UNAVAILABLE now renders an explicit
 *          "measurement unavailable" state, never a 0/N score or empty table
 *          — Radical Transparency: a no-data-source 503 must not read as a false zero).
 *
 * Endpoint: POST /geo/snapshot (requireJWT wpsb-app + enforceSubscriptionActive).
 * Renders the deterministic result the API returns:
 *   - Headline: "Visible in N of M measurable AI engines" + computed score.
 *   - Per-prompt table: prompt / engine / citation vs mention vs absent.
 *   - Competitor line (only when the API actually measured a compared domain).
 *   - CEDE-gated narrative summary (API-supplied; never invented client-side).
 *   - CTA -> recurring tracker upsell ("GEO Visibility, $49/mo").
 *   - Honesty footer: data source + 2-7 day lag + engines measured.
 *
 * RADICAL TRANSPARENCY (app CLAUDE.md rule #13b): we render ONLY engines the
 * payload reports measured. NEVER render an engine as 0 when it was simply not
 * measured. Coverage + data-lag are labelled, not hidden.
 *
 * Standalone module (Design Standards 7-point compliance):
 *   - Self-contained .jsx with IIFE wrapper + window namespace + version log
 *   - CSS variables only (var(--text/dim/panel/border) + brand semantics)
 *   - Mobile responsive (matchMedia stack)
 *   - WCAG 2.1 AA contrast + aria labels + keyboard
 *   - React.createElement throughout (no JSX); pure ASCII (no backticks/specials)
 *   - Generic placeholder only (example.com)
 */
(function () {
  'use strict';

  var React = window.React;
  var useState = React.useState, useEffect = React.useEffect;
  var e = React.createElement;
  var tx = function (k, v, f) { return (window.WPSB && window.WPSB.t) ? window.WPSB.t(k, v, f) : (f != null ? f : k); };

  function apiBase() {
    return (window.WPSBD && window.WPSBD.apiBase) ||
           window.WPSB_API_BASE ||
           (window.WPSB && window.WPSB.RAILWAY) ||
           'https://api.wpsitebeam.io';
  }
  function getToken() {
    try { return (window.WPSB && window.WPSB.getToken && window.WPSB.getToken()) || null; }
    catch (_) { return null; }
  }

  /* mention_type -> visual treatment (CSS vars only; no semantic hex). */
  function badgeFor(type) {
    if (type === 'citation') return { label: tx('page.geo.badge_cited', null, 'Cited'), color: 'var(--green)', bg: 'rgba(0,0,0,.15)' };
    if (type === 'mention')  return { label: tx('page.geo.badge_mentioned', null, 'Mentioned'), color: 'var(--beam, var(--accent, var(--text)))', bg: 'rgba(0,0,0,.15)' };
    return { label: tx('page.geo.badge_absent', null, 'Absent'), color: 'var(--dim)', bg: 'rgba(0,0,0,.15)' };
  }

  function Badge(props) {
    var b = badgeFor(props.type);
    return e('span', {
      style: {
        display: 'inline-block', padding: '2px 8px', borderRadius: 999, fontSize: '.72rem',
        fontWeight: 700, color: b.color, background: b.bg, border: '1px solid var(--border)',
        whiteSpace: 'nowrap',
      },
    }, b.label);
  }

  function GeoVisibility(props) {
    var initialDomain = (props && props.domain) || '';
    var autoRun = !!(props && props.autoRun);

    var st = useState('idle'); var status = st[0], setStatus = st[1];   // idle|running|done|error|unavailable
    var dd = useState(null);   var data = dd[0],   setData = dd[1];
    var ee = useState('');     var err = ee[0],    setErr = ee[1];
    var ec = useState('');     var errCode = ec[0], setErrCode = ec[1];  // last non-ok response code (e.g. GEO_SOURCE_UNAVAILABLE)
    var di = useState(initialDomain); var domain = di[0], setDomain = di[1];
    var mm = useState(window.matchMedia ? window.matchMedia('(max-width: 700px)').matches : false);
    var narrow = mm[0], setNarrow = mm[1];

    useEffect(function () {
      if (!window.matchMedia) return;
      var mq = window.matchMedia('(max-width: 700px)');
      var fn = function () { setNarrow(mq.matches); };
      if (mq.addEventListener) mq.addEventListener('change', fn); else mq.addListener(fn);
      return function () { if (mq.removeEventListener) mq.removeEventListener('change', fn); else mq.removeListener(fn); };
    }, []);

    function run() {
      var d = (domain || '').trim();
      if (!d) { setErr(tx('page.geo.err_enter_domain', null, 'Enter a domain to check.')); setStatus('error'); return; }
      var token = getToken();
      if (!token) { setErr(tx('page.geo.err_sign_in', null, 'Sign in to run an AI-visibility snapshot.')); setStatus('error'); return; }
      setStatus('running'); setErr('');
      fetch(apiBase() + '/geo/snapshot', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + token },
        body: JSON.stringify({ domain: d }),
      }).then(function (r) {
        return r.json().then(function (j) { return { ok: r.ok, status: r.status, j: j }; });
      }).then(function (res) {
        if (!res.ok || !res.j || res.j.ok === false) {
          var code = res.j && res.j.code;
          // GEO_SOURCE_UNAVAILABLE (503, no DFS creds) is NOT a transient error and is
          // NEVER a measurement of "0 of N engines" — render it as an explicit
          // "measurement unavailable" state, never a zero score or empty results table
          // (a false zero would violate Radical Transparency).
          if (code === 'GEO_SOURCE_UNAVAILABLE') { setErrCode(code); setStatus('unavailable'); return; }
          var msg = (res.j && res.j.error) ||
            (res.status === 503 ? tx('page.geo.err_503', null, 'AI-visibility lookup is temporarily unavailable. Please retry shortly.') :
             res.status === 402 ? tx('page.geo.err_402', null, 'Your subscription is inactive. Reactivate your plan to continue.') :
             tx('page.geo.err_snapshot_failed', null, 'Snapshot failed.'));
          setErr(msg + (code ? ' (' + code + ')' : '')); setStatus('error'); return;
        }
        setData(res.j); setStatus('done');
      }).catch(function () {
        setErr(tx('page.geo.err_network', null, 'Network error running the snapshot. Please retry.')); setStatus('error');
      });
    }

    useEffect(function () { if (autoRun && initialDomain && status === 'idle') run(); }, []); // eslint-disable-line

    /* ── header ── */
    var header = e('div', { style: { display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap', marginBottom: 6 } },
      e('h3', { style: { margin: 0, fontSize: '1rem', fontWeight: 800, color: 'var(--text)' } }, tx('page.geo.title', null, 'GEO / AI Visibility')),
      e('span', { style: { fontSize: '.72rem', color: 'var(--dim)', fontWeight: 600 } }, tx('page.geo.subtitle', null, 'How AI search engines see this site'))
    );

    /* ── run row ── */
    var runRow = e('div', { style: { display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center', marginBottom: 12 } },
      e('label', { htmlFor: 'geo-domain', style: { position: 'absolute', width: 1, height: 1, overflow: 'hidden', clip: 'rect(0 0 0 0)' } }, tx('page.geo.domain_label', null, 'Domain')),
      e('input', {
        id: 'geo-domain', type: 'text', value: domain, placeholder: 'example.com',
        onChange: function (ev) { setDomain(ev.target.value); },
        onKeyDown: function (ev) { if (ev.key === 'Enter') run(); },
        style: {
          flex: '1 1 200px', minWidth: 0, padding: '8px 10px', borderRadius: 8,
          border: '1px solid var(--border)', background: 'rgba(0,0,0,.15)', color: 'var(--text)', fontSize: '.85rem',
        },
      }),
      e('button', {
        onClick: run, disabled: status === 'running',
        style: {
          padding: '8px 16px', borderRadius: 8, border: '1px solid var(--border)', cursor: status === 'running' ? 'default' : 'pointer',
          background: 'var(--beam, var(--accent, var(--surface)))', color: 'var(--text)', fontWeight: 700, fontSize: '.85rem', minHeight: 40,
        },
      }, status === 'running' ? tx('page.geo.btn_checking', null, 'Checking AI engines...') : tx('page.geo.btn_run', null, 'Run AI-visibility snapshot'))
    );

    var children = [header, runRow];

    if (status === 'error') {
      children.push(e('div', {
        role: 'alert',
        style: { padding: '10px 12px', borderRadius: 8, border: '1px solid var(--border)', borderLeft: '4px solid var(--warn)', background: 'rgba(0,0,0,.15)', color: 'var(--text)', fontSize: '.85rem' },
      }, err));
    }

    /* Explicit "measurement unavailable" state — the honest render of a 503
       GEO_SOURCE_UNAVAILABLE. NOT an error alert and NEVER a 0/N score or empty
       results table: the AI-visibility data source isn't connected, so there is
       simply nothing measured to show (a false zero would mislead). */
    if (status === 'unavailable') {
      children.push(e('div', {
        role: 'status',
        style: { padding: '12px 14px', borderRadius: 12, border: '1px solid var(--border)', borderLeft: '4px solid var(--dim)', background: 'rgba(0,0,0,.15)', color: 'var(--text)', fontSize: '.85rem', lineHeight: 1.5 },
      },
        e('div', { style: { fontWeight: 700, marginBottom: 4 } }, tx('page.geo.unavailable_title', null, 'AI-visibility measurement is not available right now')),
        e('div', { style: { color: 'var(--dim)' } },
          tx('page.geo.unavailable_body1', null, 'The AI-visibility data source is not connected for this workspace yet, so there are no engines to measure. '),
          tx('page.geo.unavailable_body2', null, 'This is not a zero result - nothing was measured. Connect a data source (or add your own key) to run a snapshot.'))
      ));
    }

    if (status === 'idle') {
      children.push(e('div', { style: { fontSize: '.82rem', color: 'var(--dim)', lineHeight: 1.5 } },
        tx('page.geo.idle_body1', null, 'Run a one-time snapshot of how AI search engines answer buyer questions about this site. '),
        tx('page.geo.idle_body2', null, 'Shows where the site is cited, merely mentioned, or absent across the AI engines we can measure.')));
    }

    if (status === 'done' && data) {
      var cov = data.engines_covered || {};
      var measured = cov.engines_measured || 0;
      var visible = cov.engines_visible || 0;
      var engines = cov.engines || [];
      var score = (data.score == null) ? null : data.score;

      /* headline */
      var headline = e('div', {
        style: { display: 'flex', alignItems: 'center', gap: 16, flexWrap: 'wrap', padding: '14px 16px', borderRadius: 12, border: '1px solid var(--border)', background: 'rgba(0,0,0,.15)', marginBottom: 12 },
      },
        e('div', { style: { textAlign: 'center', minWidth: 84 } },
          e('div', { style: { fontSize: '2rem', fontWeight: 800, color: 'var(--text)', lineHeight: 1 } }, score == null ? '--' : String(score)),
          e('div', { style: { fontSize: '.66rem', color: 'var(--dim)', fontWeight: 700, letterSpacing: '.04em' } }, tx('page.geo.score_label', null, 'VISIBILITY SCORE'))
        ),
        e('div', { style: { flex: '1 1 200px', minWidth: 0 } },
          e('div', { style: { fontSize: '1.05rem', fontWeight: 700, color: 'var(--text)' } },
            measured > 0
              ? (measured === 1
                  ? tx('page.geo.visible_in_one', { visible: visible, measured: measured }, 'Visible in {visible} of {measured} measurable AI engine')
                  : tx('page.geo.visible_in_many', { visible: visible, measured: measured }, 'Visible in {visible} of {measured} measurable AI engines'))
              : tx('page.geo.no_engine_data', null, 'No measurable AI-engine data yet')),
          measured > 0 ? e('div', { style: { fontSize: '.78rem', color: 'var(--dim)', marginTop: 2 } },
            tx('page.geo.measured_list', { engines: engines.join(', ') }, 'Measured: {engines}')) : null
        )
      );

      /* per-prompt table */
      var mentions = data.mentions || [];
      var tableEl;
      if (mentions.length === 0) {
        tableEl = e('div', { style: { fontSize: '.82rem', color: 'var(--dim)', padding: '8px 0' } },
          tx('page.geo.no_rows', null, 'No per-prompt rows returned by the measured engines for this run.'));
      } else if (narrow) {
        tableEl = e('div', { style: { display: 'flex', flexDirection: 'column', gap: 8 } },
          mentions.map(function (m, i) {
            return e('div', { key: i, style: { padding: '8px 10px', borderRadius: 8, border: '1px solid var(--border)', background: 'rgba(0,0,0,.15)' } },
              e('div', { style: { fontSize: '.82rem', color: 'var(--text)', fontWeight: 600, marginBottom: 4 } }, m.prompt || tx('page.geo.prompt_fallback', null, '(prompt)')),
              e('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 8 } },
                e('span', { style: { fontSize: '.76rem', color: 'var(--dim)' } }, m.engine),
                e(Badge, { type: m.mention_type })
              )
            );
          })
        );
      } else {
        tableEl = e('table', { style: { width: '100%', borderCollapse: 'collapse', fontSize: '.82rem' } },
          e('thead', null, e('tr', { style: { textAlign: 'left', color: 'var(--dim)' } },
            e('th', { scope: 'col', style: { padding: '6px 8px', fontWeight: 700 } }, tx('page.geo.col_prompt', null, 'Prompt')),
            e('th', { scope: 'col', style: { padding: '6px 8px', fontWeight: 700 } }, tx('page.geo.col_engine', null, 'AI engine')),
            e('th', { scope: 'col', style: { padding: '6px 8px', fontWeight: 700 } }, tx('page.geo.col_result', null, 'Result'))
          )),
          e('tbody', null, mentions.map(function (m, i) {
            return e('tr', { key: i, style: { borderTop: '1px solid var(--border)' } },
              e('td', { style: { padding: '6px 8px', color: 'var(--text)' } }, m.prompt || tx('page.geo.prompt_fallback', null, '(prompt)')),
              e('td', { style: { padding: '6px 8px', color: 'var(--dim)' } }, m.engine),
              e('td', { style: { padding: '6px 8px' } }, e(Badge, { type: m.mention_type }))
            );
          }))
        );
      }

      var tableWrap = e('div', { style: { marginBottom: 12 } },
        e('div', { style: { fontSize: '.74rem', color: 'var(--dim)', fontWeight: 700, marginBottom: 6, letterSpacing: '.03em' } }, tx('page.geo.per_prompt_detail', null, 'PER-PROMPT DETAIL')),
        tableEl);
      children.push(headline, tableWrap);

      /* competitor line (only when measured) */
      if (data.competitor && data.competitor.top_competitor) {
        var c = data.competitor;
        children.push(e('div', {
          style: { padding: '10px 12px', borderRadius: 8, border: '1px solid var(--border)', background: 'rgba(0,0,0,.15)', fontSize: '.85rem', color: 'var(--text)', marginBottom: 12 },
        },
          e('strong', null, tx('page.geo.competitor_you', { visible: (c.you ? c.you.visible : 0), measured: (c.you ? c.you.measured || measured : measured) }, 'You: {visible} of {measured}')),
          tx('page.geo.competitor_vs', null, '  vs  '),
          e('strong', null, tx('page.geo.competitor_other', { visible: c.top_competitor.visible, measured: (c.top_competitor.measured || measured) }, 'a compared domain: {visible} of {measured}'))
        ));
      }

      /* narrative summary (API-supplied, CEDE-gated) */
      if (data.summary) {
        children.push(e('div', {
          style: { padding: '12px 14px', borderRadius: 12, border: '1px solid var(--border)', borderLeft: '4px solid var(--beam, var(--accent, var(--border)))', background: 'rgba(0,0,0,.15)', marginBottom: 12 },
        },
          e('p', { style: { margin: 0, fontSize: '.86rem', lineHeight: 1.55, color: 'var(--text)' } }, data.summary)
        ));
      }

      /* CTA -> recurring tracker upsell */
      children.push(e('div', {
        style: { display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'center', justifyContent: 'space-between', padding: '12px 14px', borderRadius: 12, border: '1px solid var(--border)', background: 'rgba(0,0,0,.15)', marginBottom: 12 },
      },
        e('div', { style: { fontSize: '.85rem', color: 'var(--text)', flex: '1 1 220px' } },
          e('strong', null, tx('page.geo.cta_title', null, 'Track and improve this every week.')),
          tx('page.geo.cta_body', null, ' GEO Visibility watches these AI engines on a weekly cadence so you can show the trend improve.')),
        e('button', {
          onClick: function () {
            if (props && props.onUpsell) props.onUpsell();
            else if (window.wpsbToast) window.wpsbToast(tx('page.geo.cta_toast', null, 'GEO Visibility tracker is $49/mo - coming with the recurring slice.'), 'beam');
          },
          style: { padding: '8px 16px', borderRadius: 8, border: '1px solid var(--border)', cursor: 'pointer', background: 'var(--beam, var(--accent, var(--surface)))', color: 'var(--text)', fontWeight: 700, fontSize: '.82rem', minHeight: 40 },
        }, tx('page.geo.cta_button', null, 'GEO Visibility - $49/mo'))
      ));

      /* honesty footer (Radical Transparency) */
      var lag = data.data_lag_days || cov.data_lag_days || [2, 7];
      children.push(e('div', {
        style: { fontSize: '.72rem', color: 'var(--dim)', lineHeight: 1.5, borderTop: '1px solid var(--border)', paddingTop: 8 },
      },
        tx('page.geo.footer_source', { source: (data.source || cov.source || 'DataForSEO AI Optimization API') }, 'Data source: {source}. '),
        tx('page.geo.footer_lag', { min: lag[0], max: lag[1] }, 'Figures reflect a {min}-{max} day data lag (not real-time). '),
        tx('page.geo.footer_shown', { suffix: (measured > 0 ? (' (' + engines.join(', ') + ')') : '') }, 'Only AI engines we can currently measure are shown{suffix}; '),
        tx('page.geo.footer_omitted', null, 'engines we do not yet measure are omitted rather than shown as zero.')
      ));
    }

    return e('section', {
      'aria-label': 'GEO AI Visibility',
      style: { padding: '16px', borderRadius: 14, border: '1px solid var(--border)', background: 'var(--surface)' },
    }, children);
  }

  window.GeoVisibility = GeoVisibility;
  window.WPSB = window.WPSB || {};
  window.WPSB.GeoVisibility = GeoVisibility;
  console.log('[WPSB] GeoVisibility v1.0.1 loaded (P0 proposal snapshot; Section 6 UX; explicit measurement-unavailable state)');
})();
