// Avg session duration is stored as seconds but the value tile reads better in
// m:ss. KPI's generic decimal formatter can't do that, so this thin wrapper
// renders the formatted display while still leaning on KPI's delta-chip logic
// for prev-mo / prev-yr (which compare the raw seconds).
function AvgDurationTile({ data, fallback }) {
  if (!data || data.value == null) {
    return (
      <div className="kpi">
        <span className="label">Avg session duration</span>
        <span className="value">{fallback || '—'}</span>
        <span className="source">GA4</span>
      </div>
    );
  }
  const fmt = (s) => `${Math.floor(s / 60)}:${String(Math.floor(s % 60)).padStart(2, '0')}`;
  const renderDelta = (d, label) => {
    if (d == null) return null;
    const arrow = d > 0 ? '↑' : d < 0 ? '↓' : '';
    const sign = d > 0 ? '+' : '';
    const cls = d === 0 ? 'flat' : (d > 0 ? 'up' : 'down');
    return <span className={`delta-row ${cls}`}>{arrow} {label} {sign}{d.toFixed(1)}s</span>;
  };
  return (
    <div className="kpi">
      <span className="label">Avg session duration</span>
      <span className="value">{fmt(data.value)}</span>
      <div className="delta-stack">
        {renderDelta(data.mom, 'prev mo')}
        {renderDelta(data.yoy, 'prev yr')}
      </div>
      {data.source && <span className="source">{data.source}</span>}
    </div>
  );
}

/* Shown when the Google token is present but expired/revoked (reauthRequired).
   Honest, non-alarming, actionable — rankings + backlinks are unaffected. */
function GoogleReauthNotice({ label }) {
  return (
    <>
      <div className="page-head">
        <div>
          <div className="eyebrow gold"><span className="dot"/>{label}</div>
          <h1>Reconnect Google to load this</h1>
          <div className="sub">The dashboard's Google connection expired. Keyword rankings and backlinks are unaffected — they do not use Google sign-in.</div>
        </div>
      </div>
      <div className="panel" style={{marginTop: 16}}>
        <div className="panel-body" style={{padding: '28px', display:'flex', flexDirection:'column', gap:14, alignItems:'flex-start'}}>
          <p style={{fontSize:13, color:'var(--text-muted)', lineHeight:1.6, maxWidth:560}}>
            {label} data comes from Google. The saved access expired, so this view is paused until it is reconnected. One reconnect restores it instantly — no data is lost.
          </p>
          <button className="btn btn-primary"
                  onClick={() => window.open(`${window.API_BASE}/auth/google/init`, '_blank', 'width=600,height=760')}>
            <Icon name="refresh" size={13}/> Reconnect Google
          </button>
          <span className="mono" style={{fontSize:11, color:'var(--text-dim)'}}>
            Sign in as the account with access (ragaburn@gmail.com), approve read-only Analytics + Search Console, then reload this page.
          </span>
        </div>
      </div>
    </>
  );
}

/* Page: GSC Search Performance */
function GscView({ client, range }) {
  // Pass-through to backend parseDateRange (handles month:YYYY-MM + legacy '7d'/'30d'/etc).
  const rangeParam = range || '28d';
  const { data, loading, error } = useApi(`/api/clients/${client.id}/gsc?range=${encodeURIComponent(rangeParam)}`, [client.id, rangeParam]);
  if (loading) return <div className="loading-state">Loading search performance...</div>;
  if (error) return <div className="error-state">Failed to load GSC data: {error}</div>;
  const D = data || {};
  if (D.reauthRequired) return <GoogleReauthNotice label="Google Search Console" />;
  return (
    <>
      <div className="page-head">
        <div>
          <div className="eyebrow gold"><span className="dot"/>Google Search Console · {client?.gscDomain || '—'}</div>
          <h1>Search performance</h1>
          <div className="sub">Clicks, impressions, CTR, and average position from GSC. Top queries + landing pages from the live API.</div>
        </div>
        <div className="actions">
          <a className="btn btn-secondary" href={`https://search.google.com/search-console?resource_id=${encodeURIComponent(client?.gscDomain || '')}`} target="_blank" rel="noreferrer">
            <Icon name="ext" size={13}/> Open in GSC
          </a>
        </div>
      </div>

      <div className="kpi-grid" style={{gridTemplateColumns: 'repeat(4, 1fr)'}}>
        <KPI label="Clicks"        {...(D.kpis?.clicks || {})}/>
        <KPI label="Impressions"   {...(D.kpis?.impressions || {})}/>
        <KPI label="CTR"           {...(D.kpis?.ctr || {})}/>
        <KPI label="Avg position"  {...(D.kpis?.position || {})}/>
      </div>

      <div className="panel" style={{marginTop: 24}}>
        <div className="panel-head">
          <h3>Clicks · daily</h3>
          <span className="sub">{D.periodLabel || rangeParam}</span>
        </div>
        <div className="panel-body" style={{padding: '12px 8px 4px'}}>
          <TrendChart current={(D.daily || []).map(d => d.clicks)} previous={[]} dates={(D.daily || []).map(d => d.date)}/>
        </div>
      </div>

      <div className="row-2" style={{marginTop: 16}}>
        <div className="panel">
          <div className="panel-head"><h3>Top queries</h3><span className="sub">{D.periodLabel || rangeParam}</span></div>
          <div className="panel-body" style={{padding: 0}}>
            <table className="table">
              <thead><tr><th>Query</th><th className="num">Clicks</th><th className="num">Imps</th><th className="num">CTR</th><th className="num">Pos</th></tr></thead>
              <tbody>
                {(D.queries || []).slice(0, 25).map((q, i) => (
                  <tr key={i}>
                    <td><span style={{color:'var(--text)'}}>{q.query}</span></td>
                    <td className="num mono">{(q.clicks || 0).toLocaleString()}</td>
                    <td className="num mono">{(q.impressions || 0).toLocaleString()}</td>
                    <td className="num">
                      <div className="bar-cell">
                        <span className="bar green"><span style={{width: `${Math.min(100, (q.ctr || 0) * 10)}%`}}/></span>
                        <span className="mono">{(q.ctr || 0).toFixed(1)}%</span>
                      </div>
                    </td>
                    <td className="num"><span className={`pos-chip ${(q.position || 0) <= 3 ? 'top3' : (q.position || 0) <= 10 ? 'top10' : 'top30'}`}>{(q.position || 0).toFixed(1)}</span></td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>

        <div className="panel">
          <div className="panel-head"><h3>Top landing pages</h3><span className="sub">{D.periodLabel || rangeParam}</span></div>
          <div className="panel-body" style={{padding: 0}}>
            <table className="table">
              <thead><tr><th>URL</th><th className="num">Clicks</th><th className="num">Imps</th><th className="num">Pos</th></tr></thead>
              <tbody>
                {(D.pages || []).slice(0, 25).map((p, i) => {
                  const short = (p.url || '').replace(/^https?:\/\/[^/]+/, '') || '/';
                  return (
                    <tr key={i}>
                      <td><span className="mono" style={{fontSize: 11, color:'var(--text)', wordBreak:'break-all'}}>{short}</span></td>
                      <td className="num mono">{(p.clicks || 0).toLocaleString()}</td>
                      <td className="num mono">{(p.impressions || 0).toLocaleString()}</td>
                      <td className="num"><span className={`pos-chip ${(p.position || 0) <= 3 ? 'top3' : (p.position || 0) <= 10 ? 'top10' : 'top30'}`}>{(p.position || 0).toFixed(1)}</span></td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </>
  );
}
window.GscView = GscView;

/* Page: GA4 Traffic & engagement */
function Ga4View({ client, range }) {
  // Pass-through to backend parseDateRange (handles month:YYYY-MM + legacy '7d'/'30d'/etc).
  const rangeParam = range || '30d';
  const { data, loading, error } = useApi(`/api/clients/${client.id}/ga4?range=${encodeURIComponent(rangeParam)}`, [client.id, rangeParam]);
  if (loading) return <div className="loading-state">Loading traffic data...</div>;
  if (error) return <div className="error-state">Failed to load GA4 data: {error}</div>;
  const D = data || {};
  if (D.reauthRequired) return <GoogleReauthNotice label="Traffic & engagement (GA4)" />;
  return (
    <>
      <div className="page-head">
        <div>
          <div className="eyebrow gold"><span className="dot"/>GA4 · property {client?.ga4PropertyId || '—'}</div>
          <h1>Traffic & engagement</h1>
          <div className="sub">Sessions, users, channel mix, and conversions for the selected reporting period.</div>
        </div>
      </div>

      <div className="kpi-grid">
        <KPI label="Sessions" {...(D.kpis?.sessions || {})}/>
        <KPI label="Users"    {...(D.kpis?.users || {})}/>
        <KPI label="Engaged rate" {...(D.kpis?.engagedRate || {})}/>
        <AvgDurationTile data={D.kpis?.avgSessionDuration} fallback={D.summary?.avgSessionDurationFormatted}/>
        <KPI label="Conversions" {...(D.kpis?.conversions || {})}/>
      </div>

      <div className="row-2" style={{marginTop: 24}}>
        <div className="panel">
          <div className="panel-head"><h3>Sessions by channel</h3><span className="sub">Daily · {D.periodLabel || rangeParam}</span></div>
          <div className="panel-body" style={{padding: '12px 8px 4px'}}>
            <TrendChart current={D.traffic || []} previous={[]} height={220} dates={D.trafficDates || []}/>
          </div>
        </div>
        <div className="panel">
          <div className="panel-head"><h3>Channel mix</h3></div>
          <div className="panel-body" style={{display:'flex', gap: 18, alignItems: 'center'}}>
            <Donut data={D.channels || []} size={180} total={(D.channels || []).reduce((a,c) => a + c.value, 0)}/>
            <div style={{flex: 1, display:'flex', flexDirection:'column', gap: 8}}>
              {(D.channels || []).map((c, i) => (
                <div key={i} style={{display:'flex', alignItems:'center', gap: 8, fontSize: 12}}>
                  <span style={{width: 8, height: 8, borderRadius: 2, background: ['var(--gold)','var(--text)','var(--accent)','var(--gold-light)','var(--text-muted)','var(--text-dim)'][i]}}/>
                  <span style={{flex: 1, color: 'var(--text)'}}>{c.name}</span>
                  <span className="mono num" style={{color: 'var(--text-dim)'}}>{c.share.toFixed(1)}%</span>
                  <span className={`delta-chip ${c.delta >= 0 ? 'up' : 'down'}`} style={{minWidth: 50, justifyContent:'flex-end'}}>
                    {c.delta >= 0 ? '+' : ''}{c.delta.toFixed(1)}%
                  </span>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>

      <div className="row-2" style={{marginTop: 16}}>
        <div className="panel">
          <div className="panel-head"><h3>Top landing pages</h3><span className="sub">Organic only · {D.periodLabel || rangeParam}</span></div>
          <div className="panel-body" style={{padding: 0}}>
            <table className="table">
              <thead><tr><th>Page</th><th className="num">Sessions</th><th className="num">Engaged</th><th className="num">Conv</th><th className="num">Conv rate</th></tr></thead>
              <tbody>
                {(D.pages || []).slice(0, 6).map((p, i) => (
                  <tr key={i}>
                    <td>
                      <div className="cell-stack">
                        <span className="lead">{p.url}</span>
                        <span className="meta mono-label" style={{fontSize:9}}>ORGANIC</span>
                      </div>
                    </td>
                    <td className="num mono">{p.sessions.toLocaleString()}</td>
                    <td className="num">
                      <div className="bar-cell"><span className="bar green"><span style={{width: `${Math.round((p.engagedSessions / Math.max(p.sessions,1)) * 100)}%`}}/></span><span className="mono">{Math.round((p.engagedSessions / Math.max(p.sessions,1)) * 100)}%</span></div>
                    </td>
                    <td className="num mono">{p.conversions}</td>
                    <td className="num mono">{p.sessions > 0 ? ((p.conversions / p.sessions) * 100).toFixed(1) : '0.0'}%</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </div>
        <div className="panel">
          <div className="panel-head"><h3>Conversions by event</h3><span className="sub">GA4 · {D.periodLabel || rangeParam}</span></div>
          <div className="panel-body">
            {(D.conversions || []).length === 0 ? (
              <div className="dim" style={{fontSize: 12, padding: 12}}>No key events configured in GA4 yet.</div>
            ) : (
              <HBar items={(D.conversions || []).slice(0, 5).map((cv, i) => ({
                label: cv.event.toUpperCase().replace(/_/g, ' '),
                value: cv.conversions,
                color: ['var(--gold)','var(--accent)','var(--gold-light)','var(--text-muted)','var(--text-dim)'][i],
              }))} max={Math.max(1, ...(D.conversions || []).slice(0,5).map(cv => cv.conversions))} format={v => v.toString()}/>
            )}
          </div>
        </div>
      </div>
    </>
  );
}
window.Ga4View = Ga4View;

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

  // Backend sets configured=false when AHREFS_API_KEY is missing or no client.ahrefsTarget.
  if (!D.configured) {
    return (
      <>
        <div className="page-head">
          <div>
            <div className="eyebrow gold"><span className="dot"/>Backlinks</div>
            <h1>Backlinks</h1>
            <div className="sub">Referring domain growth, DR distribution, top referring sites.</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: 520, margin: '0 auto', lineHeight: 1.6}}>
            {D.message || (
              <>Backlinks data needs DataForSEO credentials + per-client target. Add <span className="mono">DATAFORSEO_LOGIN</span> and <span className="mono">DATAFORSEO_PASSWORD</span> to the server env vars and set <span className="mono">dataforseoDomain</span> in <span className="mono">api/config/clients.json</span>, then redeploy.</>
            )}
          </p>
        </div>
      </>
    );
  }

  return (
    <>
      <div className="page-head">
        <div>
          <div className="eyebrow gold"><span className="dot"/>DataForSEO · {client?.dataforseoDomain || client?.ahrefsTarget || ''}</div>
          <h1>Backlinks</h1>
          <div className="sub">Referring domain growth and top referring sites from DataForSEO.</div>
        </div>
      </div>

      <div className="kpi-grid">
        <div className="kpi"><span className="label">Domain rating</span><span className="value">{D.overview?.domainRating ?? '—'}</span><span className="delta flat">—</span><span className="source">DataForSEO</span></div>
        <div className="kpi"><span className="label">Referring domains</span><span className="value">{(D.overview?.referringDomains ?? 0).toLocaleString()}</span><span className="delta flat">—</span><span className="source">DataForSEO</span></div>
        <div className="kpi"><span className="label">Backlinks</span><span className="value">{(D.overview?.backlinks ?? 0).toLocaleString()}</span><span className="delta flat">—</span><span className="source">DataForSEO</span></div>
      </div>

      <div className="panel" style={{marginTop: 24}}>
        <div className="panel-head"><h3>Referring domains · growth</h3><span className="sub">90d</span></div>
        <div className="panel-body" style={{padding: '12px 8px 4px'}}>
          <TrendChart current={(D.history || []).map(h => h.refdomains)} previous={[]} height={220} dates={(D.history || []).map(h => h.date)}/>
        </div>
      </div>

      <div className="panel" style={{marginTop: 16}}>
        <div className="panel-head">
          <h3>Top referring domains</h3>
          <span className="sub">Sorted by DR</span>
        </div>
        <div className="panel-body" style={{padding: 0}}>
          <table className="table">
            <thead><tr><th>Domain</th><th className="num">DR</th><th className="num">Links</th><th className="num">Dofollow</th><th>First seen</th></tr></thead>
            <tbody>
              {(D.domains || []).map((d, i) => (
                <tr key={i}>
                  <td>
                    <div style={{display:'flex', alignItems:'center', gap: 10}}>
                      <Icon name="globe" size={14} color="var(--text-dim)"/>
                      <span className="mono" style={{color:'var(--text)'}}>{d.domain}</span>
                    </div>
                  </td>
                  <td className="num">
                    <div className="bar-cell">
                      <span className="bar"><span style={{width: `${d.domainRating}%`}}/></span>
                      <span className="mono">{d.domainRating}</span>
                    </div>
                  </td>
                  <td className="num mono">{d.links}</td>
                  <td className="num mono">{d.dofollow}</td>
                  <td className="mono" style={{fontSize: 11, color:'var(--text-muted)'}}>{d.firstSeen}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </div>
    </>
  );
}
window.BacklinksView = BacklinksView;

/* Page: Settings / integrations */
function GoogleAccountsPanel() {
  const { useState } = React;
  const [version, setVersion] = useState(0);
  const { data: accounts, loading } = useApi('/api/google/accounts', [version]);

  function fmtDate(ts) {
    if (!ts) return '—';
    // updated_at is an ISO string (e.g. "2026-06-28T..."); tolerate a unix-seconds
    // number/string from any older rows. parseInt on an ISO string yielded the
    // year (e.g. 2026) → *1000 → Jan 1970, which is the bug this guards against.
    const d = typeof ts === 'number' ? new Date(ts)
            : /^\d+$/.test(String(ts)) ? new Date(parseInt(ts, 10) * 1000)
            : new Date(ts);
    return isNaN(d.getTime()) ? '—' : d.toLocaleString();
  }

  function fmtExpiry(ms) {
    if (!ms) return '—';
    const days = Math.floor((ms - Date.now()) / 86400000);
    if (days < 0) return 'expired';
    if (days === 0) return '<1 day';
    return `${days}d`;
  }

  function connectNew() {
    window.open(`${window.API_BASE}/auth/google/init`, '_blank', 'width=600,height=700');
    // Refresh after assumed flow completion
    setTimeout(() => setVersion(v => v + 1), 30000);
  }

  function disconnect(email) {
    if (!confirm(`Disconnect ${email}? The dashboard will lose access to GA4/GSC properties this account reads.`)) return;
    fetch(`${window.API_BASE}/api/google/accounts/${encodeURIComponent(email)}`, {
      method: 'DELETE',
      headers: { Authorization: `Bearer ${window.__GE_API_KEY__ || ''}` }
    }).then(() => setVersion(v => v + 1));
  }

  return (
    <div className="panel" style={{ marginBottom: 16 }}>
      <div className="panel-head" style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <h3>Connected Google accounts</h3>
        <button className="btn btn-primary" onClick={connectNew}>
          <Icon name="plus" size={12} />
          Connect Google account
        </button>
      </div>
      <div className="panel-body" style={{ paddingTop: 8 }}>
        {loading && <div style={{ fontSize: 12, color: 'var(--text-muted)' }}>Loading…</div>}
        {!loading && (!accounts || accounts.length === 0) && (
          <div style={{ fontSize: 13, color: 'var(--text-muted)', padding: '12px 0' }}>
            No Google accounts connected yet. Click <strong>Connect Google account</strong> above and grant analytics + search-console read access.
          </div>
        )}
        {accounts && accounts.length > 0 && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
            {accounts.map(a => (
              <div key={a.email} style={{
                display: 'flex', alignItems: 'center', gap: 12,
                padding: '10px 12px', borderRadius: 6,
                border: '1px solid var(--border-light)',
                background: 'var(--surface)'
              }}>
                <div style={{
                  width: 32, height: 32, borderRadius: 8,
                  background: 'var(--gold-dim)', color: 'var(--gold)',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  fontFamily: 'var(--font-mono)', fontSize: 11, fontWeight: 600,
                  flexShrink: 0
                }}>G</div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontSize: 13, color: 'var(--text)', fontWeight: 500 }}>{a.email}</div>
                  <div className="mono-label" style={{ fontSize: 9, marginTop: 2 }}>
                    UPDATED {fmtDate(a.updated_at)} · TOKEN {fmtExpiry(a.expires_at)}
                  </div>
                </div>
                <span className="status ok"><span className="dot" />Active</span>
                <button className="btn-ghost" onClick={() => disconnect(a.email)}>Disconnect</button>
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}

function SettingsView({ client }) {
  const { data: health } = useApi('/api/sync/health', []);
  const { data: googleAccounts } = useApi('/api/google/accounts', []);
  const recentSyncs = health?.recentSyncs || [];
  const googleConnected = Array.isArray(googleAccounts) && googleAccounts.length > 0;

  function getStatus(code) {
    // GA4 + GSC are read live via the shared Google OAuth account (not synced into
    // a table), so their status follows whether a Google account is connected.
    if (code === 'GA4' || code === 'GSC') return googleConnected ? 'connected' : 'available';
    const hit = recentSyncs.find(s => s.client_id === client?.id && s.integration === code.toLowerCase());
    if (!hit) return 'available';
    // The sync logger writes 'success' (not 'ok'); treat both as healthy.
    return (hit.status === 'ok' || hit.status === 'success') ? 'connected' : 'error';
  }

  function getLastSync(code) {
    const hit = recentSyncs.find(s => s.client_id === client?.id && s.integration === code.toLowerCase());
    if (!hit || !hit.synced_at) return null;
    // synced_at is an ISO timestamp string; tolerate a unix-seconds number too.
    const ms = typeof hit.synced_at === 'number' ? hit.synced_at * 1000 : Date.parse(hit.synced_at);
    if (!ms) return null;
    const age = Math.floor((Date.now() - ms) / 1000);
    return age < 3600 ? `${Math.round(age/60)}m ago`
         : age < 86400 ? `${Math.round(age/3600)}h ago`
         : `${Math.round(age/86400)}d ago`;
  }

  const sources = [
    { name: 'Google Analytics 4',   code: 'GA4',     desc: 'Sessions, users, conversions, attribution.' },
    { name: 'Google Search Console',code: 'GSC',     desc: 'Queries, pages, clicks, impressions, position.' },
    { name: 'Ahrefs',               code: 'AHREFS',  desc: 'Backlinks, referring domains, domain rating.' },
    { name: 'Semrush',              code: 'SEMRUSH', desc: 'Keyword positions, visibility, SERP features.' },
    { name: 'Google Ads',           code: 'ADS',     desc: 'Paid campaigns, keywords, conversions.',        future: true },
    { name: 'Meta Ads',             code: 'META',    desc: 'Paid social campaigns, audiences, ROAS.',       future: true },
    { name: 'Looker Studio',        code: 'LOOKER',  desc: 'Embed live tiles into client portals.' },
    { name: 'CallRail',             code: 'CALLRAIL',desc: 'Call tracking attributed to keyword + page.' },
  ].map(s => ({
    ...s,
    status: getStatus(s.code),
    prop: recentSyncs.find(r => r.client_id === client?.id && r.integration === s.code.toLowerCase())?.integration || null,
    sync: getLastSync(s.code),
  }));

  return (
    <>
      <div className="page-head">
        <div>
          <div className="eyebrow gold"><span className="dot"/>Workspace · {client?.name || 'Client'}</div>
          <h1>Integrations</h1>
          <div className="sub">Connect data sources once per client. Tokens are encrypted and refreshed automatically. PPC and Paid Social sources will activate when those channels launch.</div>
        </div>
      </div>

      <GoogleAccountsPanel />

      <div className="row-2">
        <div style={{display:'flex', flexDirection:'column', gap: 10}}>
          {sources.map((s, i) => (
            <div key={i} className="panel" style={{padding: '16px 18px', display:'flex', alignItems:'center', gap: 14}}>
              <div style={{
                width: 44, height: 44, borderRadius: 8,
                background: s.status === 'connected' ? 'var(--gold-dim)' : 'var(--surface)',
                border: '1px solid var(--border)',
                display:'flex', alignItems:'center', justifyContent:'center',
                fontFamily:'var(--font-mono)', fontSize: 9, letterSpacing: '0.1em',
                color: s.status === 'connected' ? 'var(--gold)' : 'var(--text-muted)',
                flexShrink: 0,
              }}>{s.code}</div>
              <div style={{flex: 1, minWidth: 0}}>
                <div style={{display:'flex', alignItems:'center', gap: 8}}>
                  <span style={{fontSize: 14, color:'var(--text)', fontWeight: 500}}>{s.name}</span>
                  {s.future && <span className="serp-badge">PPC · soon</span>}
                </div>
                <div style={{fontSize: 12, color:'var(--text-muted)', marginTop: 2}}>{s.desc}</div>
                {s.sync && (
                  <div className="mono-label" style={{fontSize: 9, marginTop: 6}}>
                    {s.code} · SYNCED {s.sync}
                  </div>
                )}
              </div>
              {s.status === 'connected' || s.status === 'error' ? (
                <>
                  <span className={`status ${s.status === 'connected' ? 'ok' : 'err'}`}><span className="dot"/>{s.status === 'connected' ? 'Connected' : 'Error'}</span>
                  <span className="mono-label" style={{fontSize: 9, opacity: 0.5}} title="Disconnect via the Google accounts panel above">manage in panel</span>
                </>
              ) : (s.code === 'GA4' || s.code === 'GSC') ? (
                <button className="btn btn-secondary" onClick={() => window.open(`${window.API_BASE}/auth/google/init`, '_blank', 'width=600,height=700')}>
                  <Icon name="plus" size={12}/>Connect Google
                </button>
              ) : (
                <button className="btn btn-secondary" disabled title="Integration not yet built" style={{opacity: 0.5, cursor: 'not-allowed'}}>
                  <Icon name="plus" size={12}/>Coming soon
                </button>
              )}
            </div>
          ))}
        </div>

        <div style={{display:'flex', flexDirection:'column', gap: 10}}>
          <div className="panel">
            <div className="panel-head"><h3>Workspace defaults</h3></div>
            <div className="panel-body" style={{display:'flex', flexDirection:'column', gap: 14, fontSize: 13}}>
              <Field label="Default reporting period" value="Last 30 days"/>
              <Field label="Compare to" value="Previous period"/>
              <Field label="Country" value="Philippines"/>
              <Field label="Device" value="Desktop"/>
              <Field label="Currency" value="PHP ₱"/>
              <Field label="Time zone" value="Asia / Manila"/>
            </div>
          </div>

          <div className="panel">
            <div className="panel-head"><h3>Client portal access</h3></div>
            <div className="panel-body" style={{fontSize: 13, color: 'var(--text-muted)', lineHeight: 1.6}}>
              <p>No client users have been invited to this workspace yet. The invite flow is not yet built — for now, sign-in is internal-only.</p>
              <button className="btn btn-secondary" disabled title="Client invite flow not yet built" style={{marginTop: 14, opacity: 0.5, cursor: 'not-allowed'}}>
                <Icon name="plus" size={12}/>Invite client user (soon)
              </button>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

function Field({ label, value }) {
  return (
    <div style={{display:'flex', alignItems:'center', justifyContent:'space-between', padding: '6px 0', borderBottom:'1px solid var(--border-light)'}}>
      <span className="mono-label">{label}</span>
      <span style={{color:'var(--text)'}}>{value}</span>
    </div>
  );
}

window.SettingsView = SettingsView;
