/**
 * useCarouselHeight
 *
 * Calculates and returns a responsive minimum height for a carousel container
 * based on the width of its parent element and the expected thumbnail aspect ratio.
 *
 * This ensures that the carousel container allocates enough vertical space
 * to prevent layout shifts when a thumbnail "grows" (e.g. when active).
 *
 * The height is calculated using:
 * - the container’s current width (via ResizeObserver),
 * - the active thumbnail aspect ratio (per shape: square, portrait, stories),
 * - the number of visible thumbnails (based solely on contentSize),
 * - a fractional width for partially visible items (default: partialItemWidth from consts),
 * - and an optional pixel buffer for spacing (default: 40).
 *
 * @param ref - a ref pointing to the carousel container element
 * @param shape - one of: 'square', 'portrait', 'stories'; determines aspect ratio
 * @param contentSize - max number of visible items configured
 * @param itemCount - actual number of carousel items
 * @param partialItemWidth - fraction of width reserved for a partially visible item (default: partialItemWidth from consts)
 * @param buffer - additional space to reserve below thumbnails (default: 40)
 * @returns the calculated height in pixels
 */
import { useEffect, useState, RefObject } from 'react';
import {
  activeSquareAspectRatio,
  activePortraitAspectRatio,
  activeStoriesAspectRatio,
} from '../components/consts';
import { ISettings } from '../types';

const ACTIVE_SLIDE_ASPECT_RATIOS: Record<ISettings['thumbnail_shape'], number> = {
  square: activeSquareAspectRatio,
  portrait: activePortraitAspectRatio,
  stories: activeStoriesAspectRatio,
};

interface UseCarouselHeightParams {
  ref: RefObject<HTMLDivElement>;
  shape: ISettings['thumbnail_shape'];
  contentSize: ISettings['content_size'];
  itemCount: number;
  partialItemWidth: number;
  buffer?: number;
}

export const useCarouselHeight = (params: UseCarouselHeightParams): number => {
  const { ref, shape, contentSize, itemCount, partialItemWidth, buffer = 40 } = params;
  const [height, setHeight] = useState(0);

  useEffect(() => {
    if (!ref.current) return;

    const updateHeight = (): void => {
      if (!ref.current) return;

      const containerWidth = ref.current.offsetWidth;
      const aspectRatioPercent = ACTIVE_SLIDE_ASPECT_RATIOS[shape] ?? 100;
      const aspectRatio = aspectRatioPercent / 100;

      const configuredVisibleItems = contentSize > 0 ? contentSize : Math.max(itemCount, 1);
      const isEven = configuredVisibleItems % 2 === 0;
      const partialWidth = isEven ? partialItemWidth : 0;
      const itemWidth = containerWidth / (configuredVisibleItems + partialWidth);

      setHeight(itemWidth * aspectRatio + buffer);
    };

    updateHeight();

    const observer = new ResizeObserver(updateHeight);
    observer.observe(ref.current);

    return () => {
      observer.disconnect();
    };
  }, [ref, shape, contentSize, itemCount, partialItemWidth, buffer]);

  return height;
};
