import React, { useState, useEffect } from 'react';
import { clickup as clickupApi, gsc as gscApi } from './lib/api';
import { gsc } from './lib/api';
import { useSiteData } from './hooks/useSiteData';
import MetricsRow from './components/MetricsRow';
import KeywordTracker from './components/KeywordTracker';
import TasksKanban from './components/TasksKanban';
import SheetsPanel from './components/SheetsPanel';
import DateRangePicker from './components/DateRangePicker';
import SiteSettings, { loadSiteFolderIds } from './components/SiteSettings';
import TeamPanel from './components/TeamPanel';
import ThemePicker, { initTheme } from './components/ThemePicker';
import KpiTracker from './components/KpiTracker';
import FolderGroupTasks from './components/FolderGroupTasks';

// Init saved theme on load
initTheme();

const SITE_COLORS = ['#378ADD','#1D9E75','#D85A30','#7F77DD','#BA7517','#D4537E','#0F6E56','#854F0B','#993C1D','#534AB7'];

const TABS = [
  { key: 'overview',  label: 'Overview'          },
  { key: 'keywords',  label: 'Keyword positions'  },
  { key: 'traffic',   label: 'Traffic & history'  },
  { key: 'backlinks', label: 'Backlinks'           },
  { key: 'tasks',     label: 'ClickUp tasks'       },
  { key: 'sheets',    label: 'Google Sheets'       },
  { key: 'kpi',       label: 'KPI pages'            },
  { key: 'team',      label: 'Team & Projects'     },
];

function DRBadge({ dr }) {
  if (dr == null) return null;
  const color = dr >= 70 ? 'var(--green-text)' : dr >= 40 ? 'var(--amber-text)' : 'var(--text2)';
  const bg    = dr >= 70 ? 'var(--green-bg)'   : dr >= 40 ? 'var(--amber-bg)'   : 'var(--surface2)';
  return <span style={{ fontSize: 11, fontWeight: 500, padding: '2px 7px', borderRadius: 5, background: bg, color }}>DR {dr}</span>;
}

function PosBadge({ pos }) {
  if (!pos && pos !== 0) return null;
  const p = parseFloat(pos);
  const cls = p <= 3 ? 'p13' : p <= 10 ? 'p410' : p <= 20 ? 'p1120' : 'p20p';
  return <span className={`pbadge ${cls}`}>#{Math.round(p)}</span>;
}

function fmt(n) {
  if (n == null) return '—';
  if (n >= 1000000) return (n / 1000000).toFixed(1) + 'M';
  if (n >= 1000) return (n / 1000).toFixed(0) + 'K';
  return String(n);
}

function OverviewCard({ label, value, highlight }) {
  return (
    <div className="metric-card">
      <div className="metric-label">{label}</div>
      <div className="metric-value" style={highlight ? { color: 'var(--blue-text)' } : {}}>{value ?? '—'}</div>
    </div>
  );
}

// ── Traffic chart (GSC daily history) ─────────────────────────
import { Line } from 'react-chartjs-2';
import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Tooltip, Filler } from 'chart.js';
ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Tooltip, Filler);

const chartOpts = {
  responsive: true, maintainAspectRatio: false,
  plugins: { legend: { display: false }, tooltip: { mode: 'index', intersect: false } },
  scales: {
    x: { grid: { display: false }, ticks: { font: { size: 10 }, maxTicksLimit: 12, color: '#888' } },
    y: { grid: { color: 'rgba(128,128,128,0.1)' }, ticks: { font: { size: 10 }, color: '#888' } },
  },
};

function TrafficHistoryChart({ history, loading, days }) {
  if (loading) return <div className="skeleton" style={{ height: 160, borderRadius: 8 }} />;
  if (!history?.length) return <p style={{ fontSize: 12, color: 'var(--text2)', padding: '16px 0' }}>No history data available.</p>;
  // Show only the selected period
  const slice = history.slice(-Math.ceil(days / (history.length > 60 ? 7 : 1)));
  const d = {
    labels: slice.map(r => r.date?.slice(5)),
    datasets: [{
      label: 'Clicks', data: slice.map(r => r.clicks ?? r.organicTraffic ?? 0),
      borderColor: '#378ADD', backgroundColor: '#378ADD18', fill: true, tension: 0.4, pointRadius: 0, borderWidth: 1.5,
    }],
  };
  return <div style={{ height: 160 }}><Line data={d} options={chartOpts} /></div>;
}

function ImpressionsChart({ history, loading, days }) {
  if (loading) return <div className="skeleton" style={{ height: 140, borderRadius: 8 }} />;
  if (!history?.length) return null;
  const slice = history.slice(-Math.ceil(days / (history.length > 60 ? 7 : 1)));
  const d = {
    labels: slice.map(r => r.date?.slice(5)),
    datasets: [{
      label: 'Impressions', data: slice.map(r => r.impressions ?? 0),
      borderColor: '#1D9E75', backgroundColor: '#1D9E7518', fill: true, tension: 0.4, pointRadius: 0, borderWidth: 1.5,
    }],
  };
  return <div style={{ height: 140 }}><Line data={d} options={chartOpts} /></div>;
}

// ── Compact team summary for Overview tab ─────────────────────
function TeamSummary({ folderIds, onViewAll }) {
  const [data, setData] = React.useState(null);
  React.useEffect(() => {
    clickupApi.teamOverview(folderIds)
      .then(setData).catch(() => setData(null));
  }, [folderIds]);
  if (!data) return null;
  const { members, totals } = data;
  if (!members?.length) return null;
  return (
    <div style={{ marginTop: 12 }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8 }}>
        <div style={{ fontSize: 12, fontWeight: 500, color: 'var(--text2)' }}>Team workload</div>
        <button onClick={onViewAll} style={{ fontSize: 11, color: 'var(--blue-text)', background: 'none', border: 'none', cursor: 'pointer', padding: 0 }}>View full →</button>
      </div>
      <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
        {members.slice(0, 5).map(m => {
          const initials = (m.name || '?').split(' ').map(w => w[0]).join('').slice(0,2).toUpperCase();
          const colors = ['#378ADD','#1D9E75','#D85A30','#7F77DD','#BA7517','#D4537E'];
          const color  = colors[(m.name||'').charCodeAt(0) % colors.length];
          return (
            <div key={m.id} style={{ display: 'flex', alignItems: 'center', gap: 7, background: 'var(--surface2)', borderRadius: 20, padding: '4px 10px 4px 4px', border: '0.5px solid var(--border)' }}>
              {m.avatar
                ? <img src={m.avatar} style={{ width: 22, height: 22, borderRadius: '50%', objectFit: 'cover' }} />
                : <div style={{ width: 22, height: 22, borderRadius: '50%', background: color, color: '#fff', fontSize: 9, fontWeight: 700, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{initials}</div>
              }
              <span style={{ fontSize: 11, fontWeight: 500 }}>{m.name.split(' ')[0]}</span>
              <span style={{ fontSize: 10, color: 'var(--text3)' }}>{m.totalTasks} tasks</span>
              {m.overdueTasks > 0 && <span style={{ fontSize: 10, color: 'var(--red-text)' }}>⚠{m.overdueTasks}</span>}
            </div>
          );
        })}
      </div>
    </div>
  );
}


// ── KPI Overview panels (same style as main Overview) ─────────
function KpiOverviewCard({ site, days, onViewAll }) {
  const [data, setData]       = React.useState(null);
  const [loading, setLoading] = React.useState(false);
  const [allRows, setAllRows] = React.useState([]);
  const [showAll, setShowAll] = React.useState({ pages: false, queries: false });
  const STORAGE_KEY = `kpi_v3_${site}`;

  useEffect(() => {
    if (!site) return;
    let cancelled = false;
    let kpis = [];
    try { kpis = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]'); } catch {}
    if (!kpis.length) { setData({ empty: true }); return; }

    setLoading(true);
    const pages = kpis.map(k => k.page);

    gscApi.kpiPages(site, pages, days)
      .then(res => {
        if (cancelled) return;
        const rows = res?.pages || (Array.isArray(res) ? res : []);

        // Aggregate totals
        let totalClicks = 0, totalImpressions = 0, weightedPos = 0, posWeight = 0;
        let improved = 0, declined = 0;

        const enriched = rows.map(r => {
          const kpi = kpis.find(k => k.page === r.page) || {};
          if (r.clicks != null) {
            totalClicks      += r.clicks || 0;
            totalImpressions += r.impressions || 0;
            if (r.position && r.impressions) { weightedPos += r.position * r.impressions; posWeight += r.impressions; }
            if (r.movement === 'up')   improved++;
            if (r.movement === 'down') declined++;
          }
          return { ...r, priority: kpi.priority, keyword: kpi.keyword };
        });

        const avgPos = posWeight > 0 ? parseFloat((weightedPos / posWeight).toFixed(1)) : null;
        const avgCtr = totalImpressions > 0 ? parseFloat((totalClicks / totalImpressions * 100).toFixed(2)) : null;

        setAllRows(enriched);
        setData({ totalClicks, totalImpressions, avgPos, avgCtr, improved, declined, total: kpis.length });
      })
      .catch(() => setData(null))
      .finally(() => { if (!cancelled) setLoading(false); });

    return () => { cancelled = true; };
  }, [site, days]);

  const fmtN = (n) => { if (n == null) return '—'; if (n >= 1000) return (n/1000).toFixed(1)+'K'; return String(n); };

  if (!data && !loading) return null;

  // Sort pages by clicks desc
  const pagesSorted = [...allRows]
    .filter(r => r.clicks != null)
    .sort((a, b) => (b.clicks || 0) - (a.clicks || 0));

  // Flatten all top queries from all KPI pages, deduplicate, sort by clicks
  const queryMap = {};
  allRows.forEach(r => {
    (r.topQueries || []).forEach(q => {
      if (!queryMap[q.query]) {
        queryMap[q.query] = { ...q };
      } else {
        queryMap[q.query].clicks      = (queryMap[q.query].clicks      || 0) + (q.clicks      || 0);
        queryMap[q.query].impressions = (queryMap[q.query].impressions || 0) + (q.impressions || 0);
        // Keep the best (lowest) position
        if (q.position && (!queryMap[q.query].position || q.position < queryMap[q.query].position)) {
          queryMap[q.query].position      = q.position;
          queryMap[q.query].positionDelta = q.positionDelta;
          queryMap[q.query].movement      = q.movement;
        }
      }
    });
  });
  const queriesSorted = Object.values(queryMap)
    .sort((a, b) => (b.clicks || 0) - (a.clicks || 0));

  const PAGE_PREVIEW  = 7;
  const QUERY_PREVIEW = 7;

  if (data?.empty) return (
    <div className="panel" style={{ marginBottom: 12 }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8 }}>
        <div className="ptitle" style={{ margin: 0 }}>KPI pages overview</div>
        <button onClick={onViewAll} style={{ fontSize: 11, color: 'var(--blue-text)', background: 'none', border: 'none', cursor: 'pointer', padding: 0 }}>Set up KPI pages →</button>
      </div>
      <p style={{ fontSize: 12, color: 'var(--text2)' }}>No KPI pages tracked yet. <button onClick={onViewAll} style={{ color: 'var(--blue-text)', background: 'none', border: 'none', cursor: 'pointer', fontSize: 12, padding: 0 }}>Add pages →</button></p>
    </div>
  );

  return (
    <div style={{ marginBottom: 12 }}>

      {/* Header + summary metrics — same style as main metrics row */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>
        <div className="ptitle" style={{ margin: 0 }}>KPI pages overview · {data?.total || '…'} pages</div>
        <button onClick={onViewAll} style={{ fontSize: 11, color: 'var(--blue-text)', background: 'none', border: 'none', cursor: 'pointer', padding: 0 }}>
          Full KPI tracker →
        </button>
      </div>

      {/* 4 summary metric cards — same layout as site-wide metrics */}
      <div className="metrics-row" style={{ marginBottom: 12 }}>
        {[
            { label: 'KPI clicks',      value: loading ? null : fmtN(data?.totalClicks),      delta: null, deltaColor: null },
          { label: 'KPI impressions', value: loading ? null : fmtN(data?.totalImpressions),  delta: null, deltaColor: null },
          { label: 'Avg CTR',         value: loading ? null : (data?.avgCtr != null ? data.avgCtr + '%' : '—'), delta: null, deltaColor: null },
          { label: 'Avg position',    value: loading ? null : (data?.avgPos != null ? '#' + data.avgPos : '—'), delta: null, deltaColor: null },
        ].map(s => (
          <div key={s.label} className={loading ? 'metric-card skeleton' : 'metric-card'}>
            {!loading && <>
              <div className="metric-label">{s.label}</div>
              <div className="metric-value">{s.value}</div>
              {s.label === 'KPI clicks' && data && (
                <div className="metric-delta">
                  <span style={{ color: 'var(--green-text)' }}>{data.improved}↑</span>
                  {' '}
                  <span style={{ color: 'var(--red-text)' }}>{data.declined}↓</span>
                  {' '}pages vs prev period
                </div>
              )}
            </>}
          </div>
        ))}
      </div>

      {/* Two-panel row — same as main Overview panels grid */}
      <div className="panels">

        {/* Left: KPI pages list */}
        <div className="panel" style={{ marginBottom: 0 }}>
          <div className="ptitle">KPI pages · by clicks</div>
          {loading
            ? <div className="skeleton" style={{ height: 180 }} />
            : pagesSorted.length === 0
              ? <p style={{ fontSize: 12, color: 'var(--text2)' }}>No GSC data yet. Try refreshing.</p>
              : <>
                  {(showAll.pages ? pagesSorted : pagesSorted.slice(0, PAGE_PREVIEW)).map((p, i) => {
                    const pos = p.position ? Math.round(p.position) : null;
                    const posColor = !pos ? 'var(--text3)' : pos <= 3 ? 'var(--green-text)' : pos <= 10 ? 'var(--amber-text)' : 'var(--text)';
                    return (
                      <div key={p.page} className="kpi-row">
                        <span style={{ fontSize: 11, color: 'var(--text3)', minWidth: 18, flexShrink: 0 }}>{i+1}</span>
                        <span style={{ flex: 1, fontSize: 12, fontWeight: 500, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={p.page}>
                          {p.page}
                        </span>
                        {p.clicks != null && <span style={{ fontSize: 11, color: 'var(--text2)', marginRight: 8, flexShrink: 0 }}>{fmtN(p.clicks)}</span>}
                        {pos && <span style={{ fontSize: 12, fontWeight: 600, color: posColor, marginRight: 5, flexShrink: 0 }}>#{pos}</span>}
                        {p.positionDelta > 0.5  && <span style={{ fontSize: 11, color: 'var(--green-text)', flexShrink: 0 }}>↑{Math.round(p.positionDelta)}</span>}
                        {p.positionDelta < -0.5 && <span style={{ fontSize: 11, color: 'var(--red-text)',   flexShrink: 0 }}>↓{Math.abs(Math.round(p.positionDelta))}</span>}
                        {(!p.positionDelta || Math.abs(p.positionDelta) < 0.5) && p.movement === 'stable' && <span style={{ fontSize: 10, color: 'var(--text3)', flexShrink: 0 }}>—</span>}
                        {p.movement === 'new' && <span style={{ fontSize: 10, color: 'var(--blue-text)', flexShrink: 0 }}>new</span>}
                      </div>
                    );
                  })}
                  {pagesSorted.length > PAGE_PREVIEW && (
                    <button onClick={() => setShowAll(s => ({ ...s, pages: !s.pages }))}
                      style={{ fontSize: 11, color: 'var(--blue-text)', background: 'none', border: 'none', cursor: 'pointer', padding: '7px 0 0', width: '100%', textAlign: 'center' }}>
                      {showAll.pages ? '▲ Show less' : `▼ Show all ${pagesSorted.length} KPI pages`}
                    </button>
                  )}
                </>
          }
        </div>

        {/* Right: KPI queries list */}
        <div className="panel" style={{ marginBottom: 0 }}>
          <div className="ptitle">KPI queries · by clicks</div>
          {loading
            ? <div className="skeleton" style={{ height: 180 }} />
            : queriesSorted.length === 0
              ? <p style={{ fontSize: 12, color: 'var(--text2)' }}>No query data yet.</p>
              : <>
                  {(showAll.queries ? queriesSorted : queriesSorted.slice(0, QUERY_PREVIEW)).map((q, i) => {
                    const pos = q.position ? Math.round(q.position) : null;
                    const posColor = !pos ? 'var(--text3)' : pos <= 3 ? 'var(--green-text)' : pos <= 10 ? 'var(--amber-text)' : 'var(--text)';
                    const posBg    = !pos ? 'var(--surface2)' : pos <= 3 ? 'var(--green-bg)' : pos <= 10 ? 'var(--amber-bg)' : 'var(--surface2)';
                    return (
                      <div key={q.query} className="kpi-row">
                        <span style={{ flex: 1, fontSize: 12, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={q.query}>
                          {q.query}
                        </span>
                        {q.clicks != null && <span style={{ fontSize: 11, color: 'var(--text2)', marginRight: 8, flexShrink: 0 }}>{fmtN(q.clicks)}</span>}
                        {pos && (
                          <span style={{ fontSize: 11, fontWeight: 600, color: posColor, background: posBg, padding: '1px 5px', borderRadius: 4, marginRight: 5, flexShrink: 0 }}>#{pos}</span>
                        )}
                        {q.positionDelta > 0.5  && <span style={{ fontSize: 11, color: 'var(--green-text)', flexShrink: 0 }}>↑{Math.round(q.positionDelta)}</span>}
                        {q.positionDelta < -0.5 && <span style={{ fontSize: 11, color: 'var(--red-text)',   flexShrink: 0 }}>↓{Math.abs(Math.round(q.positionDelta))}</span>}
                        {q.movement === 'new'    && <span style={{ fontSize: 10, color: 'var(--blue-text)', flexShrink: 0 }}>new</span>}
                        {q.movement === 'stable' && Math.abs(q.positionDelta || 0) < 0.5 && <span style={{ fontSize: 10, color: 'var(--text3)', flexShrink: 0 }}>—</span>}
                      </div>
                    );
                  })}
                  {queriesSorted.length > QUERY_PREVIEW && (
                    <button onClick={() => setShowAll(s => ({ ...s, queries: !s.queries }))}
                      style={{ fontSize: 11, color: 'var(--blue-text)', background: 'none', border: 'none', cursor: 'pointer', padding: '7px 0 0', width: '100%', textAlign: 'center' }}>
                      {showAll.queries ? '▲ Show less' : `▼ Show all ${queriesSorted.length} queries`}
                    </button>
                  )}
                </>
          }
        </div>

      </div>
    </div>
  );
}


// ── Main App ───────────────────────────────────────────────────
export default function App() {
  const [sites, setSites]               = useState([]);
  const [activeSite, setActiveSite]     = useState(null);
  const [activeTab, setActiveTab]       = useState('overview');
  const [sitesLoading, setSitesLoading] = useState(true);
  const [days, setDays]                 = useState(28);
  const [settingsOpen, setSettingsOpen] = useState(false);
  const [folderIds, setFolderIds]       = useState(null);

  // Load saved folder mapping whenever site changes
  useEffect(() => {
    if (!activeSite) return;
    const saved = loadSiteFolderIds(activeSite);
    setFolderIds(saved || null);
  }, [activeSite]);

  const { metrics, keywords, pages, history, overview, backlinks, tasks, insight, loading, errors, refetch } =
    useSiteData(activeSite, { days, folderIds });

  useEffect(() => {
    gsc.sites()
      .then(data => {
        const list = data.map((s, i) => ({
          url: s.url, color: SITE_COLORS[i % SITE_COLORS.length],
          label: s.url.replace(/^https?:\/\//, '').replace(/\/$/, '').replace(/^sc-domain:/, ''),
        }));
        setSites(list);
        if (list.length > 0) setActiveSite(list[0].url);
      })
      .catch(() => {
        const envSites = (import.meta.env.VITE_GSC_SITES || '').split(',').filter(Boolean);
        if (envSites.length > 0) {
          const list = envSites.map((url, i) => ({
            url: url.trim(), color: SITE_COLORS[i % SITE_COLORS.length],
            label: url.trim().replace(/^https?:\/\//, '').replace(/\/$/, ''),
          }));
          setSites(list); setActiveSite(list[0].url);
        }
      })
      .finally(() => setSitesLoading(false));
  }, []);

  const activeSiteData = sites.find(s => s.url === activeSite);

  const handleSettingsClose = (reload) => {
    setSettingsOpen(false);
    if (reload && activeSite) {
      const saved = loadSiteFolderIds(activeSite);
      setFolderIds(saved || null);
    }
  };

  const periodLabel = days === 7 ? '7 days' : days === 28 ? '28 days' : days === 90 ? '3 months' : days === 180 ? '6 months' : days === 365 ? '12 months' : `${days} days`;

  return (
    <div className="app">
      {/* Header */}
      <div className="topbar">
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <div style={{ width: 8, height: 8, borderRadius: '50%', background: activeSiteData?.color || '#378ADD' }} />
          <h1>SEO Command Center</h1>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          {overview && <DRBadge dr={overview.domainRating} />}
          {/* Date range picker */}
          <DateRangePicker days={days} onChange={d => setDays(d)} />
          {/* Settings button */}
          <button onClick={() => setSettingsOpen(true)} title="ClickUp folder settings"
            style={{ fontSize: 13, padding: '3px 9px', borderRadius: 7, border: '0.5px solid var(--border2)', background: 'transparent', color: 'var(--text2)', cursor: 'pointer' }}>
            ⚙ Folders
          </button>
          <ThemePicker />
          <button className="btn-icon" onClick={refetch} title="Refresh">↻</button>
        </div>
      </div>

      {/* Site tabs */}
      <div className="site-tabs">
        {sitesLoading
          ? [0,1,2,3].map(i => <div key={i} className="stab skeleton" style={{ width: 80, height: 28 }} />)
          : sites.length === 0
            ? <div style={{ fontSize: 12, color: 'var(--text2)' }}>No GSC sites found.</div>
            : sites.map(s => (
                <div key={s.url} className={`stab ${activeSite === s.url ? 'active' : ''}`} onClick={() => setActiveSite(s.url)}>
                  <span style={{ display: 'inline-block', width: 7, height: 7, borderRadius: '50%', background: s.color, marginRight: 5 }} />
                  {s.label}
                </div>
              ))
        }
      </div>

      {/* Period + folder info strip */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 10, fontSize: 11, color: 'var(--text3)' }}>
        <span>Period: <strong style={{ color: 'var(--text2)' }}>{periodLabel}</strong></span>
        {folderIds && <span>· ClickUp: <strong style={{ color: 'var(--text2)' }}>filtered by {folderIds.split(',').length} folder{folderIds.split(',').length > 1 ? 's' : ''}</strong></span>}
        {!folderIds && <span>· ClickUp: <strong style={{ color: 'var(--text2)' }}>all tasks</strong></span>}
        <button onClick={() => setSettingsOpen(true)} style={{ fontSize: 10, color: 'var(--blue-text)', background: 'none', border: 'none', cursor: 'pointer', padding: 0 }}>
          change
        </button>
      </div>

      {/* AI Insight Banner */}
      <div className="ai-banner">
        <span className="ai-icon">✦</span>
        <span style={{ flex: 1, fontSize: 12, lineHeight: 1.5 }}>
          {loading.insight
            ? 'Analyzing site data…'
            : insight || `${activeSiteData?.label || '...'} · ${periodLabel} · Add ANTHROPIC_API_KEY to .env for AI insights.`}
        </span>
      </div>

      {/* GSC Metrics */}
      <MetricsRow metrics={metrics} loading={loading.metrics} />

      {/* Ahrefs overview strip (optional) */}
      {(overview || loading.overview) && (
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, minmax(0,1fr))', gap: 10, marginBottom: 14 }}>
          {loading.overview
            ? [0,1,2,3].map(i => <div key={i} className="metric-card skeleton" style={{ height: 56 }} />)
            : <>
                <OverviewCard label="Domain Rating"    value={overview.domainRating}          highlight />
                <OverviewCard label="Organic traffic"  value={fmt(overview.organicTraffic)}               />
                <OverviewCard label="Organic keywords" value={fmt(overview.organicKeywords)}               />
                <OverviewCard label="Referring domains"value={fmt(overview.refDomains)}                    />
              </>
          }
        </div>
      )}

      {/* Tab nav */}
      <div className="tab-nav">
        {TABS.map(t => (
          <div key={t.key} className={`ntab ${activeTab === t.key ? 'active' : ''}`} onClick={() => setActiveTab(t.key)}>
            {t.label}
          </div>
        ))}
      </div>

      {/* ── Overview ── */}
      {activeTab === 'overview' && (
        <div>
          <div className="panels">
            <div className="panel">
              <div className="ptitle">Top pages · {periodLabel}</div>
              {loading.pages
                ? <div className="skeleton" style={{ height: 140 }} />
                : pages.length === 0
                  ? <p style={{ fontSize: 12, color: 'var(--text2)' }}>No page data yet.</p>
                  : pages.map(p => (
                      <div key={p.page || p.url} className="kpi-row">
                        <span style={{ flex: 1, fontSize: 12, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                          {(p.page || p.url || '').replace(/^https?:\/\/[^/]+/, '') || '/'}
                        </span>
                        {p.clicks != null && <span style={{ fontSize: 11, color: 'var(--text2)', marginRight: 6 }}>{fmt(p.clicks)} clicks</span>}
                        {p.topKeywordPosition && <PosBadge pos={p.topKeywordPosition} />}
                      </div>
                    ))
              }
            </div>
            <div className="panel">
              <div className="ptitle">Top queries · {periodLabel}</div>
              {loading.keywords
                ? <div className="skeleton" style={{ height: 140 }} />
                : keywords.slice(0, 7).map(k => (
                    <div key={k.keyword} className="kpi-row">
                      <span style={{ flex: 1, fontSize: 12, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{k.keyword}</span>
                      <PosBadge pos={k.position} />
                      {k.positionDelta > 0.5  && <span style={{ fontSize: 11, color: 'var(--green-text)', marginLeft: 4 }}>↑{Math.round(k.positionDelta)}</span>}
                      {k.positionDelta < -0.5 && <span style={{ fontSize: 11, color: 'var(--red-text)',   marginLeft: 4 }}>↓{Math.abs(Math.round(k.positionDelta))}</span>}
                    </div>
                  ))
              }
            </div>
          </div>
          {/* KPI pages summary */}
          <KpiOverviewCard site={activeSite} days={days} onViewAll={() => setActiveTab('kpi')} />

          <div className="panel" style={{ marginBottom: 12 }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>
              <div className="ptitle" style={{ margin: 0 }}>ClickUp tasks {folderIds ? '· filtered' : ''}</div>
              <button onClick={() => setSettingsOpen(true)} style={{ fontSize: 11, color: 'var(--blue-text)', background: 'none', border: 'none', cursor: 'pointer', padding: 0 }}>
                ⚙ Change folders
              </button>
            </div>
            <TasksKanban tasks={tasks} loading={loading.tasks} onTaskUpdate={refetch} />
          </div>
        </div>
      )}

      {/* ── KPI pages ── */}
      {activeTab === 'kpi' && (
        <div className="panel">
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16 }}>
            <div className="ptitle" style={{ margin: 0 }}>KPI pages tracker</div>
            <span style={{ fontSize: 11, color: 'var(--text3)' }}>Live data from GSC · {periodLabel}</span>
          </div>
          <KpiTracker site={activeSite} days={days} />
        </div>
      )}

      {/* ── Team tab ── */}
      {activeTab === 'team' && (
        <div className="panel">
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14 }}>
            <div className="ptitle" style={{ margin: 0 }}>Team & Projects</div>
            {folderIds && <span style={{ fontSize: 11, color: 'var(--text3)' }}>Filtered by {folderIds.split(',').length} folder{folderIds.split(',').length > 1 ? 's' : ''} · <button onClick={() => setSettingsOpen(true)} style={{ fontSize: 11, color: 'var(--blue-text)', background: 'none', border: 'none', cursor: 'pointer', padding: 0 }}>change</button></span>}
          </div>
          <TeamPanel folderIds={folderIds} />
        </div>
      )}

      {/* ── Keywords ── */}
      {activeTab === 'keywords' && (
        <div className="panel">
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
            <div className="ptitle" style={{ margin: 0 }}>Search queries · {periodLabel}</div>
            <span style={{ fontSize: 11, color: 'var(--text3)' }}>Source: Google Search Console</span>
          </div>
          <KeywordTracker keywords={keywords} loading={loading.keywords} />
        </div>
      )}

      {/* ── Traffic ── */}
      {activeTab === 'traffic' && (
        <div>
          <div className="panel" style={{ marginBottom: 12 }}>
            <div className="ptitle">Organic clicks · {periodLabel}</div>
            <TrafficHistoryChart history={history} loading={loading.history} days={days} />
          </div>
          <div className="panel">
            <div className="ptitle">Impressions · {periodLabel}</div>
            <ImpressionsChart history={history} loading={loading.history} days={days} />
          </div>
        </div>
      )}

      {/* ── Backlinks ── */}
      {activeTab === 'backlinks' && (
        <div>
          {overview && (
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,minmax(0,1fr))', gap: 10, marginBottom: 14 }}>
              <OverviewCard label="Total backlinks"   value={fmt(overview.backlinks)}   />
              <OverviewCard label="Referring domains" value={fmt(overview.refDomains)}  />
              <OverviewCard label="Linked domains"    value={fmt(overview.linkedDomains)} />
            </div>
          )}
          <div className="panel">
            <div className="ptitle">Top backlinks by DR</div>
            {loading.backlinks
              ? <div className="skeleton" style={{ height: 200 }} />
              : backlinks.length === 0
                ? <p style={{ fontSize: 12, color: 'var(--text2)' }}>Configure AHREFS_API_KEY in .env to see backlink data.</p>
                : (
                  <table className="kwtable">
                    <thead>
                      <tr>
                        <th style={{ width: '8%' }}>DR</th>
                        <th style={{ width: '28%' }}>From domain</th>
                        <th style={{ width: '38%' }}>Anchor</th>
                        <th style={{ width: '14%' }}>Type</th>
                        <th style={{ width: '12%' }}>First seen</th>
                      </tr>
                    </thead>
                    <tbody>
                      {backlinks.map((bl, i) => (
                        <tr key={i}>
                          <td><DRBadge dr={bl.domainRating} /></td>
                          <td style={{ fontSize: 12, fontWeight: 500 }}>{bl.domain}</td>
                          <td style={{ fontSize: 11, color: 'var(--text2)' }}>{bl.anchor || '—'}</td>
                          <td>
                            <span style={{ fontSize: 10, padding: '2px 6px', borderRadius: 4, background: bl.follow ? 'var(--green-bg)' : 'var(--surface2)', color: bl.follow ? 'var(--green-text)' : 'var(--text2)' }}>
                              {bl.follow ? 'dofollow' : 'nofollow'}
                            </span>
                          </td>
                          <td style={{ fontSize: 11, color: 'var(--text3)' }}>{bl.firstSeen?.slice(0,10) || '—'}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                )
            }
          </div>
        </div>
      )}

      {/* ── Tasks ── */}
      {activeTab === 'tasks' && (
        <div className="panel">
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14 }}>
            <div className="ptitle" style={{ margin: 0 }}>ClickUp tasks</div>
            <button onClick={() => setSettingsOpen(true)}
              style={{ fontSize: 11, color: 'var(--blue-text)', background: 'none', border: 'none', cursor: 'pointer' }}>
              ⚙ Site folders
            </button>
          </div>
          <FolderGroupTasks site={activeSite} defaultFolderIds={folderIds} />
        </div>
      )}

      {/* ── Sheets ── */}
      {activeTab === 'sheets' && <SheetsPanel />}

      {/* Footer */}
      <div className="src-footer">
        Sources: Google Search Console · Ahrefs API v3 · ClickUp · Claude AI · Google Sheets
        {Object.entries(errors).filter(([k,v]) => v && !['overview','backlinks','tasks'].includes(k)).map(([k,v]) => (
          <span key={k} style={{ color: 'var(--red-text)', marginLeft: 10 }}>⚠ {k}: {v}</span>
        ))}
      </div>

      {/* ClickUp folder settings modal */}
      <SiteSettings sites={sites} open={settingsOpen} onClose={handleSettingsClose} />
    </div>
  );
}
