import { RefObject, useCallback } from 'react';
import type { ContextType } from 'react';
import { spotlightCarouselTransitionDurationSec } from '../../../consts';
import {
  useUniformCenteredConfig,
  useCarouselLayout,
  useCarouselHeightConfig,
  useInfiniteNavigation,
} from '../shared/hooks';
import { StoreContext } from '../../../../services/store';
import { ISettings } from '../../../../types';

// Re-export shared hooks for backward compatibility
export { useUniformCenteredConfig };
export const useSpotlightLayout = useCarouselLayout;
export const useSpotlightHeight = useCarouselHeightConfig;

type StoreStateUpdater = ContextType<typeof StoreContext>['setStoreState'];

interface NavigationParams {
  config: {
    itemCount: number;
    contentSize: ISettings['content_size'];
    cloneCount: number;
    contentSizeNotReached: boolean;
  };
  refs: {
    slideRef: RefObject<HTMLDivElement>;
    containerRef: RefObject<HTMLDivElement>;
  };
  state: {
    itemWidth: number;
    currentPosition?: number;
  };
  actions: {
    setStoreState: StoreStateUpdater;
  };
}

// Handles navigation state, slide transitions, and position syncing.
export const useSpotlightNavigation = ({
  config: { itemCount, contentSize, cloneCount, contentSizeNotReached },
  refs: { slideRef, containerRef },
  state: { itemWidth, currentPosition },
  actions: { setStoreState },
}: NavigationParams) => {
  const navigation = useInfiniteNavigation({
    config: { itemCount, contentSize, cloneCount, contentSizeNotReached },
    refs: { slideRef, containerRef },
    state: { itemWidth, currentPosition },
    actions: { setStoreState },
    transitionDurationSec: spotlightCarouselTransitionDurationSec,
  });

  const { activeIndex } = navigation;

  // Calculate the X translation that centers the active slide inside the container.
  const getTranslateX = useCallback(
    (index = activeIndex + cloneCount) => {
      if (cloneCount === 0) {
        return 0;
      }

      const containerWidth = slideRef.current?.clientWidth || 0;
      const activePos = index * itemWidth;
      const centerOffset = (containerWidth - itemWidth) / 2;

      return centerOffset - activePos;
    },
    [cloneCount, slideRef, itemWidth, activeIndex],
  );

  const goToSlide = useCallback(
    (index: number, shouldUpdateCurrentPosition = true) => {
      navigation.goToSlide(index, shouldUpdateCurrentPosition);
    },
    [navigation],
  );

  return {
    ...navigation,
    getTranslateX,
    goToSlide,
  };
};
