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

interface UsePipVisibilityOptions {
  enabled?: boolean;
  activeTab: number;
  dashboardTabIndex?: number;
  onShow?: () => void;
  onHide?: () => void;
}

interface UsePipVisibilityReturn {
  showPip: boolean;
  widgetRef: (node: HTMLDivElement | null) => void;
  setManuallyHidden: (hidden: boolean) => void;
  isManuallyHidden: boolean;
}

export function usePipVisibility(options: UsePipVisibilityOptions): UsePipVisibilityReturn {
  const {
    enabled = true,
    activeTab,
    dashboardTabIndex = 0,
    onShow,
    onHide,
  } = options;

  const [showPip, setShowPip] = useState(false);
  const [isManuallyHidden, setIsManuallyHidden] = useState(false);
  const [isWidgetVisible, setIsWidgetVisible] = useState(true);
  const [widgetElement, setWidgetElement] = useState<HTMLDivElement | null>(null);
  const [isMobileDevice, setIsMobileDevice] = useState(false);
  const prevShowPip = useRef(false);
  const observerRef = useRef<IntersectionObserver | null>(null);

  // Memoized mobile check - computed once and updated on resize
  useEffect(() => {
    const checkMobile = () => {
      if (typeof window === 'undefined') {
        setIsMobileDevice(false);
        return;
      }
      setIsMobileDevice(
        window.innerWidth < 768 || /Android|iPhone|iPad|iPod/i.test(navigator.userAgent)
      );
    };

    checkMobile();
    window.addEventListener('resize', checkMobile);
    return () => window.removeEventListener('resize', checkMobile);
  }, []);

  // Callback ref for the widget element
  const widgetRef = useCallback((node: HTMLDivElement | null) => {
    setWidgetElement(node);
  }, []);

  // Intersection Observer for scroll detection
  useEffect(() => {
    // Cleanup previous observer
    if (observerRef.current) {
      observerRef.current.disconnect();
      observerRef.current = null;
    }

    if (!enabled || isMobileDevice || !widgetElement) {
      return;
    }

    observerRef.current = new IntersectionObserver(
      ([entry]) => {
        setIsWidgetVisible(entry.isIntersecting);
      },
      {
        threshold: 0.1,
        rootMargin: '0px',
      }
    );

    observerRef.current.observe(widgetElement);

    return () => {
      if (observerRef.current) {
        observerRef.current.disconnect();
        observerRef.current = null;
      }
    };
  }, [enabled, isMobileDevice, widgetElement]);

  // Compute showPip based on all conditions
  useEffect(() => {
    if (!enabled || isMobileDevice || isManuallyHidden) {
      setShowPip(false);
      return;
    }

    // Show PiP if:
    // 1. Not on dashboard tab, OR
    // 2. On dashboard tab but widgets scrolled out of view
    const isOnDashboard = activeTab === dashboardTabIndex;
    const shouldShow = !isOnDashboard || (isOnDashboard && !isWidgetVisible);

    setShowPip(shouldShow);
  }, [enabled, activeTab, dashboardTabIndex, isWidgetVisible, isManuallyHidden, isMobileDevice]);

  // Trigger callbacks on show/hide
  useEffect(() => {
    if (showPip && !prevShowPip.current) {
      onShow?.();
    } else if (!showPip && prevShowPip.current) {
      onHide?.();
    }
    prevShowPip.current = showPip;
  }, [showPip, onShow, onHide]);

  // Reset manually hidden when returning to dashboard
  useEffect(() => {
    if (activeTab === dashboardTabIndex && isWidgetVisible) {
      setIsManuallyHidden(false);
    }
  }, [activeTab, dashboardTabIndex, isWidgetVisible]);

  const setManuallyHidden = useCallback((hidden: boolean) => {
    setIsManuallyHidden(hidden);
  }, []);

  return {
    showPip,
    widgetRef,
    setManuallyHidden,
    isManuallyHidden,
  };
}

export default usePipVisibility;
