import React, { useEffect, useRef, useState, useLayoutEffect } from "react";

interface Tab {
  id: string;
  label: string;
}

interface SlidingTabsProps {
  tabs: Tab[];
  activeTab: string;
  onChange: (id: string) => void;
  className?: string;
}

export const SlidingTabs: React.FC<SlidingTabsProps> = ({
  tabs,
  activeTab,
  onChange,
  className = "",
}) => {
  const [sliderStyle, setSliderStyle] = useState<React.CSSProperties>({
    width: 0,
    transform: "translateX(0)",
    opacity: 0,
  });

  const containerRef = useRef<HTMLDivElement>(null);
  const tabsRef = useRef<{ [key: string]: HTMLButtonElement | null }>({});

  const updateSlider = () => {
    const activeElement = tabsRef.current[activeTab];
    const container = containerRef.current;

    // Validate that we have valid elements and that activeTab exists in our tabs
    if (
      !activeElement ||
      !container ||
      !tabs.some((tab) => tab.id === activeTab)
    ) {
      return;
    }

    try {
      const activeRect = activeElement.getBoundingClientRect();
      const containerRect = container.getBoundingClientRect();

      // Additional validation - ensure we have valid dimensions
      if (activeRect.width === 0 || containerRect.width === 0) {
        return;
      }

      const relativeLeft = activeRect.left - containerRect.left;

      setSliderStyle({
        width: activeRect.width,
        transform: `translateX(${relativeLeft}px)`,
        // We set opacity to 1 once we have positions to avoid FOUC
        opacity: 1,
      });
    } catch (error) {
      // Handle potential DOM measurement errors during zoom/resize
      console.warn("SlidingTabs: Error updating slider position:", error);
    }
  };

  // Update when active tab changes
  useLayoutEffect(() => {
    // Initial calculation needs to happen after paint often to get correct widths
    // requestAnimationFrame ensures we are measuring at a good time
    requestAnimationFrame(updateSlider);
  }, [activeTab]);

  // Handle window resize
  useEffect(() => {
    let resizeTimeout: number;

    const handleResize = () => {
      // Debounce resize events to avoid excessive calculations during zoom
      clearTimeout(resizeTimeout);
      resizeTimeout = window.setTimeout(() => {
        // Use requestAnimationFrame to ensure DOM has finished updating
        requestAnimationFrame(updateSlider);
      }, 50);
    };

    window.addEventListener("resize", handleResize, { passive: true });

    // Also a failsafe timeout for font loading shifts etc
    const timeout = setTimeout(updateSlider, 150);

    return () => {
      window.removeEventListener("resize", handleResize);
      clearTimeout(timeout);
      clearTimeout(resizeTimeout);
    };
  }, [activeTab]); // Add activeTab as dependency so resize handler is recreated when tab changes

  return (
    <div
      ref={containerRef}
      className={`b3-wvs-relative b3-wvs-sub-tabs ${className}`}
      role="tablist"
    >
      {/* Animated Slider */}
      <div
        className="b3-wvs-absolute b3-wvs-top-1 b3-wvs-bottom-1 b3-wvs-left-0 b3-wvs-bg-admin b3-wvs-rounded-full b3-wvs-shadow-sm b3-wvs-pointer-events-none"
        style={{
          ...sliderStyle,
          // Using the specific ease from request
          transition:
            "transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1), width 0.35s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.2s ease",
          zIndex: 1,
        }}
        aria-hidden="true"
      />

      {/* Tab Buttons */}
      {tabs.map((tab) => (
        <button
          key={tab.id}
          ref={(el) => (tabsRef.current[tab.id] = el)}
          type="button"
          onClick={() => onChange(tab.id)}
          role="tab"
          aria-selected={activeTab === tab.id}
          style={{ zIndex: 2 }}
          className={`b3-wvs-sub-tab ${activeTab === tab.id ? "is-active" : ""}`}
        >
          {tab.label}
        </button>
      ))}
    </div>
  );
};
