/* PAGE 4 — Performance by Dimension (chart + companion period-over-period table)
   RC-PAGE-040 / RC-PAGE-041 / RC-PAGE-042 / RC-SEC-050 */

/* 10-line palette for RC-SEC-050: chart-1/2/3 as anchors plus harmonious
   oklch extensions. Two rows when shown as a legend. */
const DIM_LINE_PALETTE = [
  'var(--rc-chart-1)',               // blue
  'var(--rc-chart-2)',               // teal
  'var(--rc-chart-3)',               // amber
  'oklch(0.62 0.20 300)',            // violet
  'oklch(0.66 0.18 10)',             // red-pink
  'oklch(0.70 0.14 140)',            // green
  'oklch(0.68 0.13 230)',            // cyan
  'oklch(0.64 0.18 60)',             // orange
  'oklch(0.58 0.15 340)',            // magenta
  'oklch(0.55 0.08 260)',            // slate
];

/* Deterministic-ish time-series generator — each dim value gets a distinct
   wave shape keyed off its label. 14-day series feels right for a "Last 14"
   default without overloading the chart. */
function makeDimTimeSeries(label, metric, anchorValue, n = 14) {
  const seed = [...label].reduce((a, c) => a + c.charCodeAt(0), 0);
  const freq = 0.4 + (seed % 7) * 0.08;
  const phase = (seed % 12) * 0.4;
  const drift = (seed % 13) / 300 - 0.02; // -0.02..+0.02 per step
  const volatility = 0.08 + (seed % 5) * 0.02;
  const values = [];
  for (let i = 0; i < n; i++) {
    const base = anchorValue * (1 + drift * i);
    const wave = Math.sin(i * freq + phase) * volatility;
    const jitter = Math.sin(i * 2.3 + seed) * (volatility * 0.35);
    values.push(Math.max(0, base * (1 + wave + jitter)));
  }
  return values;
}

const PageByDimension = ({ reportType, viewBy, comparison, changeMode, setChangeMode }) => {
  const [metric, setMetric] = React.useState(reportType.scorecards[0]);

  // Generate dimension rows based on viewBy (ordered) — first dim drives grouping.
  const primaryDim = viewBy[0] || reportType.viewByDims[0];
  const rows = makeDimensionRows(primaryDim, metric, 10); // up to 10 for RC-SEC-050

  return (
    <div style={{ padding: 16, display: 'flex', flexDirection: 'column', gap: 14 }}>
      {/* RC-SEC-050 — Trend by Dimension */}
      <DimensionTrendChart metric={metric} setMetric={setMetric}
        options={reportType.scorecards}
        rows={rows} primaryDim={primaryDim} />

      {/* Chart card — horizontal bars snapshot */}
      <Card>
        <div style={{ padding: '12px 14px', borderBottom: '1px solid var(--rc-border-soft)',
          display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: 10 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <h3 style={{ margin: 0, fontSize: 13, fontWeight: 600, fontFamily: 'Poppins' }}>
              {METRIC_LABELS[metric]} by {primaryDim}
            </h3>
            <span style={{ fontSize: 11, color: 'var(--rc-text-sub)' }}>Top {Math.min(rows.length, 8)}</span>
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
            <div style={{ position: 'relative' }}>
              <MetricPickerButton metric={metric} setMetric={setMetric} options={reportType.scorecards} />
            </div>
            <IconBtn name="download" title="Export chart as image"
              onClick={() => {
                const run = () => {
                  const sid = window.__rcToast.exportStarted({ scope: 'chart image' });
                  setTimeout(() => {
                    window.__rcToast.dismiss(sid);
                    if (Math.random() < 0.7) {
                      window.__rcToast.exportSucceeded({
                        scope: 'chart',
                        filename: `${METRIC_LABELS[metric].toLowerCase().replace(/\s+/g, '-')}_by_${primaryDim}.png`,
                      });
                    } else {
                      window.__rcToast.exportFailed({ scope: 'chart image', onRetry: run });
                    }
                  }, 900);
                };
                run();
              }} />
            <IconBtn name="expand" title="Expand" />
          </div>
        </div>
        <div style={{ padding: '14px 14px 12px' }}>
          <HorizontalBars rows={rows.slice(0, 8)} metric={metric} primaryDim={primaryDim} />
        </div>
      </Card>

      {/* Companion table — period-over-period */}
      <Card>
        <div style={{ padding: '10px 14px', borderBottom: '1px solid var(--rc-border-soft)',
          display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <h3 style={{ margin: 0, fontSize: 13, fontWeight: 600, fontFamily: 'Poppins' }}>Period-over-Period</h3>
            <span style={{ fontSize: 11, color: 'var(--rc-text-sub)' }}>Each metric shown current / prior / change</span>
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
            <Segmented
              tabs={[{ value: 'pct', label: '%' }, { value: 'net', label: 'Net' }, { value: 'pts', label: 'pts' }]}
              active={changeMode} onChange={setChangeMode} size="sm" />
            <IconBtn name="filter" title="Filter" />
            <IconBtn name="download" title="Export table data"
              onClick={() => {
                const run = () => {
                  const sid = window.__rcToast.exportStarted({ scope: 'period-over-period table' });
                  setTimeout(() => {
                    window.__rcToast.dismiss(sid);
                    if (Math.random() < 0.6) {
                      window.__rcToast.exportSucceeded({
                        scope: 'table',
                        filename: `period_over_period_by_${primaryDim}.xlsx`,
                      });
                    } else {
                      window.__rcToast.exportFailed({ scope: 'period-over-period table', onRetry: run });
                    }
                  }, 900);
                };
                run();
              }} />
          </div>
        </div>

        <div style={{ overflow: 'auto' }}>
          <DimensionPopTable rows={rows} viewBy={viewBy} metrics={reportType.scorecards.slice(0, 5)} changeMode={changeMode} comparison={comparison} />
        </div>
      </Card>
    </div>
  );
};

/* =================================================================
   RC-SEC-050 — Dimension Trend Chart
   1 metric × N lines (one per dim value), top-N cap 10, legend toggle.
   ================================================================= */
const DimensionTrendChart = ({ metric, setMetric, options, rows, primaryDim }) => {
  const N = 14;
  // x labels — last 14 days, rough labels every other day
  const xLabels = React.useMemo(() => {
    const arr = [];
    for (let i = N - 1; i >= 0; i--) {
      const d = new Date();
      d.setDate(d.getDate() - i);
      arr.push(i % 2 === 0 ? `${d.getMonth() + 1}/${d.getDate()}` : '');
    }
    return arr;
  }, []);

  // Build up to 10 series, sorted desc by current value
  const ranked = [...rows].sort((a, b) => b.current - a.current).slice(0, 10);
  const allSeries = ranked.map((r, i) => ({
    key: r.label,
    label: r.label,
    color: DIM_LINE_PALETTE[i % DIM_LINE_PALETTE.length],
    values: makeDimTimeSeries(r.label, metric, r.current, N),
    row: r,
  }));

  const [hidden, setHidden] = React.useState(new Set());
  const [pinned, setPinned] = React.useState(null); // pinned label for emphasis
  const [hoveredIdx, setHoveredIdx] = React.useState(null);

  const toggle = (key) => {
    const next = new Set(hidden);
    if (next.has(key)) next.delete(key); else next.add(key);
    setHidden(next);
  };

  const series = allSeries.map(s => ({
    ...s,
    visible: !hidden.has(s.key),
    emphasis: pinned === s.key,
    dimmed: pinned !== null && pinned !== s.key,
  }));

  const visibleCount = series.filter(s => s.visible).length;

  return (
    <Card>
      <div style={{ padding: '12px 14px', borderBottom: '1px solid var(--rc-border-soft)',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: 10 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <h3 style={{ margin: 0, fontSize: 13, fontWeight: 600, fontFamily: 'Poppins' }}>
            {METRIC_LABELS[metric]} trend by {primaryDim}
          </h3>
          <span style={{ fontSize: 11, color: 'var(--rc-text-sub)' }}>
            Top {allSeries.length} · Last {N} days
            {visibleCount < allSeries.length && <> · {visibleCount} visible</>}
          </span>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
          <MetricPickerButton metric={metric} setMetric={setMetric} options={options} />
          <IconBtn name="download" title="Export chart as image"
            onClick={() => {
              const sid = window.__rcToast.exportStarted({ scope: 'trend chart' });
              setTimeout(() => {
                window.__rcToast.dismiss(sid);
                window.__rcToast.exportSucceeded({
                  scope: 'trend chart',
                  filename: `trend_${METRIC_LABELS[metric].toLowerCase().replace(/\s+/g, '-')}_by_${primaryDim.toLowerCase().replace(/\s+/g, '-')}.png`,
                });
              }, 900);
            }} />
          <IconBtn name="expand" title="Expand" />
        </div>
      </div>

      <div style={{ padding: '14px 14px 6px' }}>
        <SharedAxisLineChart seriesList={series}
          xLabels={xLabels}
          hoveredIdx={hoveredIdx}
          setHoveredIdx={setHoveredIdx}
          height={260} />
      </div>

      {/* Legend — clickable chips to toggle, click again to pin/emphasize */}
      <div style={{
        padding: '10px 14px 14px',
        borderTop: '1px solid var(--rc-border-soft)',
        display: 'flex', flexWrap: 'wrap', gap: 6,
      }}>
        {series.map(s => {
          const isHidden = !s.visible;
          const isPinned = pinned === s.key;
          return (
            <button key={s.key}
              onClick={() => {
                if (isHidden) { toggle(s.key); return; }
                // cycle: visible → pinned → hidden → visible
                if (!isPinned && pinned === null) setPinned(s.key);
                else if (isPinned) { setPinned(null); toggle(s.key); }
                else setPinned(s.key);
              }}
              onDoubleClick={(e) => {
                e.preventDefault();
                // double-click: isolate — hide all others
                const others = allSeries.filter(x => x.key !== s.key).map(x => x.key);
                setHidden(new Set(others));
                setPinned(null);
              }}
              title={isHidden ? 'Show' : isPinned ? 'Unpin' : 'Click to emphasize · double-click to isolate'}
              style={{
                display: 'inline-flex', alignItems: 'center', gap: 6,
                padding: '4px 9px 4px 6px',
                background: isPinned
                  ? `color-mix(in srgb, ${s.color} 14%, var(--rc-card))`
                  : 'var(--rc-subtle)',
                border: `1px solid ${isPinned ? s.color : 'var(--rc-border-soft)'}`,
                borderRadius: 999,
                fontSize: 11, color: isHidden ? 'var(--rc-text-mute)' : 'var(--rc-text)',
                cursor: 'pointer', fontFamily: 'inherit',
                opacity: isHidden ? 0.55 : 1,
                maxWidth: 200, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
              }}>
              <span style={{
                width: 10, height: 10, borderRadius: 2,
                background: s.color,
                opacity: isHidden ? 0.3 : 1,
                flexShrink: 0,
              }} />
              <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', fontWeight: isPinned ? 600 : 500 }}>
                {s.label}
              </span>
            </button>
          );
        })}
        {hidden.size > 0 && (
          <button onClick={() => { setHidden(new Set()); setPinned(null); }}
            style={{
              padding: '4px 10px', background: 'transparent',
              border: 0, color: 'var(--rc-chart-1)',
              fontSize: 11, fontWeight: 500, cursor: 'pointer', fontFamily: 'inherit',
            }}>
            Show all
          </button>
        )}
      </div>
    </Card>
  );
};

const MetricPickerButton = ({ metric, setMetric, options }) => {
  const [open, setOpen] = React.useState(false);
  return (
    <div style={{ position: 'relative' }}>
      <button onClick={() => setOpen(!open)} style={{
        display: 'inline-flex', alignItems: 'center', gap: 6,
        padding: '5px 10px', background: 'var(--rc-card)',
        border: '1px solid var(--rc-border)', borderRadius: 6,
        fontSize: 12, fontWeight: 500, color: 'var(--rc-text)',
        cursor: 'pointer', fontFamily: 'inherit',
      }}>
        Metric: {METRIC_LABELS[metric]}
        <Icon name="chevronDown" size={10} />
      </button>
      {open && (
        <Dropdown onClose={() => setOpen(false)} align="right" width={200}>
          {options.map(o => (
            <DropItem key={o} active={o === metric} onClick={() => { setMetric(o); setOpen(false); }}>
              {METRIC_LABELS[o]}
            </DropItem>
          ))}
        </Dropdown>
      )}
    </div>
  );
};

/* Horizontal bars — one bar per dimension row */
const HorizontalBars = ({ rows, metric, primaryDim }) => {
  const maxVal = Math.max(...rows.map(r => r.current));
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
      {rows.map((r, i) => {
        const pct = (r.current / maxVal) * 100;
        const priorPct = (r.prior / maxVal) * 100;
        return (
          <div key={r.label} style={{ display: 'grid', gridTemplateColumns: '180px 1fr 90px 60px', gap: 10, alignItems: 'center' }}>
            <div style={{ fontSize: 12, color: 'var(--rc-text)', fontWeight: 500, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
              <DimLabel dim={primaryDim} row={r} />
            </div>
            <div style={{ position: 'relative', height: 18 }}>
              {/* prior bar (outlined) */}
              <div style={{
                position: 'absolute', left: 0, top: 2, height: 6,
                width: `${priorPct}%`, borderRadius: 3,
                background: 'color-mix(in srgb, var(--rc-chart-1) 14%, transparent)',
              }} />
              {/* current bar (solid) */}
              <div style={{
                position: 'absolute', left: 0, top: 10, height: 7,
                width: `${pct}%`, borderRadius: 3,
                background: 'var(--rc-chart-1)',
              }} />
            </div>
            <div style={{ fontSize: 12, color: 'var(--rc-text)', textAlign: 'right', fontVariantNumeric: 'tabular-nums' }}>
              {formatValue(metric, r.current)}
            </div>
            <div style={{ textAlign: 'right' }}>
              <Delta value={formatChange(metric, r.current, r.prior, 'pct')} direction={changeDirection(metric, r.current - r.prior)} size={11} />
            </div>
          </div>
        );
      })}
      <div style={{ display: 'flex', gap: 14, fontSize: 10, color: 'var(--rc-text-sub)', paddingTop: 6, borderTop: '1px solid var(--rc-border-soft)', marginTop: 4 }}>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}>
          <span style={{ width: 18, height: 7, borderRadius: 2, background: 'var(--rc-chart-1)' }} /> Current
        </span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}>
          <span style={{ width: 18, height: 6, borderRadius: 2, background: 'color-mix(in srgb, var(--rc-chart-1) 14%, transparent)' }} /> Prior
        </span>
      </div>
    </div>
  );
};

/* Companion period-over-period table */
const DimensionPopTable = ({ rows, viewBy, metrics, changeMode, comparison }) => {
  const primaryDim = viewBy[0];
  return (
    <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 11, fontFamily: 'Inter', fontVariantNumeric: 'tabular-nums' }}>
      <thead>
        <tr>
          <th rowSpan="2" style={{ ...matHead, textAlign: 'left', minWidth: 180 }}>{primaryDim}</th>
          {metrics.map(m => (
            <th key={m} colSpan={comparison === 'none' ? 1 : 3} style={{ ...matHead, textAlign: 'center', borderLeft: '1px solid var(--rc-border)' }}>
              {METRIC_LABELS[m]}
            </th>
          ))}
        </tr>
        <tr>
          {metrics.map(m => (
            <React.Fragment key={m}>
              <th style={{ ...matHead, textAlign: 'right', borderLeft: '1px solid var(--rc-border)' }}>Current</th>
              {comparison !== 'none' && <>
                <th style={{ ...matHead, textAlign: 'right' }}>Prior</th>
                <th style={{ ...matHead, textAlign: 'right' }}>{changeMode === 'pct' ? '% Δ' : changeMode === 'net' ? 'Net Δ' : 'pts Δ'}</th>
              </>}
            </React.Fragment>
          ))}
        </tr>
      </thead>
      <tbody>
        {rows.map((r, i) => (
          <tr key={r.label} style={{ borderTop: '1px solid var(--rc-border-soft)' }}>
            <td style={{ ...matCell, color: 'var(--rc-text)', fontWeight: 500 }}>
              <div><DimLabel dim={viewBy[0]} row={r} /></div>
              {viewBy.length > 1 && (
                <div style={{ fontSize: 10, color: 'var(--rc-text-mute)', marginTop: 2 }}>
                  {viewBy.slice(1).map(d => `${d}: ${DIM_SAMPLES[d]?.[i % (DIM_SAMPLES[d]?.length || 1)] || '—'}`).join(' · ')}
                </div>
              )}
            </td>
            {metrics.map((m, mi) => {
              const base = BASELINES[m] ?? 100;
              const factor = 0.7 + Math.sin((i + mi * 1.1) * 0.8) * 0.28;
              const current = base * factor;
              const prior = current * (1 - 0.04 - (i % 4) * 0.02);
              const dir = changeDirection(m, current - prior);
              return (
                <React.Fragment key={m}>
                  <td style={{ ...matCell, textAlign: 'right', color: 'var(--rc-text)', borderLeft: '1px solid var(--rc-border-soft)' }}>
                    {formatValue(m, current)}
                  </td>
                  {comparison !== 'none' && <>
                    <td style={{ ...matCell, textAlign: 'right', color: 'var(--rc-text-sub)' }}>{formatValue(m, prior)}</td>
                    <td style={{ ...matCell, textAlign: 'right', color: dir === 'good' ? 'var(--rc-green-ink)' : dir === 'bad' ? 'var(--rc-negative)' : 'var(--rc-text-mute)', fontWeight: 500 }}>
                      {formatChange(m, current, prior, changeMode)}
                    </td>
                  </>}
                </React.Fragment>
              );
            })}
          </tr>
        ))}
      </tbody>
    </table>
  );
};

/* ---- Dimension fixture data ---- */
const DIM_SAMPLES = {
  'ASIN': ASIN_FIXTURES.map(a => a.asin),
  'Product Name': ASIN_FIXTURES.map(a => a.name),
  'Parent ASIN': ASIN_FIXTURES.map(a => 'P' + a.asin.slice(2)),
  'Brand': ['Hydrapak', 'Stretch Labs', 'American Outdoor', 'FitWave', 'Urban Gear', 'Peak Form'],
  'Category': ['Hydration', 'Apparel', 'Outdoor', 'Fitness', 'Accessories'],
  'Marketplace': ['Amazon.com', 'Amazon.ca', 'Amazon.co.uk', 'Amazon.de'],
  'Campaign': ['SP Auto — Hydration', 'SP Manual — Apparel', 'SB Video — Core', 'SD Retarget', 'SP Auto — Gear'],
  'Campaign Type': ['Sponsored Products', 'Sponsored Brands', 'Sponsored Display'],
  'Ad Group': ['Core Keywords', 'Branded', 'Competitor', 'Auto Targeting', 'Category'],
  'Keyword': ['hydration pack', 'running vest', 'trail water bottle', 'collapsible flask'],
  'Match Type': ['Exact', 'Phrase', 'Broad', 'Auto'],
  'Targeting Type': ['Auto', 'Manual — Keyword', 'Manual — Product'],
  'Placement': ['Top of Search', 'Product Pages', 'Rest of Search'],
};

function makeDimensionRows(dim, metric, n) {
  const labels = DIM_SAMPLES[dim] || ASIN_FIXTURES.map(a => a.name);
  const base = BASELINES[metric] ?? 100;
  return labels.slice(0, n).map((label, i) => {
    const factor = 1.1 - i * 0.09 + Math.sin(i * 1.7) * 0.12;
    const current = base * factor;
    const asinRef = ASIN_FIXTURES[i % ASIN_FIXTURES.length];
    return {
      label, current,
      prior: current * (1 - 0.05 - (i % 3) * 0.02),
      asin: dim === 'ASIN' ? label : dim === 'Parent ASIN' ? label : asinRef.asin,
      productName: dim === 'Product Name' ? label : asinRef.name,
    };
  });
}

/* Render the first-column label w/ AsinCell when the dim is ASIN-shaped. */
const DimLabel = ({ dim, row }) => {
  if (dim === 'ASIN' || dim === 'Parent ASIN') {
    return <AsinCell asin={row.asin || row.label} name={row.productName} marketplace="US" />;
  }
  if (dim === 'Product Name') {
    return (
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
        <span style={{ color: 'var(--rc-text)' }}>{row.label}</span>
        <AsinCell asin={row.asin} marketplace="US" />
      </span>
    );
  }
  return <span>{row.label}</span>;
};

Object.assign(window, { PageByDimension, DimensionTrendChart, HorizontalBars, DimensionPopTable, DIM_SAMPLES, makeDimensionRows, DimLabel, makeDimTimeSeries });
