"use client";

/**
 * TESTIMONIALS — an interactive, auto-advancing carousel that feels substantial.
 *   - 6 sample testimonials, one large featured quote at a time, with a
 *     monogram avatar, name, role, company and a result chip.
 *   - Auto-advances every ~6s; pauses on hover/focus-within and when offscreen
 *     or the tab is hidden. Manual prev/next buttons + clickable dots.
 *   - A thumbnail rail of all clients (monogram avatars) doubles as navigation;
 *     the active one is highlighted.
 *   - Slides crossfade/slide with Motion (AnimatePresence) using the page's
 *     EASE curves; direction-aware.
 *   - Fully keyboard accessible: real <button>s, arrow-key support, aria-live
 *     announces the active slide, aria-roledescription="carousel".
 *   - prefers-reduced-motion: no auto-advance, instant slide swaps.
 */
import { useCallback, useEffect, useRef, useState } from "react";
import { AnimatePresence, motion, useReducedMotion } from "motion/react";
import Reveal from "./Reveal";
import { testimonials } from "../content";
import { EASE_OUT } from "./motion";

const AUTOPLAY_MS = 6000;

export default function Testimonials() {
  const reduce = useReducedMotion();
  const [[index, dir], setState] = useState<[number, number]>([0, 0]);
  const [paused, setPaused] = useState(false);
  const rootRef = useRef<HTMLElement>(null);
  const inView = useRef(true);

  const count = testimonials.length;
  const go = useCallback(
    (next: number, direction: number) => {
      setState([(next + count) % count, direction]);
    },
    [count]
  );
  const next = useCallback(() => go(index + 1, 1), [go, index]);
  const prev = useCallback(() => go(index - 1, -1), [go, index]);

  // autoplay — paused on hover/focus, offscreen, hidden tab, reduced-motion
  useEffect(() => {
    if (reduce) return;
    const el = rootRef.current;
    if (!el) return;

    const io = new IntersectionObserver(
      ([e]) => {
        inView.current = e.isIntersecting;
      },
      { threshold: 0.25 }
    );
    io.observe(el);

    const id = window.setInterval(() => {
      if (paused || !inView.current || document.hidden) return;
      setState(([i]) => [(i + 1) % count, 1]);
    }, AUTOPLAY_MS);

    return () => {
      io.disconnect();
      window.clearInterval(id);
    };
  }, [reduce, paused, count]);

  // keyboard arrows when the carousel has focus
  const onKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === "ArrowRight") {
      e.preventDefault();
      next();
    } else if (e.key === "ArrowLeft") {
      e.preventDefault();
      prev();
    }
  };

  const t = testimonials[index];

  const variants = {
    enter: (d: number) =>
      reduce
        ? { opacity: 0 }
        : { opacity: 0, x: d > 0 ? 60 : -60, filter: "blur(6px)" },
    center: { opacity: 1, x: 0, filter: "blur(0px)" },
    exit: (d: number) =>
      reduce
        ? { opacity: 0 }
        : { opacity: 0, x: d > 0 ? -60 : 60, filter: "blur(6px)" },
  };

  return (
    <section
      ref={rootRef}
      className="quotes frame"
      aria-labelledby="quotes-h"
      onMouseEnter={() => setPaused(true)}
      onMouseLeave={() => setPaused(false)}
      onFocusCapture={() => setPaused(true)}
      onBlurCapture={() => setPaused(false)}
    >
      <div className="wrap">
        <header className="sec-head">
          <p className="kicker">
            <span className="kicker__dot" />
            In their words — sample
          </p>
          <Reveal as="h2" variant="clip">
            <span id="quotes-h" className="display sec-head__title">
              The number is the point
            </span>
          </Reveal>
        </header>

        <div
          className="carousel"
          role="group"
          aria-roledescription="carousel"
          aria-label="Client testimonials"
          tabIndex={0}
          onKeyDown={onKeyDown}
        >
          <div className="carousel__stage">
            {/* decorative oversized quote mark */}
            <span className="carousel__mark display" aria-hidden="true">
              &ldquo;
            </span>

            <AnimatePresence mode="wait" custom={dir} initial={false}>
              <motion.figure
                key={index}
                className="carousel__slide"
                custom={dir}
                variants={variants}
                initial="enter"
                animate="center"
                exit="exit"
                transition={{ duration: reduce ? 0.2 : 0.55, ease: EASE_OUT }}
                aria-roledescription="slide"
                aria-label={`${index + 1} of ${count}`}
              >
                <blockquote className="carousel__quote display">
                  {t.quote}
                </blockquote>
                <figcaption className="carousel__by">
                  <span className="carousel__avatar">
                    {/* eslint-disable-next-line @next/next/no-img-element */}
                    <img
                      src={t.avatar}
                      alt=""
                      width={64}
                      height={64}
                      loading="lazy"
                      style={{ width: "100%", height: "100%", objectFit: "cover", borderRadius: "50%", display: "block" }}
                    />
                  </span>
                  <span className="carousel__id">
                    <span className="carousel__name">{t.name}</span>
                    <span className="carousel__role">
                      {t.role}, {t.company}
                    </span>
                  </span>
                  <span className="carousel__chip">{t.metric}</span>
                </figcaption>
              </motion.figure>
            </AnimatePresence>
          </div>

          {/* controls */}
          <div className="carousel__controls">
            <button
              type="button"
              className="carousel__arrow"
              onClick={prev}
              aria-label="Previous testimonial"
              data-cursor="Prev"
            >
              <svg viewBox="0 0 24 24" width="20" height="20" aria-hidden="true">
                <path
                  d="M15 5l-7 7 7 7"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="2"
                  strokeLinecap="round"
                  strokeLinejoin="round"
                />
              </svg>
            </button>

            <ul className="carousel__dots" role="tablist" aria-label="Choose testimonial">
              {testimonials.map((tt, i) => (
                <li key={tt.name} role="presentation">
                  <button
                    type="button"
                    role="tab"
                    aria-selected={i === index}
                    aria-label={`${tt.name}, ${tt.company}`}
                    className={`carousel__dot ${i === index ? "is-active" : ""}`}
                    onClick={() => go(i, i > index ? 1 : -1)}
                  />
                </li>
              ))}
            </ul>

            <button
              type="button"
              className="carousel__arrow"
              onClick={next}
              aria-label="Next testimonial"
              data-cursor="Next"
            >
              <svg viewBox="0 0 24 24" width="20" height="20" aria-hidden="true">
                <path
                  d="M9 5l7 7-7 7"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="2"
                  strokeLinecap="round"
                  strokeLinejoin="round"
                />
              </svg>
            </button>
          </div>
        </div>

        {/* avatar rail — all clients; doubles as quick nav */}
        <ul className="carousel__rail" aria-hidden="true">
          {testimonials.map((tt, i) => (
            <li key={tt.name}>
              <button
                type="button"
                tabIndex={-1}
                className={`carousel__railitem ${i === index ? "is-active" : ""}`}
                onClick={() => go(i, i > index ? 1 : -1)}
              >
                <span className="carousel__railmono">
                  {/* eslint-disable-next-line @next/next/no-img-element */}
                  <img
                    src={tt.avatar}
                    alt=""
                    width={44}
                    height={44}
                    loading="lazy"
                    style={{ width: "100%", height: "100%", objectFit: "cover", borderRadius: "50%", display: "block" }}
                  />
                </span>
                <span className="carousel__railname">{tt.company}</span>
              </button>
            </li>
          ))}
        </ul>

        {/* live region for screen readers */}
        <p className="sr-only" aria-live="polite">
          Testimonial {index + 1} of {count}: {t.name}, {t.role} at {t.company}.
        </p>
      </div>
    </section>
  );
}
