"use client";

import { useEffect, useState } from "react";
import { metricCharts } from "@/content/metrics";
import { cn } from "@/lib/cn";

/** Returns true one frame after `visible` turns true, so CSS transitions run from their initial state. */
function useDrawn(visible: boolean) {
  const [drawn, setDrawn] = useState(false);
  useEffect(() => {
    if (!visible) return;
    const frame = requestAnimationFrame(() => setDrawn(true));
    return () => cancelAnimationFrame(frame);
  }, [visible]);
  return drawn;
}

/** Grouped bars: Campaign A wins on cheap leads, Campaign B wins on pipeline. Relative shapes only. */
export function PipelineChart({ visible }: { visible: boolean }) {
  const drawn = useDrawn(visible);
  const { stages, series } = metricCharts.saas;
  const baseline = 236;
  const maxHeight = 176;
  const centers = [104, 248, 392, 536];

  return (
    <svg viewBox="0 0 640 300" className="h-auto w-full" role="img" aria-labelledby="pipeline-chart-title pipeline-chart-desc">
      <title id="pipeline-chart-title">Illustrative chart: cheap leads versus real pipeline</title>
      <desc id="pipeline-chart-desc">
        Campaign A produces more leads than Campaign B, but far fewer of them become sales-qualified leads, opportunities, and closed-won
        deals. Campaign B produces fewer leads and more pipeline. Illustrative shapes, no real values.
      </desc>

      <g className="font-mono" fontSize="11" letterSpacing="0.06em">
        <rect x="40" y="16" width="12" height="12" rx="2" className="fill-night-muted/25 stroke-night-muted/70" />
        <text x="60" y="26.5" className="fill-night-muted">
          CAMPAIGN A · CHEAPER LEADS
        </text>
        <rect x="300" y="16" width="12" height="12" rx="2" className="fill-signal-bright" />
        <text x="320" y="26.5" className="fill-night-text">
          CAMPAIGN B · MORE PIPELINE
        </text>
      </g>

      <path d={`M32 ${baseline} H616`} className="stroke-night-line" />

      {stages.map((stage, stageIndex) => {
        const center = centers[stageIndex];
        return (
          <g key={stage}>
            {series.map((item, seriesIndex) => {
              const height = item.values[stageIndex] * maxHeight;
              const isB = seriesIndex === 1;
              return (
                <rect
                  key={item.name}
                  x={isB ? center + 4 : center - 40}
                  y={baseline - height}
                  width="36"
                  height={height}
                  rx="2"
                  className={cn(
                    "origin-bottom [transform-box:fill-box]",
                    isB ? "fill-signal-bright" : "fill-night-muted/25 stroke-night-muted/70",
                  )}
                  style={{
                    transform: drawn ? "scaleY(1)" : "scaleY(0)",
                    transition: `transform 1000ms var(--ease-out-expo) ${stageIndex * 110 + seriesIndex * 60}ms`,
                  }}
                />
              );
            })}
            <text x={center} y={baseline + 26} textAnchor="middle" className="fill-night-muted font-mono" fontSize="11" letterSpacing="0.06em">
              {stage.toUpperCase()}
            </text>
          </g>
        );
      })}

      <g className="transition-opacity duration-700" style={{ opacity: drawn ? 1 : 0, transitionDelay: "700ms" }} fontSize="12">
        <path d={`M${centers[0] - 22} 52 V${baseline - maxHeight - 8}`} className="stroke-night-muted/70" strokeDasharray="2 3" />
        <text x={centers[0] - 22} y="46" textAnchor="middle" className="fill-night-muted">
          A wins here
        </text>
        <path d={`M${centers[3] + 22} ${baseline - 0.12 * maxHeight - 10} V${baseline - 0.12 * maxHeight - 34}`} className="stroke-signal-bright" />
        <text x={centers[3] + 22} y={baseline - 0.12 * maxHeight - 42} textAnchor="middle" className="fill-signal-bright">
          B wins here
        </text>
      </g>
    </svg>
  );
}

/** Platform-reported ROAS climbs while blended MER stays flat and contribution margin slips. */
export function MerRoasChart({ visible }: { visible: boolean }) {
  const drawn = useDrawn(visible);
  const { platformRoas, blendedMer, contributionMargin } = metricCharts.ecommerce;
  const left = 48;
  const right = 592;
  const step = (right - left) / (platformRoas.length - 1);
  const y = (value: number) => 196 - ((value - 0.3) / 0.5) * 140;
  const points = (values: number[]) => values.map((value, i) => `${left + i * step},${y(value)}`);
  const roasPoints = points(platformRoas);
  const merPoints = points(blendedMer);
  const gapPolygon = [...roasPoints, ...[...merPoints].reverse()].join(" ");
  const lastX = left + (platformRoas.length - 1) * step;

  return (
    <svg viewBox="0 0 640 300" className="h-auto w-full" role="img" aria-labelledby="mer-chart-title mer-chart-desc">
      <title id="mer-chart-title">Illustrative chart: platform ROAS versus blended MER</title>
      <desc id="mer-chart-desc">
        Over twelve weeks, platform-reported ROAS rises steadily while blended marketing efficiency ratio stays flat, and contribution
        margin declines. The widening gap shows attribution overlap. Illustrative shapes, no real values.
      </desc>
      <defs>
        <clipPath id="mer-reveal">
          <rect
            x="0"
            y="0"
            width="640"
            height="300"
            className="origin-left [transform-box:fill-box]"
            style={{ transform: drawn ? "scaleX(1)" : "scaleX(0)", transition: "transform 1600ms var(--ease-out-expo)" }}
          />
        </clipPath>
      </defs>

      <g className="font-mono" fontSize="11" letterSpacing="0.06em">
        <path d="M40 22 H64" className="stroke-night-text/80" strokeWidth="1.5" strokeDasharray="4 4" />
        <text x="72" y="26" className="fill-night-muted">
          PLATFORM-REPORTED ROAS
        </text>
        <path d="M300 22 H324" className="stroke-signal-bright" strokeWidth="2" />
        <text x="332" y="26" className="fill-night-text">
          BLENDED MER
        </text>
      </g>

      <g clipPath="url(#mer-reveal)">
        <polygon points={gapPolygon} className="fill-signal-bright/10" />
        <polyline points={roasPoints.join(" ")} className="fill-none stroke-night-text/80" strokeWidth="1.5" strokeDasharray="5 5" />
        <polyline points={merPoints.join(" ")} className="fill-none stroke-signal-bright" strokeWidth="2.25" />
        {contributionMargin.map((value, i) => (
          <rect key={i} x={left + i * step - 12} y={284 - value * 52} width="24" height={value * 52} rx="2" className="fill-night-muted/30" />
        ))}
      </g>

      <g className="transition-opacity duration-700" style={{ opacity: drawn ? 1 : 0, transitionDelay: "1100ms" }}>
        <path d={`M${lastX + 14} ${y(platformRoas.at(-1)!)} V${y(blendedMer.at(-1)!)}`} className="stroke-night-muted" />
        <path d={`M${lastX + 10} ${y(platformRoas.at(-1)!)} H${lastX + 18} M${lastX + 10} ${y(blendedMer.at(-1)!)} H${lastX + 18}`} className="stroke-night-muted" />
        <text x={lastX - 4} y={(y(platformRoas.at(-1)!) + y(blendedMer.at(-1)!)) / 2 + 4} textAnchor="end" className="fill-night-text" fontSize="12">
          Attribution gap
        </text>
      </g>

      <text x={left - 12} y="218" className="fill-night-muted font-mono" fontSize="10.5" letterSpacing="0.06em">
        CONTRIBUTION MARGIN ↓
      </text>
      <path d="M36 284 H604" className="stroke-night-line" />
    </svg>
  );
}
