"use client";

import React, { useState, useMemo, useRef } from "react";
import ArrowButton from "../ui/ArrowButton";
import ImageLightbox from "@/src/components/ui/ImageLightbox";
import { withCDN, optimizedImage } from "@/src/lib/utils";
import type { WorkshopSection } from "@/src/lib/services/workshopService";
import { scrollToId } from "@/src/lib/utils/scrollToId";

interface WorkshopTabProps {
  whyWorkshopData?: WorkshopSection;
}

const STATIC_IMAGES = [
  "/Workshop/pct%20(6).png",
  "/discover/discover-6.png",
  "/Workshop/main%20pct%20(selected)%20(1).png",
  "/Workshop/main%20pct%20(selected)%20(2).png",
  "/Workshop/main%20pct%20(selected)%20(3).png",
];

type SlideDirection = "next" | "prev";

interface WorkshopSlideProps {
  tab: {
    contentTitle: string;
    description: string;
    mainImage: string;
  };
  onImageClick: () => void;
}

export default function ClientDiscoverSlider({
  whyWorkshopData,
}: WorkshopTabProps) {
  const parsedSliders = useMemo(() => {
    try {
      if (whyWorkshopData?.sliders) {
        const parsed =
          typeof whyWorkshopData.sliders === "string"
            ? JSON.parse(whyWorkshopData.sliders)
            : whyWorkshopData.sliders;

        return Array.isArray(parsed) ? parsed : [];
      }

      return [];
    } catch (error) {
      console.error(
        "[WorkshopTab] Failed to parse sliders",
        error
      );

      return [];
    }
  }, [whyWorkshopData?.sliders]);

  const tabs = useMemo(() => {
    const itemCount = Math.max(
      parsedSliders.length,
      STATIC_IMAGES.length
    );

    return Array.from({ length: itemCount }).map(
      (_, index) => {
        const apiSlider = parsedSliders[index] || {};

        return {
          tabTitle:
            apiSlider.sliderHeading ||
            `Workshop ${index + 1}`,

          contentTitle:
            apiSlider.title ||
            `Workshop Experience ${index + 1}`,

          description:
            apiSlider.description ||
            "Explore our workshops and discover new possibilities.",

          mainImage:
            apiSlider.image ||
            STATIC_IMAGES[index % STATIC_IMAGES.length],
        };
      }
    );
  }, [parsedSliders]);

  const [activeTab, setActiveTab] = useState(0);

  const [lightboxIndex, setLightboxIndex] = useState<
    number | null
  >(null);

  const [previousTab, setPreviousTab] = useState<
    number | null
  >(null);

  const [slideDirection, setSlideDirection] =
    useState<SlideDirection>("next");

  const [isAnimating, setIsAnimating] = useState(false);

  // Pointer swipe and drag state
  const pointerStartX = useRef<number | null>(null);
  const pointerStartY = useRef<number | null>(null);
  const pointerId = useRef<number | null>(null);
  const pointerType = useRef<string | null>(null);
  const pointerStartTarget = useRef<EventTarget | null>(null);

  const minSwipeDistance = 60;
  const currentTab = tabs[activeTab];

  const tabContainerRef = useRef<HTMLDivElement>(null);

  const tabRefs = useRef<
    (HTMLButtonElement | null)[]
  >([]);

  // Prepare images for the lightbox.
  const lightboxImages = useMemo(
    () => tabs.map((tab) => withCDN(tab.mainImage)),
    [tabs]
  );

  // FIX: Correct tab scrolling on iOS Safari.
  // Original tab styling and layout remain unchanged.
  const scrollToTab = (index: number) => {
    const container = tabContainerRef.current;
    const tab = tabRefs.current[index];

    if (!container || !tab || window.innerWidth >= 768) {
      return;
    }

    const maxScroll = Math.max(
      0,
      container.scrollWidth - container.clientWidth
    );

    let targetLeft: number;

    if (index === 0) {
      // Return to the start without leaving a gap.
      targetLeft = 0;
    } else if (index === tabs.length - 1) {
      // Scroll to the actual end of the tab container.
      targetLeft = maxScroll;
    } else {
      const containerRect =
        container.getBoundingClientRect();

      const tabRect = tab.getBoundingClientRect();

      targetLeft =
        container.scrollLeft +
        tabRect.left -
        containerRect.left -
        (container.clientWidth - tab.clientWidth) / 2;

      targetLeft = Math.max(
        0,
        Math.min(targetLeft, maxScroll)
      );
    }

    container.scrollTo({
      left: targetLeft,
      behavior: "smooth",
    });
  };

  // Change slides
  const changeTab = (
    nextIndex: number,
    direction: SlideDirection
  ) => {
    if (
      isAnimating ||
      nextIndex === activeTab ||
      nextIndex < 0 ||
      nextIndex >= tabs.length
    ) {
      return;
    }

    setPreviousTab(activeTab);
    setSlideDirection(direction);
    setIsAnimating(true);
    setActiveTab(nextIndex);

    scrollToTab(nextIndex);
  };

  const handlePrev = () => {
    if (isAnimating || tabs.length <= 1) return;

    const nextIndex =
      activeTab === 0
        ? tabs.length - 1
        : activeTab - 1;

    changeTab(nextIndex, "prev");
  };

  const handleNext = () => {
    if (isAnimating || tabs.length <= 1) return;

    const nextIndex =
      activeTab === tabs.length - 1
        ? 0
        : activeTab + 1;

    changeTab(nextIndex, "next");
  };

  const handleTabClick = (index: number) => {
    if (isAnimating || index === activeTab) return;

    changeTab(
      index,
      index > activeTab ? "next" : "prev"
    );
  };

  // Start mouse drag or touch swipe.
  // Do not capture the pointer: normal image clicks must work.
  const handlePointerDown = (
    e: React.PointerEvent<HTMLDivElement>
  ) => {
    if (isAnimating || tabs.length <= 1) return;

    if (e.pointerType === "mouse" && e.button !== 0) {
      return;
    }

    pointerStartX.current = e.clientX;
    pointerStartY.current = e.clientY;
    pointerId.current = e.pointerId;
    pointerType.current = e.pointerType;
    pointerStartTarget.current = e.target;
  };

  const handlePointerMove = (
    e: React.PointerEvent<HTMLDivElement>
  ) => {
    if (
      pointerStartX.current === null ||
      pointerId.current !== e.pointerId
    ) {
      return;
    }

    if (pointerType.current === "mouse") {
      e.preventDefault();
    }
  };

  const resetPointer = () => {
    pointerStartX.current = null;
    pointerStartY.current = null;
    pointerId.current = null;
    pointerType.current = null;
    pointerStartTarget.current = null;
  };

  const handlePointerUp = (
    e: React.PointerEvent<HTMLDivElement>
  ) => {
    if (
      pointerStartX.current === null ||
      pointerId.current !== e.pointerId
    ) {
      return;
    }

    const startX = pointerStartX.current;
    const startY = pointerStartY.current ?? e.clientY;
    const startTarget = pointerStartTarget.current;

    const distanceX = startX - e.clientX;
    const distanceY = startY - e.clientY;

    resetPointer();

    // Ignore vertical movement to preserve page scrolling.
    if (Math.abs(distanceY) > Math.abs(distanceX)) {
      return;
    }

    // Normal clicks should not change slides.
    if (Math.abs(distanceX) < minSwipeDistance) {
      return;
    }

    // Do not drag the slider from interactive controls.
    if (
      startTarget instanceof Element &&
      startTarget.closest(
        "button, a, input, textarea, select"
      )
    ) {
      return;
    }

    if (isAnimating) return;

    if (distanceX > 0) {
      handleNext();
    } else {
      handlePrev();
    }
  };

  const handlePointerCancel = () => {
    resetPointer();
  };

  // Finish outgoing slide animation.
  const handleSlideAnimationEnd = (
    e: React.AnimationEvent<HTMLDivElement>
  ) => {
    if (e.target !== e.currentTarget) return;

    setPreviousTab(null);
    setIsAnimating(false);
  };

  // Reusable slide content
  const renderSlideContent = ({
    tab,
    onImageClick,
  }: WorkshopSlideProps) => {
    const imageSrc = optimizedImage(
      tab.mainImage.startsWith("http")
        ? tab.mainImage
        : withCDN(tab.mainImage),
      1280
    );

    return (
      <div className="flex flex-col md:flex-row gap-6 justify-between items-center sm:flex-row max-[767px]:!flex-col-reverse">
        {/* TEXT CONTENT */}
        <div className="md:w-[45%] lg:w-[550px] md:mt-[-40px]">
          <h2 className="text-[20px] xl:text-[30px] font-light text-[#0097DC] mb-2 leading-tight uppercase">
            {tab.contentTitle}
          </h2>

          <p className="text-[#58585A] text-[18px] md:text-[16px] xl:text-[22px] mb-4 font-light">
            {tab.description}
          </p>

          <button
            type="button"
            className="flex items-center gap-3 bg-[#0097DC] text-white px-6 py-3 rounded-full hover:bg-[#0097DC] hover:shadow-[10px_14px_14px_#0000000D] cursor-pointer active:bg-[#0084C1] text-[16px] xl:text-h2-tab mt-8 uppercase transition work-btn"
            onClick={() => {
              scrollToId("allWorkshop");
            }}
          >
            <img
              src={withCDN("/gear.png")}
              alt="Gear"
              className="w-6 h-6"
              draggable={false}
            />
            Discover workshops
          </button>
        </div>

        {/* IMAGE WITH LIGHTBOX */}
        <div className="md:w-[55%] lg:w-2/3 w-[421px] xl:w-[700px] max-[767px]:w-[70%] max-[767px]:h-[300px] max-[600px]:h-[170px]">
          <div className="rounded-xl overflow-hidden">
            <img
              src={imageSrc}
              alt={tab.contentTitle || "Workshop"}
              className="w-full h-[170px] max-[767px]:h-[300px] max-[600px]:h-[170px] sm:h-[270px] md:h-[270px] xl:h-[430px] rounded-[20px] sm:rounded-[30px] object-cover cursor-pointer"
              draggable={false}
              onClick={onImageClick}
            />
          </div>
        </div>
      </div>
    );
  };

  if (!currentTab) return null;

  return (
    <div className="max-w-[1300px] mx-auto w-full px-4 sm:px-0 py-16 max-[767px]:px-0 workshop-tabs-cols">
      {/* MAIN HEADING */}
      <h2 className="text-[30px] xl:text-[50px] font-bold text-[#0097DC] mb-6 leading-tight uppercase">
        {whyWorkshopData?.mainHeading ||
          "Why Workshops with YE"}
      </h2>

      {/* TAB NAVIGATION - ORIGINAL DESIGN PRESERVED */}
      <div
        ref={tabContainerRef}
        className="flex justify-between items-stretch gap-2 mb-6 max-[767px]:overflow-x-auto no-scrollbar max-[767px]:scroll-smooth tab-wrap"
        style={{
          WebkitOverflowScrolling: "touch",
          overscrollBehaviorX: "contain",
        }}
      >
        {tabs.map((tab, index) => (
          <button
            key={index}
            ref={(el) => {
              tabRefs.current[index] = el;
            }}
            type="button"
            onClick={() => handleTabClick(index)}
            disabled={isAnimating}
            className={`text-[16px] md:text-[14px] lg:text-[15px] xl:lg:text-[16px] tab-btns cursor-pointer transition text-center border border-[#0097DC] rounded-[7px] px-[10px] md:px-[6px] lg:px-[10px] py-[10px] bg-[#fff]
              ${
                activeTab === index
                  ? "text-[#0097DC] border-[#0097DC] !border-[2px]"
                  : "text-gray-500 border-transparent"
              }`}
          >
            {tab.tabTitle}
          </button>
        ))}
      </div>

      {/* SLIDE VIEWPORT */}
      <div
        className="workshop-slide-viewport cursor-grab active:cursor-grabbing"
        onPointerDown={handlePointerDown}
        onPointerMove={handlePointerMove}
        onPointerUp={handlePointerUp}
        onPointerCancel={handlePointerCancel}
        style={{
          touchAction: "pan-y",
          userSelect: "none",
          WebkitUserSelect: "none",
        }}
      >
        <div className="workshop-slide-track">
          {/* OUTGOING SLIDE */}
          {previousTab !== null && isAnimating && (
            <div
              key={`out-${previousTab}`}
              className={`workshop-slide-layer workshop-slide-out-${slideDirection}`}
              onAnimationEnd={handleSlideAnimationEnd}
            >
              {renderSlideContent({
                tab: tabs[previousTab],
                onImageClick: () => {
                  const index = tabs.findIndex(
                    (item) =>
                      item.mainImage ===
                      tabs[previousTab].mainImage
                  );

                  if (index !== -1) {
                    setLightboxIndex(index);
                  }
                },
              })}
            </div>
          )}

          {/* INCOMING SLIDE */}
          <div
            key={`in-${activeTab}`}
            className={`workshop-slide-layer ${
              previousTab !== null && isAnimating
                ? `workshop-slide-in-${slideDirection}`
                : "workshop-slide-static"
            }`}
          >
            {renderSlideContent({
              tab: currentTab,
              onImageClick: () => {
                setLightboxIndex(activeTab);
              },
            })}
          </div>
        </div>
      </div>

      {/* ARROW NAVIGATION */}
      <div className="flex justify-between mt-6 absolute w-[90%] top-[45%] left-[5%] tab-arrow-mob">
        <ArrowButton
          direction="left"
          onClick={handlePrev}
        />

        <ArrowButton
          direction="right"
          onClick={handleNext}
        />
      </div>

      {/* LIGHTBOX */}
      {lightboxIndex !== null && (
        <ImageLightbox
          images={lightboxImages}
          index={lightboxIndex}
          onClose={() => setLightboxIndex(null)}
        />
      )}
    </div>
  );
}