'use client';

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

interface FloatingDropdownLayout {
  top: number;
  left: number;
  width: number;
  height: number;
}

interface UseFloatingDropdownOptions {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  margin?: number;
  minWidth?: number;
  minHeight?: number;
  maxHeight?: number;
}

export const useFloatingDropdown = ({
  open,
  onOpenChange,
  margin = 8,
  minWidth = 0,
  minHeight = 220,
  maxHeight = 420,
}: UseFloatingDropdownOptions) => {
  const anchorRef = useRef<HTMLDivElement | null>(null);
  const dropdownRef = useRef<HTMLDivElement | null>(null);
  const [layout, setLayout] = useState<FloatingDropdownLayout | null>(null);

  const updateLayout = useCallback(() => {
    const anchor = anchorRef.current;
    if (!anchor) return;

    const rect = anchor.getBoundingClientRect();
    const viewportBottomSpace = window.innerHeight - rect.bottom - margin;
    const availableWidth = Math.max(0, window.innerWidth - margin * 2);
    const width = Math.min(availableWidth, Math.max(rect.width, minWidth));
    const centeredLeft = rect.left + rect.width / 2 - width / 2;
    const left = Math.min(Math.max(centeredLeft, margin), window.innerWidth - margin - width);

    setLayout({
      top: rect.bottom + margin,
      left,
      width,
      height: Math.max(minHeight, Math.min(maxHeight, viewportBottomSpace)),
    });
  }, [margin, maxHeight, minHeight, minWidth]);

  useEffect(() => {
    if (!open) return;

    updateLayout();
    window.addEventListener('resize', updateLayout);
    window.addEventListener('scroll', updateLayout, true);

    return () => {
      window.removeEventListener('resize', updateLayout);
      window.removeEventListener('scroll', updateLayout, true);
    };
  }, [open, updateLayout]);

  useEffect(() => {
    const handlePointerDown = (event: PointerEvent) => {
      const target = event.target as Node;
      const insideAnchor = anchorRef.current?.contains(target);
      const insideDropdown = dropdownRef.current?.contains(target);

      if (!insideAnchor && !insideDropdown) {
        onOpenChange(false);
      }
    };

    document.addEventListener('pointerdown', handlePointerDown);
    return () => document.removeEventListener('pointerdown', handlePointerDown);
  }, [onOpenChange]);

  return {
    anchorRef,
    dropdownRef,
    layout,
    updateLayout,
  };
};
