// Scene 3: the dashboard reveal.
// Appears around 4.2s as the chips are still settling, builds in panels:
//   - Big KPI: Months of cash, ticking up to 9.2
//   - Runway line chart: animates a clean ascending curve
//   - Fund-balance bar: restricted vs unrestricted fills in
//   - Cash position counter: counts up to a tidy figure
// Holds through the headline scene (gently breathing) and then dissolves
// before the loop restarts.

const NAVY    = '#0e1f3a';
const NAVY_2  = '#1c2f4f';
const CREAM   = '#f5f0e6';
const CREAM_2 = '#ede6d6';
const ACCENT  = '#9b6a3f'; // warm copper
const ACCENT_2 = '#c89a6e';
const MUTED   = '#5a6478';
const RULE    = '#d8d0bf';

// Easing helper for "in then hold" panel reveals
function panelOpacity(time, start, dur = 0.5) {
  if (time < start) return 0;
  const t = clamp((time - start) / dur, 0, 1);
  return Easing.easeOutCubic(t);
}
function panelLift(time, start, dur = 0.5) {
  if (time < start) return 14;
  const t = clamp((time - start) / dur, 0, 1);
  return (1 - Easing.easeOutCubic(t)) * 14;
}

// Months-of-cash KPI: ticks 0 → 9.2 between 4.6 and 6.4
function MonthsKpi({ time }) {
  const start = 4.6;
  const end   = 6.4;
  const t = clamp((time - start) / (end - start), 0, 1);
  const eased = Easing.easeOutCubic(t);
  const v = (eased * 9.2).toFixed(1);

  const op = panelOpacity(time, 4.4, 0.6);
  const lift = panelLift(time, 4.4, 0.6);

  return (
    <div style={{
      position: 'absolute',
      left: 760, top: 140,
      width: 540, height: 260,
      background: CREAM,
      border: `1px solid ${RULE}`,
      borderRadius: 6,
      padding: '32px 36px',
      opacity: op,
      transform: `translateY(${lift}px)`,
      boxShadow: '0 8px 24px rgba(14,31,58,0.06)',
    }}>
      <div style={{
        fontFamily: 'Inter, system-ui, sans-serif',
        fontSize: 13, fontWeight: 600,
        letterSpacing: '0.14em', textTransform: 'uppercase',
        color: MUTED,
      }}>
        Months of cash
      </div>
      <div style={{
        fontFamily: 'Source Serif 4, "Source Serif Pro", Georgia, serif',
        fontSize: 152,
        fontWeight: 400,
        color: NAVY,
        lineHeight: 1,
        letterSpacing: '-0.03em',
        marginTop: 12,
        fontVariantNumeric: 'tabular-nums',
        display: 'flex', alignItems: 'baseline', gap: 10,
      }}>
        {v}
        <span style={{
          fontFamily: 'Inter, system-ui, sans-serif',
          fontSize: 22, fontWeight: 500,
          color: ACCENT,
          letterSpacing: '0.04em',
        }}>
          ↑ healthy
        </span>
      </div>
      <div style={{
        marginTop: 14,
        fontFamily: 'Inter, system-ui, sans-serif',
        fontSize: 14, color: MUTED,
        letterSpacing: '-0.005em',
      }}>
        Up from 3.1 months at engagement.
      </div>
    </div>
  );
}

// Runway line chart: a clean ascending line that draws in.
// Uses SVG path with stroke-dasharray reveal.
function RunwayChart({ time }) {
  const op = panelOpacity(time, 5.0, 0.6);
  const lift = panelLift(time, 5.0, 0.6);

  // Reveal animation 5.2 → 6.8
  const drawT = clamp((time - 5.2) / 1.6, 0, 1);
  const drawn = Easing.easeInOutCubic(drawT);

  // 12 monthly data points, ascending with a small dip mid-year (storytelling)
  const data = [3.1, 3.6, 4.0, 4.2, 4.0, 4.6, 5.4, 6.1, 6.8, 7.5, 8.4, 9.2];
  const w = 460, h = 150;
  const padX = 8, padY = 12;
  const innerW = w - padX * 2;
  const innerH = h - padY * 2;
  const maxV = 10, minV = 0;
  const pts = data.map((v, i) => {
    const x = padX + (i / (data.length - 1)) * innerW;
    const y = padY + (1 - (v - minV) / (maxV - minV)) * innerH;
    return [x, y];
  });
  const d = pts.map((p, i) => `${i === 0 ? 'M' : 'L'} ${p[0].toFixed(1)} ${p[1].toFixed(1)}`).join(' ');

  // Approximate path length for stroke reveal
  const pathLen = 700;

  return (
    <div style={{
      position: 'absolute',
      left: 760, top: 420,
      width: 540, height: 220,
      background: CREAM,
      border: `1px solid ${RULE}`,
      borderRadius: 6,
      padding: '20px 24px',
      opacity: op,
      transform: `translateY(${lift}px)`,
      boxShadow: '0 8px 24px rgba(14,31,58,0.06)',
    }}>
      <div style={{
        display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
        marginBottom: 6,
      }}>
        <div style={{
          fontFamily: 'Inter, system-ui, sans-serif',
          fontSize: 13, fontWeight: 600,
          letterSpacing: '0.14em', textTransform: 'uppercase',
          color: MUTED,
        }}>
          Runway · 12 mo
        </div>
        <div style={{
          fontFamily: 'JetBrains Mono, ui-monospace, monospace',
          fontSize: 12, color: MUTED,
          letterSpacing: '0.04em',
        }}>
          FY24 → FY26
        </div>
      </div>
      <svg width={w} height={h} style={{ display: 'block', overflow: 'visible' }}>
        {/* Baseline grid */}
        {[0, 0.25, 0.5, 0.75, 1].map((g, i) => (
          <line key={i}
            x1={padX} x2={w - padX}
            y1={padY + g * innerH} y2={padY + g * innerH}
            stroke={RULE} strokeWidth={1}
          />
        ))}
        {/* Path with reveal */}
        <path
          d={d}
          fill="none"
          stroke={NAVY}
          strokeWidth={2.5}
          strokeLinejoin="round"
          strokeLinecap="round"
          style={{
            strokeDasharray: pathLen,
            strokeDashoffset: pathLen * (1 - drawn),
          }}
        />
        {/* Endpoint dot */}
        {drawn > 0.96 && (
          <circle
            cx={pts[pts.length - 1][0]} cy={pts[pts.length - 1][1]}
            r={5} fill={ACCENT}
            opacity={(drawn - 0.96) / 0.04}
          />
        )}
      </svg>
    </div>
  );
}

// Fund-balance bar: restricted/unrestricted split fills horizontally.
function FundBalanceBar({ time }) {
  const op = panelOpacity(time, 5.4, 0.6);
  const lift = panelLift(time, 5.4, 0.6);

  // Fill in 5.6 → 6.6
  const fillT = clamp((time - 5.6) / 1.0, 0, 1);
  const fill = Easing.easeOutCubic(fillT);

  const restrictedPct = 0.42;
  const unrestrictedPct = 0.58;
  const totalW = 480;

  return (
    <div style={{
      position: 'absolute',
      left: 200, top: 420,
      width: 540, height: 220,
      background: CREAM,
      border: `1px solid ${RULE}`,
      borderRadius: 6,
      padding: '20px 24px',
      opacity: op,
      transform: `translateY(${lift}px)`,
      boxShadow: '0 8px 24px rgba(14,31,58,0.06)',
    }}>
      <div style={{
        fontFamily: 'Inter, system-ui, sans-serif',
        fontSize: 13, fontWeight: 600,
        letterSpacing: '0.14em', textTransform: 'uppercase',
        color: MUTED,
      }}>
        Net assets · by class
      </div>
      <div style={{
        marginTop: 16,
        fontFamily: 'Source Serif 4, "Source Serif Pro", Georgia, serif',
        fontSize: 40,
        fontWeight: 400,
        color: NAVY,
        lineHeight: 1,
        letterSpacing: '-0.02em',
        fontVariantNumeric: 'tabular-nums',
      }}>
        $1,084,392
      </div>
      {/* The bar */}
      <div style={{
        marginTop: 22,
        width: totalW, height: 14,
        background: CREAM_2,
        borderRadius: 2,
        position: 'relative',
        overflow: 'hidden',
      }}>
        <div style={{
          position: 'absolute', left: 0, top: 0, bottom: 0,
          width: totalW * unrestrictedPct * fill,
          background: NAVY,
        }}/>
        <div style={{
          position: 'absolute',
          left: totalW * unrestrictedPct, top: 0, bottom: 0,
          width: totalW * restrictedPct * fill,
          background: ACCENT,
        }}/>
      </div>
      {/* Legend */}
      <div style={{
        marginTop: 14,
        display: 'flex', gap: 24,
        fontFamily: 'Inter, system-ui, sans-serif',
        fontSize: 13, color: MUTED,
        opacity: fill,
      }}>
        <LegendDot color={NAVY} label="Unrestricted" pct="58%" />
        <LegendDot color={ACCENT} label="Restricted" pct="42%" />
      </div>
    </div>
  );
}

function LegendDot({ color, label, pct }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
      <div style={{
        width: 10, height: 10, borderRadius: 5,
        background: color,
      }}/>
      <div>{label}</div>
      <div style={{
        fontFamily: 'JetBrains Mono, ui-monospace, monospace',
        fontVariantNumeric: 'tabular-nums',
        color: NAVY, fontWeight: 500,
      }}>{pct}</div>
    </div>
  );
}

// Cash position: top-left card with counter ticking up.
function CashPosition({ time }) {
  const op = panelOpacity(time, 4.7, 0.6);
  const lift = panelLift(time, 4.7, 0.6);

  const start = 4.9;
  const end = 6.6;
  const t = clamp((time - start) / (end - start), 0, 1);
  const eased = Easing.easeOutCubic(t);
  const target = 487420;
  const v = Math.round(eased * target);
  const formatted = v.toLocaleString('en-US');

  return (
    <div style={{
      position: 'absolute',
      left: 200, top: 140,
      width: 540, height: 260,
      background: NAVY,
      borderRadius: 6,
      padding: '32px 36px',
      opacity: op,
      transform: `translateY(${lift}px)`,
      boxShadow: '0 12px 32px rgba(14,31,58,0.18)',
      color: CREAM,
    }}>
      <div style={{
        fontFamily: 'Inter, system-ui, sans-serif',
        fontSize: 13, fontWeight: 600,
        letterSpacing: '0.14em', textTransform: 'uppercase',
        color: 'rgba(245,240,230,0.7)',
      }}>
        Cash position
      </div>
      <div style={{
        fontFamily: 'Source Serif 4, "Source Serif Pro", Georgia, serif',
        fontSize: 96,
        fontWeight: 400,
        lineHeight: 1,
        letterSpacing: '-0.03em',
        marginTop: 14,
        fontVariantNumeric: 'tabular-nums',
        color: CREAM,
      }}>
        ${formatted}
      </div>
      <div style={{
        marginTop: 20,
        display: 'flex', gap: 24,
        fontFamily: 'Inter, system-ui, sans-serif',
        fontSize: 14,
        color: 'rgba(245,240,230,0.7)',
      }}>
        <div>
          <div style={{ color: ACCENT_2, fontWeight: 500 }}>+ $214,180</div>
          <div style={{ fontSize: 12, marginTop: 2 }}>vs. Jan 2025</div>
        </div>
        <div style={{ width: 1, background: 'rgba(245,240,230,0.15)' }}/>
        <div>
          <div style={{ color: CREAM, fontWeight: 500 }}>Reconciled</div>
          <div style={{ fontSize: 12, marginTop: 2 }}>through Mar 31, 2026</div>
        </div>
      </div>
    </div>
  );
}

// A small "NFP CFO · Q1 Report" header above the dashboard area
function DashHeader({ time }) {
  const op = panelOpacity(time, 4.3, 0.6);
  return (
    <div style={{
      position: 'absolute',
      left: 200, top: 78,
      display: 'flex', alignItems: 'baseline', gap: 18,
      opacity: op,
    }}>
      <div style={{
        fontFamily: 'Inter, system-ui, sans-serif',
        fontSize: 13, fontWeight: 600,
        color: NAVY,
        letterSpacing: '0.18em', textTransform: 'uppercase',
      }}>
        Board Packet · Q1 FY26
      </div>
      <div style={{
        fontFamily: 'JetBrains Mono, ui-monospace, monospace',
        fontSize: 12, color: MUTED,
        letterSpacing: '0.04em',
      }}>
        Prepared by The Not-For-Profit CFO
      </div>
    </div>
  );
}

function DashboardScene() {
  const time = useTime();

  // Dashboard exits before the headline takes over
  const exitStart = 7.6;
  const exitEnd   = 8.3;
  let groupOp = 1;
  let groupLift = 0;
  let groupScale = 1;
  if (time >= exitStart) {
    const t = clamp((time - exitStart) / (exitEnd - exitStart), 0, 1);
    const eased = Easing.easeInCubic(t);
    groupOp = 1 - eased;
    groupLift = -eased * 24;
    groupScale = 1 - eased * 0.02;
  }

  // Subtle "breathing" while held
  const holdStart = 6.8;
  const breath = time > holdStart && time < exitStart
    ? Math.sin((time - holdStart) * 1.4) * 1.2
    : 0;

  if (time < 4.2) return null;

  return (
    <div style={{
      position: 'absolute', inset: 0,
      opacity: groupOp,
      transform: `translateY(${groupLift + breath}px) scale(${groupScale})`,
      transformOrigin: 'center',
      willChange: 'transform, opacity',
    }}>
      <DashHeader time={time} />
      <CashPosition time={time} />
      <MonthsKpi time={time} />
      <FundBalanceBar time={time} />
      <RunwayChart time={time} />
    </div>
  );
}

Object.assign(window, { DashboardScene });
