"use client";

import Image from "next/image";
import React, { useEffect, useRef, useState } from "react";
import { motion, AnimatePresence } from "framer-motion";

import { playfair } from "@/lib/fonts";


const CMS_BASE_URL =
  process.env.NEXT_PUBLIC_CMS_BASE_URL?.replace(/\/$/, "") ?? "";

import {
  type RichTextRoot,
  type RichTextChild,
  renderLexical,
  extractPlainText
} from "../utils";

type MediaSizes = {
  small?: { url?: string | null };
  medium?: { url?: string | null };
  large?: { url?: string | null };
  og?: { url?: string | null };
};

type MediaDocument = {
  url?: string | null;
  alt?: string | null;
  width?: number | null;
  height?: number | null;
  sizes?: MediaSizes | null;
};

type AwardItem = {
  id?: string;
  title?: RichTextRoot | string | null;
  imageId?: number | null;
};

type AwardsBlock = {
  type?: string;
  props?: {
    heading?: RichTextRoot | null;
    variant?: string | null;
    items?: AwardItem[];
    meta?: {
      anchorId?: string | null;
    } | null;
  } | null;
};

type ScillyPageData = {
  layout?: AwardsBlock[];
  included?: {
    media?: Record<string, MediaDocument>;
  } | null;
};

type AwardLogo = {
  id: string;
  src: string;
  alt: string;
  width: number;
  height: number;
};

function isAwardsBlock(block: AwardsBlock | undefined): block is AwardsBlock {
  return (
    block?.type === "contentListV1" && block?.props?.variant === "logo-grid"
  );
}

function toAbsoluteUrl(url?: string | null) {
  if (!url) return null;
  if (url.startsWith("http://") || url.startsWith("https://")) return url;
  if (!CMS_BASE_URL || !url.startsWith("/")) return url;
  return `${CMS_BASE_URL}${url}`;
}

function resolvePreferredImageUrl(media: MediaDocument | null) {
  return toAbsoluteUrl(
    media?.sizes?.small?.url ??
    media?.sizes?.medium?.url ??
    media?.sizes?.large?.url ??
    media?.url,
  );
}



export default function AwardsRecognition({ data }: { data: ScillyPageData }) {
  const awardsBlock = data.layout?.find(isAwardsBlock);
  const mediaMap = data.included?.media ?? {};
  const heading = renderLexical(awardsBlock?.props?.heading);

  const scrollRef = useRef<HTMLDivElement>(null);
  const [hoveredImage, setHoveredImage] = useState<{ id: string; x: number; y: number } | null>(null);
  const hoverTimerRef = React.useRef<NodeJS.Timeout | null>(null);
  const [activeIndex, setActiveIndex] = useState(0);

  const awards =
    awardsBlock?.props?.items
      ?.map((item, index) => {
        const media =
          item.imageId != null
            ? (mediaMap[String(item.imageId)] ?? null)
            : null;

        const src = resolvePreferredImageUrl(media);

        if (!src) return null;

        return {
          id: item.id ?? String(index),
          src,
          alt: media?.alt?.trim() || extractPlainText(item.title) || `Award ${index + 1}`,
          width: media?.width ?? 135,
          height: media?.height ?? 157,
        };
      })
      .filter((award): award is AwardLogo => Boolean(award)) ?? [];

  const handleScroll = () => {
    const node = scrollRef.current;
    if (!node || window.innerWidth >= 768) return;

    const children = Array.from(node.children) as HTMLElement[];
    const scrollLeft = node.scrollLeft;
    const viewportCenter = scrollLeft + node.clientWidth / 2;

    let nearestIndex = 0;
    let minDistance = Number.MAX_VALUE;

    children.forEach((child, index) => {
      const childCenter = child.offsetLeft + child.clientWidth / 2;
      const distance = Math.abs(childCenter - viewportCenter);
      if (distance < minDistance) {
        minDistance = distance;
        nearestIndex = index;
      }
    });

    if (nearestIndex !== activeIndex) {
      setActiveIndex(nearestIndex);
    }
  };

  const scrollToAward = (index: number, behavior: ScrollBehavior = "smooth") => {
    const node = scrollRef.current;
    if (!node) return;

    const target = node.children[index] as HTMLElement;
    if (target) {
      const left = target.offsetLeft - (node.clientWidth - target.clientWidth) / 2;
      node.scrollTo({
        left: Math.max(left, 0),
        behavior,
      });
      setActiveIndex(index);
    }
  };

  if (!awardsBlock || awards.length === 0) {
    return null;
  }

  return (
    <section
      id={awardsBlock?.props?.meta?.anchorId ?? undefined}
      className="relative w-full"
    >
      <div className="mx-auto w-full max-w-[1200px] px-4 pt-[28px] pb-[36px] md:px-6 md:pt-[40px] md:pb-[60px]">
        <h2
          className={`text-center text-[22px] leading-none text-[#85714D] sm:text-[26px] md:text-[34px] lg:text-[40px] ${playfair.className}`}
        >
          {heading}
        </h2>

        <div className="mt-[24px] md:mt-[40px]">
          <div
            ref={scrollRef}
            onScroll={handleScroll}
            style={{ touchAction: "pan-x pan-y" }}
            className="
              flex flex-nowrap items-end gap-[14px] overflow-x-auto pb-4
              scrollbar-none scroll-smooth snap-x snap-mandatory
              md:flex-wrap md:justify-center md:gap-[24px] md:overflow-visible
              lg:gap-[35px]
            "
          >
            {awards.map((award) => (
              <div
                key={award.id}
                className="relative flex-shrink-0 flex items-center justify-center snap-center"
                onMouseMove={(e) => {
                  const r = e.currentTarget.getBoundingClientRect();
                  const x = e.clientX - r.left;
                  const y = e.clientY - r.top;
                  if (hoverTimerRef.current) clearTimeout(hoverTimerRef.current);
                  setHoveredImage((prev) => (prev !== null ? null : prev));
                  hoverTimerRef.current = setTimeout(() => setHoveredImage({ id: award.id, x, y }), 1000);
                }}
                onMouseLeave={() => {
                  if (hoverTimerRef.current) clearTimeout(hoverTimerRef.current);
                  setHoveredImage(null);
                }}
              >
                <Image
                  src={award.src}
                  alt={award.alt}
                  width={award.width}
                  height={award.height}
                  sizes="(max-width: 768px) 150px, 200px"
                  className="h-auto w-auto object-contain cursor-pointer"
                  style={{ height: "clamp(110px, 22vw, 157px)" }}
                  loading="lazy"
                />
                <AnimatePresence>
                  {hoveredImage?.id === award.id && (
                    <motion.div
                      initial={{ opacity: 0, scale: 0.95 }}
                      animate={{ opacity: 1, scale: 1 }}
                      exit={{ opacity: 0, scale: 0.95 }}
                      transition={{ duration: 0.12 }}
                      style={{
                        position: "absolute",
                        left: hoveredImage.x,
                        top: hoveredImage.y,
                        transform: "translate(-50%, calc(-100% - 8px))",
                        pointerEvents: "none",
                        zIndex: 100,
                        whiteSpace: "nowrap",
                      }}
                      className="rounded border border-black bg-white px-3 py-1.5 text-sm font-semibold text-black shadow-sm"
                    >
                      {award.alt}
                    </motion.div>
                  )}
                </AnimatePresence>
              </div>
            ))}
          </div>


          <div className="mt-4 flex justify-center gap-2 md:hidden">
            {awards.map((_, index) => (
              <button
                key={index}
                type="button"
                aria-label={`Go to award ${index + 1}`}
                onClick={() => scrollToAward(index)}
                className={`h-2.5 w-2.5 rounded-full transition-all cursor-pointer ${index === activeIndex ? "bg-[#85714D]" : "bg-[#DDD7CF]"
                  }`}
              />
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}