/* Page: Local visibility — Google Business Profile monthly performance.
   Source is the monthly report email Google sends the profile manager, parsed
   by api/integrations/gbp-email.js. Named for the question ("where does local
   discovery stand?") rather than the vendor, matching every other route. */

// Google supplies its own month-on-month percentage per metric, so the tile
// renders that rather than recomputing one — recomputing would disagree with
// the figure the client sees in their own inbox.
function GbpTile({ label, value, deltaPct, note }) {
  const cls = deltaPct == null ? 'flat' : deltaPct > 0 ? 'up' : deltaPct < 0 ? 'down' : 'flat';
  const arrow = deltaPct == null ? '' : deltaPct > 0 ? '↑' : deltaPct < 0 ? '↓' : '';
  return (
    <div className="kpi">
      <span className="label">{label}</span>
      <span className="value">{value == null ? '—' : value.toLocaleString()}</span>
      <span className={`delta ${cls}`}>
        {deltaPct == null ? '—' : `${arrow} ${deltaPct > 0 ? '+' : ''}${deltaPct}%`}
      </span>
      <span className="source">{note || 'Business Profile'}</span>
    </div>
  );
}

/* Overview tile: calls placed straight from the Business Profile.
   These never touch the website, so no GA4 configuration can ever record them.
   Showing them beside Conversions is the point — read alone, GA4 undercounts
   real inquiries by however many people simply tapped call on the listing. */
function GbpCallsKpiTile({ client }) {
  // The hook has to run unconditionally (rules of hooks), so gate the request by
  // passing a null path and drop out of the render afterwards.
  const enabled = !!client?.gbp;
  const { data, loading, error } = useApi(
    enabled ? `/api/clients/${client.id}/local-visibility` : null,
    [client?.id, enabled]
  );
  if (!enabled) return null;
  if (loading) {
    return (
      <div className="kpi">
        <span className="label">Calls from Business Profile</span>
        <span className="value">…</span>
        <span className="source">loading</span>
      </div>
    );
  }
  const L = (data && data.configured && data.latest) || null;
  if (error || !L) {
    return (
      <div className="kpi">
        <span className="label">Calls from Business Profile</span>
        <span className="value" style={{color: 'var(--text-dim)'}}>—</span>
        <span className="delta flat">awaiting first sync</span>
        <span className="source">not counted in Conversions</span>
      </div>
    );
  }
  const d = L.deltas?.calls;
  const cls = d == null ? 'flat' : d > 0 ? 'up' : d < 0 ? 'down' : 'flat';
  const [y, mo] = String(L.month).split('-');
  const label = new Date(Number(y), Number(mo) - 1, 1).toLocaleDateString('en-GB', { month: 'short', year: 'numeric' });
  return (
    <div className="kpi">
      <span className="label">Calls from Business Profile</span>
      <span className="value">{(L.calls ?? 0).toLocaleString()}</span>
      <span className={`delta ${cls}`}>
        {d == null ? '—' : `${d > 0 ? '↑ +' : d < 0 ? '↓ ' : ''}${d}% prev mo`}
      </span>
      <span className="source">{label} · not counted in Conversions</span>
    </div>
  );
}

function LocalVisibilityView({ client }) {
  const { data, loading, error } = useApi(`/api/clients/${client.id}/local-visibility`, [client.id]);
  if (loading) return <div className="loading-state">Loading local visibility...</div>;
  if (error) return <div className="error-state">Failed to load local visibility: {error}</div>;
  const D = data || {};

  if (!D.configured) {
    return (
      <>
        <div className="page-head">
          <div>
            <div className="eyebrow gold"><span className="dot"/>Local visibility</div>
            <h1>Local visibility</h1>
            <div className="sub">Calls, direction requests and local searches from the Business Profile.</div>
          </div>
        </div>
        <div className="panel" style={{marginTop: 24, padding: 32, textAlign: 'center'}}>
          <div className="mono-label" style={{marginBottom: 12}}>NOT CONFIGURED</div>
          <p style={{fontSize: 13, color: 'var(--text-muted)', maxWidth: 560, margin: '0 auto', lineHeight: 1.6}}>
            {D.message || <>Add a <span className="mono">gbp</span> block for this client in <span className="mono">api/config/clients.json</span>, then redeploy.</>}
          </p>
        </div>
      </>
    );
  }

  const L = D.latest || {};
  const terms = L.searchTerms || [];
  const discovery = terms.filter(t => !t.brand);
  const brand = terms.filter(t => t.brand);
  const namedTotal = (L.brandSearches || 0) + (L.discoverySearches || 0);
  const discoveryShare = namedTotal ? Math.round((L.discoverySearches / namedTotal) * 100) : null;

  const monthLabel = (m) => {
    if (!m) return '';
    const [y, mo] = m.split('-');
    return new Date(Number(y), Number(mo) - 1, 1)
      .toLocaleDateString('en-GB', { month: 'long', year: 'numeric' });
  };

  return (
    <>
      <div className="page-head">
        <div>
          <div className="eyebrow gold"><span className="dot"/>Business Profile · {D.profileName || client?.name}</div>
          <h1>Local visibility</h1>
          {/* Interactions leads the sub rather than taking a tile: it is the sum of
              the three action tiles, so as a tile it both orphaned the grid row and
              double-counted what was already beside it. */}
          <div className="sub">
            {monthLabel(L.month)} · <strong>{(L.interactions ?? 0).toLocaleString()} interactions</strong> —
            calls, direction requests and website visits, against the month before.
          </div>
        </div>
      </div>

      <div className="kpi-grid">
        <GbpTile label="Calls" value={L.calls} deltaPct={L.deltas?.calls}/>
        <GbpTile label="Direction requests" value={L.directionRequests} deltaPct={L.deltas?.directionRequests}/>
        <GbpTile label="Website visits from profile" value={L.websiteClicks} deltaPct={L.deltas?.websiteClicks}/>
        <GbpTile label="Profile views" value={L.profileViews} deltaPct={L.deltas?.profileViews}/>
        <GbpTile label="Searches" value={L.searches} deltaPct={L.deltas?.searches}/>
      </div>

      <div className="panel" style={{marginTop: 24}}>
        <div className="panel-head">
          <h3>How people searched</h3>
          <span className="sub">{monthLabel(L.month)}</span>
        </div>
        <div className="panel-body" style={{padding: '18px 20px'}}>
          {/* The split is the whole point of this panel: searches for the firm's
              own name prove nothing about reach, discovery searches do. */}
          <div style={{display: 'flex', gap: 28, flexWrap: 'wrap', marginBottom: 16}}>
            <div>
              <div className="mono-label">DISCOVERY</div>
              <div style={{fontSize: 26, fontWeight: 600}}>{(L.discoverySearches || 0).toLocaleString()}</div>
              <div style={{fontSize: 12, color: 'var(--text-muted)'}}>
                found them without knowing the name{discoveryShare != null ? ` · ${discoveryShare}% of named terms` : ''}
              </div>
            </div>
            <div>
              <div className="mono-label">BRAND</div>
              <div style={{fontSize: 26, fontWeight: 600}}>{(L.brandSearches || 0).toLocaleString()}</div>
              <div style={{fontSize: 12, color: 'var(--text-muted)'}}>searched the firm name or address</div>
            </div>
          </div>

          <table className="table">
            <thead><tr><th>Search term</th><th>Type</th><th className="num">Searches</th></tr></thead>
            <tbody>
              {terms.map((t, i) => (
                <tr key={i}>
                  <td><span className="mono" style={{color: 'var(--text)'}}>{t.term}</span></td>
                  <td>
                    <span className="tag" style={t.brand ? undefined : {color: 'var(--gold)'}}>
                      {t.brand ? 'BRAND' : 'DISCOVERY'}
                    </span>
                  </td>
                  <td className="num">{t.count.toLocaleString()}</td>
                </tr>
              ))}
              {!terms.length && <tr><td colSpan={3} style={{color: 'var(--text-dim)'}}>No search terms reported.</td></tr>}
            </tbody>
          </table>

          {/* Stated on the page, not just in the code: Google names only the top
              handful of terms and suppresses the low-volume tail, so these
              numbers are a sample and must never be read as the month's total. */}
          <p style={{fontSize: 11, color: 'var(--text-dim)', marginTop: 12, lineHeight: 1.6}}>
            Google names only its top search terms and withholds low-volume ones, so this is a
            sample of the month rather than every search. The {(L.searches || 0).toLocaleString()} figure
            above is the full count.
          </p>
        </div>
      </div>

      <div className="panel" style={{marginTop: 16}}>
        <div className="panel-head">
          <h3>Month by month</h3>
          <span className="sub">{(D.months || []).length} month{(D.months || []).length === 1 ? '' : 's'} on record</span>
        </div>
        <div className="panel-body" style={{padding: 0}}>
          <table className="table">
            <thead>
              <tr>
                <th>Month</th>
                <th className="num">Calls</th>
                <th className="num">Directions</th>
                <th className="num">Website</th>
                <th className="num">Interactions</th>
                <th className="num">Profile views</th>
                <th className="num">Searches</th>
              </tr>
            </thead>
            <tbody>
              {[...(D.months || [])].reverse().map((m, i) => (
                <tr key={i}>
                  <td>{monthLabel(m.month)}</td>
                  <td className="num">{(m.calls ?? 0).toLocaleString()}</td>
                  <td className="num">{(m.directionRequests ?? 0).toLocaleString()}</td>
                  <td className="num">{(m.websiteClicks ?? 0).toLocaleString()}</td>
                  <td className="num">{(m.interactions ?? 0).toLocaleString()}</td>
                  <td className="num">{(m.profileViews ?? 0).toLocaleString()}</td>
                  <td className="num">{(m.searches ?? 0).toLocaleString()}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </>
  );
}
