import { useEffect, useState, useCallback, useMemo } from 'react';

import type { FileTabs } from '@redocly/theme/components/CodeBlock/CodeBlock';

type CodeBlockTabsProps = {
  tabs: FileTabs;
  containerRef: React.RefObject<HTMLDivElement | null>;
  tabRefs: React.RefObject<HTMLButtonElement[]>;
};

export function useCodeBlockTabsControls({ tabs, containerRef, tabRefs }: CodeBlockTabsProps) {
  const [showControls, setShowControls] = useState(false);

  const tabsWidth = useMemo(
    () =>
      tabRefs?.current?.reduce((acc, tabRef) => {
        return tabRef ? acc + tabRef.offsetWidth : acc;
      }, 0) || 0,
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [tabRefs?.current?.length],
  );

  const { currentIndex, isFirstTab, isLastTab } = useMemo(() => {
    const currentIndex = tabs.files.findIndex((file) => file.name === tabs.activeTabName);
    return {
      currentIndex,
      isFirstTab: currentIndex === 0,
      isLastTab: currentIndex === tabs.files.length - 1,
    };
  }, [tabs]);

  useEffect(() => {
    if (containerRef.current) {
      const container = containerRef.current;
      const resizeObserver = new ResizeObserver((entries) => {
        const containerWidth = entries[0].contentRect.width;

        setShowControls(tabsWidth > containerWidth);
      });

      resizeObserver.observe(container);

      return () => {
        resizeObserver.unobserve(container as HTMLDivElement);
      };
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [containerRef.current]);

  const handlePrevTab = useCallback(() => {
    if (!isFirstTab) {
      const prevTab = tabs.files[currentIndex - 1].name;
      tabs.handleTabSwitch(prevTab);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [currentIndex]);

  const handleNextTab = useCallback(() => {
    if (!isLastTab) {
      const nextTab = tabs.files[currentIndex + 1].name;
      tabs.handleTabSwitch(nextTab);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [currentIndex]);

  return { showControls, handlePrevTab, handleNextTab };
}
