"use client";

import * as React from "react";
import Image from "next/image";
import {
  Home,
  ClipboardCheck,
  Barcode,
  Brush,
  Sparkles,
  PenTool,
  Wind,
  ShieldCheck,
  Thermometer,
  ScanLine,
  Package,
  Ship,
} from "lucide-react";
import { FadeIn } from "@/components/magicui/fade-in";

const ICON_MAP: Record<string, React.ElementType> = {
  Home,
  ClipboardCheck,
  Barcode,
  Brush,
  Sparkles,
  PenTool,
  Wind,
  ShieldCheck,
  Thermometer,
  ScanLine,
  Package,
  Ship,
};

interface ProcessJourneyProps {
  steps: {
    step: number;
    title: string;
    description: string;
    icon: string;
    images?: readonly string[];
  }[];
}

function subscribeReducedMotion(callback: () => void) {
  const mql = window.matchMedia("(prefers-reduced-motion: reduce)");
  mql.addEventListener("change", callback);
  return () => mql.removeEventListener("change", callback);
}

function getReducedMotionSnapshot() {
  return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
}

function getReducedMotionServerSnapshot() {
  return false;
}

function useReducedMotion() {
  return React.useSyncExternalStore(
    subscribeReducedMotion,
    getReducedMotionSnapshot,
    getReducedMotionServerSnapshot,
  );
}

export function ProcessJourney({ steps }: ProcessJourneyProps) {
  const containerRef = React.useRef<HTMLDivElement>(null);
  const [progress, setProgress] = React.useState(0);
  const [thresholds, setThresholds] = React.useState<number[]>(() =>
    steps.map(() => Infinity),
  );
  const reduceMotion = useReducedMotion();

  /* ── Scroll-driven progress + per-step thresholds ── */
  React.useEffect(() => {
    if (reduceMotion) return;

    const container = containerRef.current;
    if (!container) return;

    let ticking = false;

    const update = () => {
      const rect = container.getBoundingClientRect();
      const viewCenter = window.innerHeight / 2;
      const p = (viewCenter - rect.top) / rect.height;
      setProgress(Math.max(0, Math.min(1, p)));

      // Derive per-step thresholds (step-circle centre / container height)
      const wrapperEls =
        container.querySelectorAll<HTMLElement>("[data-step-idx]");
      const ts: number[] = [];
      wrapperEls.forEach((el) => {
        // Walk the offsetParent chain: the FadeIn wrapper carries a CSS
        // transform, which makes it the offsetParent of the step wrapper,
        // so a single offsetTop read would be 0.
        let y = 26;
        let node: HTMLElement | null = el;
        while (node && node !== container) {
          y += node.offsetTop;
          node = node.offsetParent as HTMLElement | null;
        }
        ts.push(y / container.offsetHeight);
      });
      setThresholds((prev) =>
        prev.length === ts.length && ts.every((v, i) => v === prev[i])
          ? prev
          : ts.length > 0
            ? ts
            : steps.map(() => Infinity),
      );

      ticking = false;
    };

    const onScroll = () => {
      if (!ticking) {
        ticking = true;
        requestAnimationFrame(update);
      }
    };

    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll, { passive: true });
    update(); // set initial value
    return () => {
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("resize", onScroll);
    };
  }, [reduceMotion, steps]);

  const effectiveProgress = reduceMotion ? 1 : progress;

  return (
    <div ref={containerRef} className="relative">
      {/* Track line (always full height) */}
      <div className="absolute left-[26px] top-0 h-full w-px bg-gold/15 md:left-1/2 md:-translate-x-1/2" />

      {/* Gold progress line (fills top→bottom via scaleY) */}
      <div
        className="absolute left-[26px] top-0 h-full w-px origin-top bg-gold md:left-1/2 md:-translate-x-1/2"
        style={{ transform: `scaleY(${effectiveProgress})` }}
      />

      {/* Traveler marker — hidden when reduced-motion */}
      {!reduceMotion && (
        <div
          className="absolute left-[26px] z-20 -translate-x-1/2 -translate-y-1/2 md:left-1/2"
          style={{ top: `${progress * 100}%` }}
        >
          <div className="journey-sweep-x">
            <div className="journey-sweep-y">
              <div className="journey-face">
                <Image
                  src="/images/walet.png"
                  alt=""
                  width={48}
                  height={48}
                  aria-hidden="true"
                  className="-scale-x-100 select-none animate-bird-flap"
                  style={{
                    objectFit: "contain",
                    // Gold-silhouette recolor: the raw sketch is too pale to read at 48px over white cards
                    filter:
                      "brightness(0) invert(42%) sepia(35%) saturate(540%) hue-rotate(2deg) brightness(80%) contrast(90%) drop-shadow(0px 1px 1px rgba(255,255,255,0.8)) drop-shadow(0px 1px 2px rgba(0,0,0,0.2))",
                  }}
                />
              </div>
            </div>
          </div>
        </div>
      )}

      {/* Step cards */}
      <div className="space-y-0">
        {steps.map((step, index) => {
          const Icon = ICON_MAP[step.icon] ?? Home;
          const isLast = index === steps.length - 1;
          const reached =
            reduceMotion || effectiveProgress >= thresholds[index];
          const isEven = index % 2 === 0;

          return (
            <FadeIn key={step.step} delay={index * 50}>
              <div
                data-step-idx={index}
                className={`relative flex flex-col md:flex-row md:items-start md:justify-between ${isLast ? "pb-0" : "pb-12"
                  }`}
              >
                {/* Desktop Left Area */}
                <div className="hidden w-[calc(50%-3rem)] justify-end md:flex">
                  {isEven && (
                    <DesktopCard step={step} reached={reached} Icon={Icon} isEven={true} />
                  )}
                </div>

                {/* Number circle */}
                <div className="absolute left-[26px] top-0 z-10 flex h-[52px] w-[52px] -translate-x-1/2 flex-col items-center justify-center rounded-full bg-white md:left-1/2">
                  <div
                    className={`flex h-[52px] w-[52px] items-center justify-center rounded-full border-2 shadow-sm transition-colors duration-300 ${reached
                      ? "border-gold bg-gold"
                      : "border-gold/25 bg-white"
                      }`}
                  >
                    <span
                      className={`font-serif text-lg font-bold transition-colors duration-300 ${reached ? "text-white" : "text-gold"
                        }`}
                    >
                      {String(step.step).padStart(2, "0")}
                    </span>
                  </div>
                </div>

                {/* Desktop Right Area */}
                <div className="hidden w-[calc(50%-3rem)] justify-start md:flex">
                  {!isEven && (
                    <DesktopCard step={step} reached={reached} Icon={Icon} isEven={false} />
                  )}
                </div>

                {/* Mobile Layout (Visible only on mobile) */}
                <div className="flex w-full pl-[76px] md:hidden">
                  <MobileCard step={step} reached={reached} Icon={Icon} />
                </div>
              </div>
            </FadeIn>
          );
        })}
      </div>
    </div>
  );
}

function DesktopCard({
  step,
  reached,
  Icon,
  isEven,
}: {
  step: ProcessJourneyProps["steps"][number];
  reached: boolean;
  Icon: React.ElementType;
  isEven: boolean;
}) {
  return (
    <div
      className={`group flex w-full max-w-sm flex-col rounded-3xl border bg-white p-3 shadow-sm transition-all duration-500 hover:-translate-y-2 hover:shadow-xl ${reached ? "border-gold/40 shadow-gold/10" : "border-black/5"
      }`}
  >
    <div
      className={`relative h-56 w-full shrink-0 overflow-hidden rounded-2xl transition-all duration-700 ${reached ? "" : "opacity-60 grayscale"
        }`}
    >
      {step.images && step.images.length > 0 ? (
        <ImageCarousel images={step.images} title={step.title} />
      ) : (
          <div className="flex h-full w-full items-center justify-center bg-gold/10">
            <Icon className="h-12 w-12 text-gold/40" />
          </div>
        )}
        <div className="absolute inset-0 bg-gradient-to-t from-ink/80 via-ink/10 to-transparent opacity-80" />
        <div
          className={`absolute bottom-4 flex items-center gap-2 ${isEven ? "right-4 flex-row-reverse" : "left-4"
            }`}
        >
          <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-white/95 text-gold shadow-md backdrop-blur-md">
            <Icon className="h-4 w-4" />
          </div>
          <span className="font-serif text-lg font-bold text-white shadow-black drop-shadow-md">
            {step.title}
          </span>
        </div>
      </div>

      <div className={`mt-4 px-2 pb-2 ${isEven ? "text-right" : "text-left"}`}>
        <p className="text-sm leading-relaxed text-muted">
          {step.description}
        </p>
      </div>
    </div>
  );
}

function MobileCard({
  step,
  reached,
  Icon,
}: {
  step: ProcessJourneyProps["steps"][number];
  reached: boolean;
  Icon: React.ElementType;
}) {
  return (
    <div
    className={`group flex w-full flex-col gap-4 rounded-2xl border bg-white p-4 sm:flex-row sm:items-start shadow-sm transition-all duration-500 ${reached ? "border-gold/30 shadow-gold/5" : "border-black/5"
      }`}
  >
    {step.images && step.images.length > 0 ? (
      <div
        className={`relative h-40 w-full shrink-0 overflow-hidden rounded-xl transition-all duration-700 sm:h-20 sm:w-28 ${reached ? "" : "opacity-80 grayscale"
          }`}
      >
        <ImageCarousel images={step.images} title={step.title} />
        <div className="absolute bottom-2 left-2 flex h-6 w-6 items-center justify-center rounded-md bg-white/90 text-gold shadow-sm sm:bottom-1 sm:left-1 z-20">
          <Icon className="h-3.5 w-3.5" />
        </div>
      </div>
    ) : (
        <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-gold/8 text-gold">
          <Icon className="h-5 w-5" />
        </div>
      )}

      <div className="flex-1 pt-0.5">
        <h3 className="font-serif text-base font-bold text-ink sm:text-lg">
          {step.title}
        </h3>
        <p className="mt-1.5 text-sm leading-relaxed text-muted">
          {step.description}
        </p>
      </div>
    </div>
  );
}

function ImageCarousel({ images, title }: { images: readonly string[]; title: string }) {
  const [currentIdx, setCurrentIdx] = React.useState(0);

  React.useEffect(() => {
    if (images.length <= 1) return;
    const interval = setInterval(() => {
      setCurrentIdx((prev) => (prev + 1) % images.length);
    }, 3000);
    return () => clearInterval(interval);
  }, [images]);

  return (
    <>
      {images.map((src, idx) => (
        <Image
          key={src}
          src={src}
          alt={`${title} - image ${idx + 1}`}
          fill
          className={`object-cover transition-opacity duration-1000 group-hover:scale-110 ${idx === currentIdx ? "opacity-100" : "opacity-0"}`}
          sizes="(max-width: 768px) 100vw, 400px"
        />
      ))}
      {/* Optional Dots Indicator */}
      {images.length > 1 && (
        <div className="absolute bottom-2 left-1/2 flex -translate-x-1/2 gap-1.5 z-10">
          {images.map((_, idx) => (
            <div
              key={idx}
              className={`h-1.5 w-1.5 rounded-full transition-all duration-300 ${
                idx === currentIdx ? "bg-white scale-110 w-3" : "bg-white/50"
              }`}
            />
          ))}
        </div>
      )}
    </>
  );
}
