"use client";

/**
 * CASE CARD — replaces the rejected repetitive photos with a coded, animated
 * data visual unique per case:
 *   - 3D tilt that tracks the pointer via a SOFT spring (momentum => the card
 *     floats and settles, never snaps). Transform-only.
 *   - A small lift + accent shadow on hover; a press dip (scale 0.985) so the
 *     whole card shares the page's tactile press language.
 *   - An animated bars + sparkline "result chart" (CSS + GSAP DrawSVG on the
 *     spark) growing into view — no two cards look alike.
 *   - A glare/sheen that follows the cursor across the surface.
 *   - The chart panel gets a clip-path inset() wipe on first view (premium).
 *   Reduced-motion / touch: flat card, bars still grow on view via CSS.
 */
import { useEffect, useRef } from "react";
import {
  motion,
  useMotionValue,
  useSpring,
  useTransform,
  useReducedMotion,
} from "motion/react";
import { gsap } from "./gsap";
import { SPRING, EASE_OUT } from "./motion";

export type CaseData = {
  tag: string;
  problem: string;
  result: string;
  how: string;
  metricNum: string;
  metricLabel: string;
  bars: number[]; // 0..100 heights — unique per case
  accent: string; // brand accent for this card
};

export default function CaseCard({
  data,
  index,
}: {
  data: CaseData;
  index: number;
}) {
  const reduce = useReducedMotion();
  const ref = useRef<HTMLDivElement>(null);
  const mx = useMotionValue(0.5);
  const my = useMotionValue(0.5);
  const rx = useSpring(useTransform(my, [0, 1], [6, -6]), SPRING.tilt);
  const ry = useSpring(useTransform(mx, [0, 1], [-8, 8]), SPRING.tilt);
  const glare = useTransform(
    [mx, my],
    ([gx, gy]: number[]) =>
      `radial-gradient(circle at ${gx * 100}% ${gy * 100}%, rgba(255,255,255,0.16), transparent 45%)`
  );

  const onMove = (e: React.PointerEvent) => {
    if (reduce || e.pointerType !== "mouse") return;
    const el = ref.current;
    if (!el) return;
    const r = el.getBoundingClientRect();
    mx.set((e.clientX - r.left) / r.width);
    my.set((e.clientY - r.top) / r.height);
  };
  const reset = () => {
    mx.set(0.5);
    my.set(0.5);
  };

  // DrawSVG the sparkline once the card scrolls in — a small, deliberate detail.
  useEffect(() => {
    const el = ref.current;
    if (!el || reduce) return;
    const ctx = gsap.context(() => {
      gsap.from(el.querySelector(".case__spark polyline"), {
        drawSVG: "0%",
        duration: 1.1,
        ease: "power2.out",
        scrollTrigger: { trigger: el, start: "top 82%", once: true },
        delay: 0.15 + index * 0.05,
      });
    }, el);
    return () => ctx.revert();
  }, [reduce, index]);

  return (
    <motion.article
      ref={ref}
      className="case"
      onPointerMove={onMove}
      onPointerLeave={reset}
      style={
        reduce
          ? undefined
          : { rotateX: rx, rotateY: ry, transformPerspective: 1100 }
      }
      initial={reduce ? { opacity: 1 } : { opacity: 0, y: 44, filter: "blur(4px)" }}
      whileInView={{ opacity: 1, y: 0, filter: "blur(0px)" }}
      whileTap={reduce ? undefined : { scale: 0.985 }}
      viewport={{ once: true, margin: "0px 0px -12% 0px" }}
      transition={{ duration: 0.85, delay: index * 0.08, ease: EASE_OUT }}
    >
      <div
        className="case__inner"
        style={{ ["--case-accent" as string]: data.accent }}
      >
        <div className="case__head">
          <span className="case__no">{String(index + 1).padStart(2, "0")}</span>
          <span className="case__tag">{data.tag}</span>
        </div>

        {/* coded data visual — unique bars per case, clip-wiped on first view */}
        <motion.div
          className="case__viz"
          aria-hidden="true"
          initial={reduce ? { opacity: 1 } : { clipPath: "inset(0 0 100% 0)" }}
          whileInView={{ clipPath: "inset(0 0 0% 0)" }}
          viewport={{ once: true, margin: "0px 0px -10% 0px" }}
          transition={{ duration: 0.9, delay: index * 0.08 + 0.1, ease: EASE_OUT }}
        >
          <div className="case__bars">
            {data.bars.map((h, i) => (
              <span
                key={i}
                className="case__bar"
                style={{
                  ["--h" as string]: `${h}%`,
                  ["--d" as string]: `${i * 70}ms`,
                }}
              />
            ))}
          </div>
          <svg className="case__spark" viewBox="0 0 120 40" preserveAspectRatio="none">
            <polyline
              points="0,34 24,30 48,22 72,18 96,8 120,4"
              fill="none"
              stroke="var(--case-accent)"
              strokeWidth="2"
              strokeLinecap="round"
            />
          </svg>
        </motion.div>

        <div className="case__body">
          <p className="case__problem">
            <span className="case__k">Before</span>
            {data.problem}
          </p>
          <p className="case__result display">{data.result}</p>
          <p className="case__how">{data.how}</p>
        </div>

        <div className="case__metric">
          <span className="case__metric-num display">{data.metricNum}</span>
          <span className="case__metric-lab">{data.metricLabel}</span>
        </div>

        {!reduce && (
          <motion.span
            className="case__glare"
            aria-hidden="true"
            style={{ background: glare }}
          />
        )}
      </div>
    </motion.article>
  );
}
