"use client";

import Image from "next/image";
import { Fragment, useEffect, useRef } from "react";
import { motion, Variants } from "framer-motion";
import { useGetTestimonialsQuery } from "@/api/testimonial.api";

export default function Testimonials() {
  const { data } = useGetTestimonialsQuery();
  const testimonials = data?.data ?? [];

  const trackRef = useRef<HTMLDivElement>(null);
  const animRef = useRef<number>(0);
  const posRef = useRef(0);
  const pausedRef = useRef(false);
  const SPEED = 0.4;

  useEffect(() => {
    const track = trackRef.current;
    if (!track || testimonials.length === 0) return;

    const secondCopyEl = track.children[testimonials.length] as HTMLElement | undefined;
    const wrap = secondCopyEl
      ? secondCopyEl.offsetLeft - track.offsetLeft
      : track.scrollWidth / 2;

    const tick = () => {
      if (!pausedRef.current) {
        posRef.current += SPEED;
        if (posRef.current >= wrap) posRef.current -= wrap;
        track.style.transform = `translateX(-${posRef.current}px)`;
      }
      animRef.current = requestAnimationFrame(tick);
    };
    animRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(animRef.current);
  }, [testimonials.length]);

  const lineContainerVariants: Variants = {
    hidden: {},
    visible: { transition: { staggerChildren: 0.025 } },
  };

  const letterVariants: Variants = {
    hidden: { y: "100%", opacity: 0 },
    // Delay is driven by the letter's global index so the per-letter stagger is
    // identical to the previous staggerChildren timing, even though letters are
    // now nested inside non-breaking word wrappers.
    visible: (i: number) => ({
      y: 0,
      opacity: 1,
      transition: { duration: 0.55, ease: [0.22, 1, 0.36, 1], delay: i * 0.025 },
    }),
  };

  const titleVariants: Variants = {
    hidden: {},
    visible: { transition: { staggerChildren: 0.025 } },
  };

  const sliderVariants: Variants = {
    hidden: { opacity: 0, y: 40 },
    visible: {
      opacity: 1,
      y: 0,
      transition: { duration: 0.6, ease: "easeOut" },
    },
  };

  if (testimonials.length === 0) return null;

  const CARDS = [...testimonials, ...testimonials];
  const TITLE = "Trusted by Seafarers Worldwide";

  return (
    <section className="w-full bg-white py-16 overflow-x-hidden font-sans flex flex-col items-center gap-10">
      {/* Title */}
      <motion.div
        className="w-full max-w-278 px-6"
        variants={titleVariants}
        initial="hidden"
        whileInView="visible"
        viewport={{ once: true, amount: 0.5 }}
      >
        <motion.h2
          aria-label={TITLE}
          className="text-center font-bold font-['Inter'] text-[38.4px] leading-[57.6px] text-[#07121F] overflow-hidden"
          variants={lineContainerVariants}
        >
          {TITLE.split(" ").map((word, wi, words) => {
            // Global index of this word's first letter within TITLE (each
            // preceding word contributes its length + 1 for the space).
            const start = words
              .slice(0, wi)
              .reduce((acc, w) => acc + w.length + 1, 0);
            return (
              <Fragment key={wi}>
                {/* Whole word stays on one line — only the spaces between words break.
                    motion.span (not a plain span) so the visible state propagates to letters. */}
                <motion.span className="inline-block whitespace-nowrap">
                  {Array.from(word).map((char, ci) => (
                    <motion.span
                      key={ci}
                      custom={start + ci}
                      variants={letterVariants}
                      className="inline-block"
                    >
                      {char}
                    </motion.span>
                  ))}
                </motion.span>
                {wi < words.length - 1 ? " " : null}
              </Fragment>
            );
          })}
        </motion.h2>
      </motion.div>

      {/* Infinite marquee */}
      <motion.div
        className="w-full overflow-hidden"
        variants={sliderVariants}
        initial="hidden"
        whileInView="visible"
        viewport={{ once: true, amount: 0.2 }}
        onMouseEnter={() => { pausedRef.current = true; }}
        onMouseLeave={() => { pausedRef.current = false; }}
        onTouchStart={() => { pausedRef.current = true; }}
        onTouchEnd={() => { pausedRef.current = false; }}
        onTouchCancel={() => { pausedRef.current = false; }}
      >
        <div
          ref={trackRef}
          className="flex gap-5 will-change-transform w-max"
        >
          {[...CARDS, ...CARDS].map((item, i) => (
            <div
              key={`${item.id}-${i}`}
              className="shrink-0 w-85 bg-white rounded-2xl p-7 flex flex-col gap-4 border border-[#F0F0F0] shadow-[0px_4px_28px_rgba(0,0,0,0.09)]"
            >
              {/* Quote icon */}
              <div className="size-8 shrink-0 overflow-hidden">
                <Image
                  src="/assets/images/quote.svg"
                  alt="Quote"
                  width={32}
                  height={32}
                />
              </div>

              {/* Quote text */}
              <p className="flex-1 font-['Inter'] font-normal text-[15.2px] leading-6.25 text-[#364153]">
                {item.content}
              </p>

              {/* Author */}
              <div className="flex items-center gap-3 pt-2 border-t border-[#F3F4F6]">
                <div className="size-10 rounded-full overflow-hidden shrink-0">
                  <Image
                    src={item.image.filePath}
                    alt={item.name}
                    width={40}
                    height={40}
                    className="w-full h-full object-cover"
                  />
                </div>
                <span className="font-['Inter'] font-semibold text-sm leading-5 text-[#1E2939]">
                  {item.designation} {item.name}
                </span>
              </div>
            </div>
          ))}
        </div>
      </motion.div>
    </section>
  );
}
