// ──────────────────────────────────────────────────────────────
// Accountability Viz — animated card for the Accountability section.
// Alternates: big WORKFLOW STAGE (title card) → animated bar chart
// about that stage → next stage → its chart → ... on a loop.
// Light indigo card with a single brand-blue accent, sized to sit
// in the Accountability section's right column (4:3).
// ──────────────────────────────────────────────────────────────
const { useEffect: useAVEffect, useRef: useAVRef, useState: useAVState } = React;

/* Phase timing (variable per kind). */
const AV_FADE = 0.5;
const AV_BUILD = 1.6;
const AV_TITLE_DUR = 3.8;
const AV_CHART_DUR = 6.2;

/* 4:3 viewBox + single spacing unit. */
const AV_VB_W = 480, AV_VB_H = 360, AV_P = 26;

const avEaseOut = (t) => 1 - Math.pow(1 - Math.max(0, Math.min(1, t)), 3);
const avClamp01 = (t) => Math.max(0, Math.min(1, t));
const avFmt = (n) => n.toLocaleString("en-US");

/* The workflow stages the visual rotates through. */
const AV_STAGES = [
  {
    name: ["Asset", "Execution"],
    chartTitle: "Activations Verified",
    items: [
      { label: "Northeast", value: 1240 },
      { label: "Southeast", value: 1080 },
      { label: "Midwest", value: 870 },
      { label: "West", value: 720 },
      { label: "South", value: 560 },
    ],
  },
  {
    name: ["Damage", "Reporting"],
    chartTitle: "Reports by Type",
    items: [
      { label: "Signage", value: 340 },
      { label: "Displays", value: 280 },
      { label: "Fixtures", value: 210 },
      { label: "Packaging", value: 150 },
      { label: "Banners", value: 90 },
    ],
  },
  {
    name: ["Asset", "Takedown"],
    chartTitle: "Takedowns Completed",
    items: [
      { label: "Endcaps", value: 610 },
      { label: "Displays", value: 480 },
      { label: "Windows", value: 360 },
      { label: "Shelf", value: 250 },
      { label: "Banners", value: 160 },
    ],
  },
];

/* Build the flat phase timeline: title, chart, title, chart, ... */
const AV_PHASES = (() => {
  const list = [];
  let start = 0;
  AV_STAGES.forEach((st, idx) => {
    list.push({ kind: "title", st: idx, start, dur: AV_TITLE_DUR });
    start += AV_TITLE_DUR;
    list.push({ kind: "chart", st: idx, start, dur: AV_CHART_DUR });
    start += AV_CHART_DUR;
  });
  return { list, loop: start };
})();

function avPhaseState(start, dur, t, loop) {
  let dt = t - start;
  dt = (((dt % loop) + loop + loop / 2) % loop) - loop / 2;
  if (dt < -AV_FADE || dt > dur + AV_FADE) return { opacity: 0, build: 0 };
  if (dt < AV_FADE) return { opacity: (dt + AV_FADE) / (AV_FADE * 2), build: 0 };
  if (dt < AV_FADE + AV_BUILD) return { opacity: 1, build: (dt - AV_FADE) / AV_BUILD };
  if (dt < dur - AV_FADE) return { opacity: 1, build: 1 };
  return { opacity: (dur + AV_FADE - dt) / (AV_FADE * 2), build: 1 };
}

function useAVLoopTime(reduced) {
  const [t, setT] = useAVState(0);
  useAVEffect(() => {
    if (reduced) return;
    let raf, startT = performance.now();
    const tick = (now) => {
      setT(((now - startT) / 1000) % AV_PHASES.loop);
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [reduced]);
  return t;
}

/* ───── Title card ───── */
function AVTitleState({ st, build }) {
  const stage = AV_STAGES[st];
  const eyebrowOp = avEaseOut(avClamp01(build / 0.4));
  const lineGap = 54;
  const blockH = (stage.name.length - 1) * lineGap;
  const cx = AV_VB_W / 2;
  const cy = AV_VB_H / 2;
  const firstY = cy - blockH / 2 + 6;
  const ruleW = 56;
  const ruleGrow = avEaseOut(avClamp01((build - 0.35) / 0.5));

  return (
    <svg viewBox={`0 0 ${AV_VB_W} ${AV_VB_H}`} preserveAspectRatio="xMidYMid meet" aria-hidden="true">
      {stage.name.map((ln, i) => {
        const stagger = 0.18 + i * 0.16;
        const op = avEaseOut(avClamp01((build - stagger) / 0.45));
        const slide = (1 - op) * 18;
        return (
          <text key={i} x={cx} y={firstY + i * lineGap + slide}
                textAnchor="middle"
                fontSize="46" fontWeight="600" letterSpacing="-0.02em"
                fill="#2F3886" opacity={op}>{ln}</text>
        );
      })}

      <rect x={cx - (ruleW * ruleGrow) / 2} y={cy + blockH / 2 + 30}
            width={ruleW * ruleGrow} height="4" rx="2" fill="#2F3886" />
    </svg>
  );
}

/* ───── Chart card ───── */
function AVChartState({ st, build }) {
  const stage = AV_STAGES[st];
  const items = stage.items;
  const maxV = Math.max(...items.map((d) => d.value));

  const headerOp = avEaseOut(avClamp01(build / 0.3));
  const eyebrowOp = avEaseOut(avClamp01(build / 0.45));

  const xLabelH = 22;
  const valLabelH = 22;
  const chartTop = AV_P + 56 + valLabelH;
  const baseline = AV_VB_H - AV_P - xLabelH;
  const barsH = baseline - chartTop;
  const barsX0 = AV_P;
  const barsW = AV_VB_W - 2 * AV_P;
  const barW = (barsW - AV_P * 0.7 * (items.length - 1)) / items.length;

  return (
    <svg viewBox={`0 0 ${AV_VB_W} ${AV_VB_H}`} preserveAspectRatio="xMidYMid meet" aria-hidden="true">
      <text x={AV_P} y={AV_P + 16}
            fontSize="12" fontWeight="700" letterSpacing="0.2em"
            fill="rgba(47,56,134,0.7)" opacity={eyebrowOp}>{stage.name.join(" ").toUpperCase()}</text>
      <text x={AV_P} y={AV_P + 42}
            fontSize="22" fontWeight="700"
            fill="#2F3886" opacity={headerOp}>{stage.chartTitle}</text>

      <line x1={barsX0} y1={baseline} x2={barsX0 + barsW} y2={baseline}
            stroke="rgba(47,56,134,0.22)" strokeWidth="1" opacity={headerOp} />

      {items.map((d, i) => {
        const stagger = i * 0.12;
        const grow = avEaseOut(avClamp01((build - stagger) / 0.5));
        const fullH = (d.value / maxV) * barsH;
        const h = fullH * grow;
        const bx = barsX0 + i * (barW + AV_P * 0.7);
        const by = baseline - h;
        const labelOp = avEaseOut(avClamp01((build - stagger - 0.15) / 0.4));
        return (
          <g key={d.label}>
            <rect x={bx} y={by} width={barW} height={Math.max(0.001, h)}
                  rx="5" fill="#2F3886" opacity={0.5 + 0.5 * (d.value / maxV)} />
            <text x={bx + barW / 2} y={by - 8}
                  textAnchor="middle" fontSize="13" fontWeight="700"
                  fill="rgba(47,56,134,0.85)" opacity={labelOp}>{avFmt(d.value)}</text>
            <text x={bx + barW / 2} y={baseline + 17}
                  textAnchor="middle" fontSize="12.5" fontWeight="600"
                  fill="rgba(47,56,134,0.9)" opacity={headerOp}>{d.label}</text>
          </g>
        );
      })}
    </svg>
  );
}

/* ───── Top-level component ───── */
function AccountabilityViz() {
  const [reduced, setReduced] = useAVState(() => {
    if (typeof window === "undefined" || !window.matchMedia) return false;
    return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
  });
  useAVEffect(() => {
    if (!window.matchMedia) return;
    const mq = window.matchMedia("(prefers-reduced-motion: reduce)");
    const handler = (e) => setReduced(e.matches);
    mq.addEventListener?.("change", handler);
    return () => mq.removeEventListener?.("change", handler);
  }, []);

  useAVEffect(() => {
    if (document.getElementById("ts-accountability-viz-css")) return;
    const s = document.createElement("style");
    s.id = "ts-accountability-viz-css";
    s.textContent = `
      .ts-accountability-viz {
        position: relative;
        width: 100%;
        aspect-ratio: 4 / 3;
        border-radius: 20px;
        overflow: hidden;
        background: #E1E5FF;
        border: 1px solid rgba(47,56,134,0.14);
        isolation: isolate;
        color: #2F3886;
        font-family: "Montserrat", system-ui, sans-serif;
        box-shadow: 0 24px 50px -24px rgba(47,56,134,0.35);
      }
      .ts-accountability-viz .ts-av-layer {
        position: absolute; inset: 0;
        will-change: opacity, filter;
      }
      .ts-accountability-viz svg { display: block; width: 100%; height: 100%; }
      .ts-accountability-viz text { font-family: inherit; }
      @media (prefers-reduced-motion: reduce) {
        .ts-accountability-viz .ts-av-layer { transition: none !important; }
      }
    `;
    document.head.appendChild(s);
  }, []);

  const t = useAVLoopTime(reduced);

  if (reduced) {
    return (
      <div className="ts-accountability-viz" role="img"
           aria-label="Chart of activations verified by region for asset execution.">
        <div className="ts-av-layer" style={{ opacity: 1 }}>
          <AVChartState st={0} build={1} />
        </div>
      </div>
    );
  }

  return (
    <div className="ts-accountability-viz" role="img"
         aria-label="Animated card cycling through accountability workflow stages and their charts.">
      {AV_PHASES.list.map((ph, i) => {
        const stt = avPhaseState(ph.start, ph.dur, t, AV_PHASES.loop);
        if (stt.opacity <= 0.001) return null;
        return (
          <div key={i} className="ts-av-layer" style={{
            opacity: stt.opacity,
            filter: stt.opacity < 1 ? `blur(${(1 - stt.opacity) * 4}px)` : "none",
          }}>
            {ph.kind === "title"
              ? <AVTitleState st={ph.st} build={stt.build} />
              : <AVChartState st={ph.st} build={stt.build} />}
          </div>
        );
      })}
    </div>
  );
}

window.AccountabilityViz = AccountabilityViz;
