"use client";

import { useEffect, useRef, useState } from "react";
import Image from "next/image";
import Link from "next/link";
import type { FeatureCard } from "./expanding-cards";

/**
 * Static 3-up grid (the "From Insights to Action" row). Each card slides its
 * title up and reveals its description when active — hover/focus on desktop,
 * the viewport-centred card on touch. Cards are paginated `perPage` at a time
 * with dots, and each card links to its post.
 */
export function FeatureGrid({
  cards,
  perPage = 3,
}: {
  cards: FeatureCard[];
  perPage?: number;
}) {
  const [page, setPage] = useState(0);
  const [active, setActive] = useState(-1);
  const [dir, setDir] = useState<"next" | "prev">("next");
  const firstRender = useRef(true);
  const cardRefs = useRef<(HTMLElement | null)[]>([]);

  const pageCount = Math.ceil(cards.length / perPage);
  const start = page * perPage;
  const pageCards = cards.slice(start, start + perPage);

  // Navigate to a page, remembering the travel direction so the incoming cards
  // slide in from the correct side (next → from right, prev → from left).
  const goTo = (i: number) => {
    if (i === page) return;
    setDir(i > page ? "next" : "prev");
    setPage(i);
  };

  // Don't animate the very first paint — only subsequent page changes.
  useEffect(() => {
    firstRender.current = false;
  }, []);

  // The incoming row animates in from the side; `key={page}` remounts it so the
  // animation replays on every change (including rapid same-direction).
  const slideClass = firstRender.current
    ? ""
    : dir === "next"
      ? "slide-in-next"
      : "slide-in-prev";

  // On narrow screens, mark whichever card is nearest the viewport centre.
  useEffect(() => {
    // Auto-hover first card when page changes
    setActive(0);
    cardRefs.current = [];

    let raf = 0;
    const update = () => {
      if (window.innerWidth >= 768) return;
      const mid = window.innerHeight / 2;
      let best = -1;
      let bestDist = Infinity;
      cardRefs.current.forEach((el, i) => {
        if (!el) return;
        const r = el.getBoundingClientRect();
        const dist = Math.abs(r.top + r.height / 2 - mid);
        if (dist < bestDist) {
          bestDist = dist;
          best = i;
        }
      });
      setActive(best);
    };
    const onScroll = () => {
      cancelAnimationFrame(raf);
      raf = requestAnimationFrame(update);
    };
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    update();
    return () => {
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("resize", onScroll);
      cancelAnimationFrame(raf);
    };
  }, [page]);

  return (
    <div className="relative">
      <style>{`
        @keyframes slideInFromRight {
          from { opacity: 0; transform: translateX(100%); }
          to { opacity: 1; transform: translateX(0); }
        }
        @keyframes slideInFromLeft {
          from { opacity: 0; transform: translateX(-100%); }
          to { opacity: 1; transform: translateX(0); }
        }
        .slide-in-next {
          animation: slideInFromRight 1500ms cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
        }
        .slide-in-prev {
          animation: slideInFromLeft 1500ms cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
        }
      `}</style>
      {/* overflow-x-clip hides the incoming slide horizontally without clipping
          card shadows vertically or the arrows that sit outside this box. */}
      <div className="overflow-x-clip">
        <div
          key={page}
          className={`grid gap-6 sm:grid-cols-2 lg:grid-cols-3 ${slideClass}`}
        >
          {pageCards.map((card, i) => {
          const isActive = i === active;
          return (
            <article
              key={`${card.title}-${start + i}`}
              ref={(el) => {
                cardRefs.current[i] = el;
              }}
              onMouseEnter={() => setActive(i)}
              onFocus={() => setActive(i)}
              tabIndex={0}
              aria-expanded={isActive}
              className="group relative h-[24rem] overflow-hidden rounded-[1.75rem] border border-line shadow-soft focus:outline-none focus-visible:ring-2 focus-visible:ring-leaf sm:h-[30rem]"
            >
              {/* background — uploaded image or gradient fallback */}
              {card.image ? (
                <Image
                  src={card.image}
                  alt={card.title}
                  fill
                  sizes="(min-width: 1024px) 33vw, (min-width: 640px) 50vw, 100vw"
                  className={`object-cover transition-transform duration-700 ease-out ${
                    isActive ? "scale-105" : "scale-100"
                  }`}
                />
              ) : (
                <div className={`absolute inset-0 ${card.gradient}`} />
              )}

              {/* readability scrim */}
              <div className="absolute inset-0 bg-gradient-to-b from-black/45 via-black/5 to-black/80" />

              {/* label badge */}
              {card.label ? (
                <span
                  className={`absolute left-5 top-5 z-20 inline-block rounded-full px-3.5 py-1.5 text-xs font-semibold text-white backdrop-blur ${card.badgeTint}`}
                >
                  {card.label}
                </span>
              ) : null}

              {/* title — slides up under the label when active, else rests near
                  the bottom. Clamped so long blog titles never hit the label. */}
              <h3
                className={`absolute inset-x-0 z-10 line-clamp-3 px-5 font-display text-xl font-bold leading-tight text-white drop-shadow transition-all duration-500 ease-in-out sm:px-6 sm:text-2xl ${
                  isActive ? "top-[4.5rem]" : "top-[calc(100%_-_7rem)]"
                }`}
              >
                {card.title}
              </h3>

              {/* description — fades in on the active card; clamped on mobile */}
              {card.description ? (
                <div
                  className={`absolute inset-x-0 bottom-0 z-10 p-5 transition-opacity duration-500 delay-100 sm:p-6 ${
                    isActive ? "opacity-100" : "pointer-events-none opacity-0"
                  }`}
                >
                  <p className="max-w-[24rem] text-[15px] leading-relaxed text-white line-clamp-4 drop-shadow-[0_1px_8px_rgba(0,0,0,0.55)] sm:text-base sm:line-clamp-none">
                    {card.description}
                  </p>
                </div>
              ) : null}

              {/* Stretched link — whole card opens the post. */}
              {card.href ? (
                <Link href={card.href} aria-label={card.title} className="absolute inset-0 z-30" />
              ) : null}
            </article>
          );
        })}
        </div>
      </div>

      {/* Pagination dots — active = filled dot inside a ring, inactive = plain dot */}
      {pageCount > 1 ? (
        <div className="mt-7 flex items-center justify-end gap-2.5 pr-1">
          {Array.from({ length: pageCount }).map((_, i) => (
            <button
              key={i}
              type="button"
              onClick={() => goTo(i)}
              aria-label={`Go to page ${i + 1}`}
              aria-current={i === page}
              className="relative flex h-[18px] w-[18px] items-center justify-center rounded-full focus:outline-none focus-visible:ring-2 focus-visible:ring-ink/40"
            >
              {i === page ? (
                <span className="absolute inset-0 rounded-full border-2 border-black" />
              ) : null}
              <span
                className={`rounded-full bg-black transition-all duration-300 ${
                  i === page ? "h-[7px] w-[7px]" : "h-2 w-2"
                }`}
              />
            </button>
          ))}
        </div>
      ) : null}

      {/* Left arrow — simple dark circle style */}
      {pageCount > 1 ? (
        <button
          type="button"
          onClick={() => goTo(Math.max(0, page - 1))}
          disabled={page === 0}
          aria-label="Previous page"
          className="absolute left-0 top-1/2 -translate-y-1/2 -translate-x-16 flex h-10 w-10 items-center justify-center rounded-full bg-black/60 transition-all disabled:opacity-30 enabled:hover:bg-black focus:outline-none focus-visible:ring-2 focus-visible:ring-ink/40"
        >
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round">
            <path d="M15 19l-7-7 7-7" />
          </svg>
        </button>
      ) : null}

      {/* Right arrow — simple dark circle style */}
      {pageCount > 1 ? (
        <button
          type="button"
          onClick={() => goTo(Math.min(pageCount - 1, page + 1))}
          disabled={page === pageCount - 1}
          aria-label="Next page"
          className="absolute right-0 top-1/2 -translate-y-1/2 translate-x-16 flex h-10 w-10 items-center justify-center rounded-full bg-black/60 transition-all disabled:opacity-30 enabled:hover:bg-black focus:outline-none focus-visible:ring-2 focus-visible:ring-ink/40"
        >
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round">
            <path d="M9 19l7-7-7-7" />
          </svg>
        </button>
      ) : null}
    </div>
  );
}
