"use client";

import SectionBackdrop from "@/components/ui/SectionBackdrop";
import { useEffect, useRef, useState } from "react";
import { Check } from "lucide-react";
import { processSteps } from "@/lib/content";
import { useReveal } from "@/hooks/use-reveal";

/**
 * One deterministic animation timeline. `stage` is the only piece of animation state:
 * every visual (progress segments, number cards, titles, descriptions, glow) is derived
 * from it, so nothing can drift out of sync.
 *
 * `active` = the step currently highlighted, `target` = how far the blue line has travelled.
 * The line moves first (stages 1, 3, 5), then the step it reaches activates (stages 2, 4, 6).
 */
const SEQUENCE = [
  { active: 0, target: 0, hold: 700 }, // 01 activates
  { active: 0, target: 1, hold: 1100 }, // line travels 01 → 02
  { active: 1, target: 1, hold: 700 }, // 02 activates
  { active: 1, target: 2, hold: 1100 }, // 02 → 03
  { active: 2, target: 2, hold: 700 }, // 03 activates
  { active: 2, target: 3, hold: 1100 }, // 03 → 04
  { active: 3, target: 3, hold: 0 }, // 04 activates — complete
] as const;

const LAST = SEQUENCE.length - 1;

export default function Process() {
  const { ref: headRef, visible: headVisible } = useReveal<HTMLDivElement>();
  const listRef = useRef<HTMLOListElement>(null);
  const [stage, setStage] = useState(-1);

  // Start the sequence once, when ~a third of the timeline is on screen.
  useEffect(() => {
    const el = listRef.current;
    if (!el) return;

    const timers: ReturnType<typeof setTimeout>[] = [];
    let started = false;

    function start() {
      if (started) return;
      started = true;
      if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
        setStage(LAST);
        return;
      }
      // Absolute offsets scheduled up-front, so timers cannot drift relative to each other.
      let offset = 250;
      SEQUENCE.forEach((s, i) => {
        timers.push(setTimeout(() => setStage(i), offset));
        offset += s.hold;
      });
    }

    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry.isIntersecting) {
          observer.disconnect();
          start();
        }
      },
      { threshold: 0.35 },
    );
    observer.observe(el);

    return () => {
      observer.disconnect();
      timers.forEach(clearTimeout);
    };
  }, []);

  const current = stage >= 0 ? SEQUENCE[stage] : null;
  const active = current ? current.active : -1;
  const target = current ? current.target : -1;
  const complete = stage === LAST;

  const enter = (delay: number) => ({
    className: headVisible ? "animate-fade-up" : "opacity-0",
    style: { animationDelay: `${delay}ms` },
  });

  return (
    <section
      id="process"
      className="relative scroll-mt-24 overflow-x-clip py-20 sm:py-24 lg:py-32"
    >
      <ProcessBackground />

      <div className="container">
        <div ref={headRef} className="mx-auto max-w-3xl text-center">
          <p
            className={`inline-flex items-center gap-2 text-xs font-semibold uppercase tracking-[0.24em] text-accent-600 ${enter(0).className}`}
            style={enter(0).style}
          >
            <span className="h-1.5 w-1.5 rounded-full bg-accent" />
            Our Process
          </p>
          <h2
            className={`mt-5 font-display text-[2rem] font-bold leading-[1.12] tracking-tight text-[#0F172A] sm:text-4xl lg:text-[2.9rem] ${enter(100).className}`}
            style={enter(100).style}
          >
            From first idea{" "}
            <span className="relative inline-block text-accent">
              to continuous improvement.
              <svg
                viewBox="0 0 300 12"
                preserveAspectRatio="none"
                className="absolute -bottom-1.5 left-0 h-2.5 w-full text-accent/40"
                fill="none"
                aria-hidden="true"
              >
                <path
                  d="M2 9C60 3 240 3 298 7"
                  stroke="currentColor"
                  strokeWidth="3"
                  strokeLinecap="round"
                />
              </svg>
            </span>
          </h2>
          <p
            className={`mx-auto mt-6 max-w-xl text-base leading-[1.75] text-ink-300 sm:text-lg ${enter(220).className}`}
            style={enter(220).style}
          >
            Four connected stages keep every product focused, stable and always
            improving.
          </p>
        </div>

        <ol
          ref={listRef}
          className="relative mx-auto mt-16 flex max-w-6xl flex-col lg:mt-20 lg:grid lg:grid-cols-4"
        >
          {processSteps.map((step, i) => (
            <ProcessStep
              key={step.step}
              step={step}
              index={i}
              isLast={i === processSteps.length - 1}
              status={active < i ? "pending" : active === i ? "active" : "done"}
              filled={target > i}
              complete={complete}
            />
          ))}
        </ol>
      </div>
    </section>
  );
}

type Status = "pending" | "active" | "done";

function ProcessStep({
  step,
  index,
  isLast,
  status,
  filled,
  complete,
}: {
  step: (typeof processSteps)[number];
  index: number;
  isLast: boolean;
  status: Status;
  filled: boolean;
  complete: boolean;
}) {
  const reached = status !== "pending";

  return (
    <li
      className={`relative flex gap-5 lg:flex-col lg:items-center lg:gap-0 lg:px-4 lg:text-center ${
        isLast ? "" : "pb-10 lg:pb-0"
      }`}
      aria-current={status === "active" ? "step" : undefined}
    >
      {/* Line segment from this card's centre to the next card's centre */}
      {!isLast && (
        <span
          aria-hidden="true"
          className="absolute left-7 top-7 h-full w-0.5 -translate-x-1/2 overflow-hidden rounded-full bg-slate-200 lg:left-1/2 lg:top-8 lg:h-0.5 lg:w-full lg:translate-x-0 lg:-translate-y-1/2"
        >
          <span
            className={`block h-full w-full origin-top rounded-full bg-linear-to-b from-accent to-accent-400 transition-transform duration-1000 ease-[cubic-bezier(0.65,0,0.35,1)] lg:origin-left lg:bg-linear-to-r ${
              filled
                ? "scale-y-100 lg:scale-x-100"
                : "scale-y-0 lg:scale-x-0 lg:scale-y-100"
            }`}
          />
        </span>
      )}

      {/* Number card */}
      <div className="relative z-10 shrink-0">
        {status === "active" && (
          <span
            aria-hidden="true"
            className="pointer-events-none absolute inset-0 animate-step-ring rounded-[17px] border-2 border-accent"
          />
        )}
        <div
          className={`relative flex h-14 w-14 items-center justify-center rounded-[17px] border bg-white font-mono text-lg font-semibold transition-[color,border-color,box-shadow,background-color] duration-250 ease-in-out lg:h-16 lg:w-16 lg:text-xl ${
            status === "active"
              ? "animate-step-pop border-accent/50 text-accent shadow-[0_0_0_4px_rgba(0,148,238,0.1),0_14px_34px_-10px_rgba(0,148,238,0.55)]"
              : status === "done"
                ? "border-accent/25 bg-accent-50/70 text-accent-600 shadow-card"
                : "border-slate-200 text-ink-400 shadow-card"
          }`}
        >
          {step.step}
          {isLast && (
            <span
              aria-hidden="true"
              className={`absolute -right-2 -top-2 flex h-6 w-6 items-center justify-center rounded-full bg-accent text-white shadow-[0_4px_10px_-2px_rgba(0,148,238,0.6)] transition-all duration-500 ease-out ${
                complete
                  ? "scale-100 opacity-100 delay-300"
                  : "scale-75 opacity-0"
              }`}
            >
              <Check className="h-3.5 w-3.5" strokeWidth={3} />
            </span>
          )}
        </div>
      </div>

      {/* Copy */}
      <div className="min-w-0 pt-1 lg:mt-7 lg:pt-0">
        <h3
          className={`font-display text-lg font-semibold tracking-tight transition-all duration-500 ease-out ${
            reached
              ? "translate-y-0 text-[#0F172A] opacity-100"
              : "translate-y-1.5 text-slate-600 opacity-70"
          }`}
        >
          {step.title}
        </h3>
        <span
          aria-hidden="true"
          className={`mt-2 block h-0.5 rounded-full bg-linear-to-r from-accent to-accent-300 transition-all duration-500 ease-out lg:mx-auto ${
            status === "active" ? "w-10 opacity-100" : "w-0 opacity-0"
          }`}
        />
        <p
          className={`mt-2 max-w-[18rem] text-sm leading-[1.7] text-ink-300 transition-all delay-150 duration-500 ease-out lg:mx-auto ${
            reached ? "translate-y-0 opacity-100" : "translate-y-1 opacity-75"
          }`}
        >
          {step.description}
        </p>
      </div>
      <span className="sr-only">{`Step ${index + 1} of ${processSteps.length}`}</span>
    </li>
  );
}

function ProcessBackground() {
  return <SectionBackdrop variant="sideRight" />;
}
