import { useMemo } from 'react';
import { RefObject } from 'react';
import { Helpers } from '../services/helpers';
import { ARROW_DIMENSIONS } from '../components/consts';
import { ArrowSize } from '../types';

export interface CarouselDimensions {
  containerWidth: number;
  arrowSize: ArrowSize;
  arrowSpace: number;
  contentWidth: number;
  itemWidth: number;
}

interface UseCarouselDimensionsProps {
  widgetWidth: number;
  slideRef: RefObject<HTMLDivElement>;
  hideArrows: boolean;
  hasItems: boolean;
  nbElems: number;
  itemCount: number;
  isMobile?: boolean;
  partialItemWidth?: number;
 alwaysPartial?: boolean;
  forcedArrowSize?: ArrowSize;
}

export const useCarouselDimensions = ({
  widgetWidth,
  slideRef,
  hideArrows,
  hasItems,
  nbElems,
  itemCount,
  isMobile = false,
  partialItemWidth = 0,
  alwaysPartial = false,
  forcedArrowSize,
}: UseCarouselDimensionsProps): CarouselDimensions => {
  const carouselDimensions = useMemo((): CarouselDimensions => {
    const containerWidth = widgetWidth > 0 ? widgetWidth : slideRef.current?.clientWidth || 600;
    const configuredVisibleItems = nbElems > 0 ? nbElems : Math.max(itemCount, 1);

    const showArrows = !isMobile && hasItems && !hideArrows;
    const arrowSize: ArrowSize = showArrows
      ? forcedArrowSize ?? Helpers.calculateArrowSize(containerWidth)
      : 'medium';

    // Calculate actual arrow space based on size
    const arrowSpace = showArrows
  ? (ARROW_DIMENSIONS[arrowSize].width + ARROW_DIMENSIONS[arrowSize].padding * 2) * 2 // left + right arrows
      : 0;
    const contentWidth = containerWidth - arrowSpace;

    let itemWidth: number;
    if (isMobile) {
      if (configuredVisibleItems <= 1) {
        itemWidth = contentWidth * 0.8; // 80% of content width for main item with partials
      } else {
        itemWidth = contentWidth / configuredVisibleItems;
      }
    } else {
      // Calculate item width - accounting for visible items and partial items
      const visibleItems = configuredVisibleItems;

      // By default, only apply the partial-item peek for even item counts
      // (e.g. 4 items + 0.4 partial) so odd layouts fill the track cleanly.
      // When alwaysPartial is set the rule is bypassed (Buy box carousel).
      const isEven = visibleItems % 2 === 0;
      const partialWidth = alwaysPartial || isEven ? partialItemWidth : 0;

      itemWidth = Math.floor(contentWidth / (visibleItems + partialWidth));
    }

    return {
      containerWidth,
      arrowSize,
      arrowSpace,
      contentWidth,
      itemWidth,
    };
  }, [
    widgetWidth,
    hideArrows,
    hasItems,
    nbElems,
    itemCount,
    isMobile,
    partialItemWidth,
    alwaysPartial,
    forcedArrowSize,
    slideRef.current?.clientWidth,
  ]);

  return carouselDimensions;
};

export default useCarouselDimensions;
