/**
 * useTabUI - Hook for accessing per-tab UI state.
 *
 * This hook combines the TabUIContext (for tabId) with the tabUISlice (for state/actions).
 * It provides a simple interface for components to access their tab-specific UI state.
 *
 * IMPORTANT: This hook subscribes to `tabUIStates` directly to ensure proper reactivity.
 * Using getter functions (like isContextPanelVisibleForTab) in useMemo doesn't work
 * because the function reference doesn't change when the underlying state changes.
 *
 * Usage:
 * ```tsx
 * const { isAIGroupExpanded, toggleAIGroupExpansion } = useTabUI();
 *
 * // Check if a group is expanded in THIS tab
 * if (isAIGroupExpanded(groupId)) { ... }
 *
 * // Toggle expansion in THIS tab only
 * toggleAIGroupExpansion(groupId);
 * ```
 */

import { useCallback, useMemo } from 'react';

import { useTabIdOptional } from '@renderer/contexts/useTabUIContext';
import { useStore } from '@renderer/store';
import { useShallow } from 'zustand/react/shallow';

// =============================================================================
// Types
// =============================================================================

interface UseTabUIReturn {
  tabId: string | null;
  isAIGroupExpanded: (aiGroupId: string) => boolean;
  toggleAIGroupExpansion: (aiGroupId: string) => void;
  expandAIGroup: (aiGroupId: string) => void;
  getExpandedDisplayItemIds: (aiGroupId: string) => Set<string>;
  toggleDisplayItemExpansion: (aiGroupId: string, itemId: string) => void;
  expandDisplayItem: (aiGroupId: string, itemId: string) => void;
  isSubagentTraceExpanded: (subagentId: string) => boolean;
  toggleSubagentTraceExpansion: (subagentId: string) => void;
  expandSubagentTrace: (subagentId: string) => void;
  isContextPanelVisible: boolean;
  setContextPanelVisible: (visible: boolean) => void;
  selectedContextPhase: number | null;
  setSelectedContextPhase: (phase: number | null) => void;
  savedScrollTop: number | undefined;
  saveScrollPosition: (scrollTop: number) => void;
  initializeTabUI: () => void;
}

// =============================================================================
// Main Hook
// =============================================================================

/**
 * Hook for accessing per-tab UI state and actions.
 *
 * @returns Object containing per-tab state getters and actions
 */
export function useTabUI(): UseTabUIReturn {
  // Get tabId from context (null if not in a tab)
  const tabId = useTabIdOptional();

  // Subscribe to tabUIStates MAP directly for reactivity
  // This ensures re-renders when any tab state changes
  const tabUIStates = useStore(useShallow((s) => s.tabUIStates));

  // Get the current tab's state (derived from subscribed state)
  const tabState = useMemo(() => {
    if (!tabId) return null;
    return tabUIStates.get(tabId) ?? null;
  }, [tabId, tabUIStates]);

  // Get all tab UI actions from store (these are stable function references)
  const {
    toggleAIGroupExpansionForTab,
    expandAIGroupForTab,
    toggleDisplayItemExpansionForTab,
    expandDisplayItemForTab,
    toggleSubagentTraceExpansionForTab,
    expandSubagentTraceForTab,
    setContextPanelVisibleForTab,
    setSelectedContextPhaseForTab,
    saveScrollPositionForTab,
    initTabUIState,
  } = useStore(
    useShallow((s) => ({
      toggleAIGroupExpansionForTab: s.toggleAIGroupExpansionForTab,
      expandAIGroupForTab: s.expandAIGroupForTab,
      toggleDisplayItemExpansionForTab: s.toggleDisplayItemExpansionForTab,
      expandDisplayItemForTab: s.expandDisplayItemForTab,
      toggleSubagentTraceExpansionForTab: s.toggleSubagentTraceExpansionForTab,
      expandSubagentTraceForTab: s.expandSubagentTraceForTab,
      setContextPanelVisibleForTab: s.setContextPanelVisibleForTab,
      setSelectedContextPhaseForTab: s.setSelectedContextPhaseForTab,
      saveScrollPositionForTab: s.saveScrollPositionForTab,
      initTabUIState: s.initTabUIState,
    }))
  );

  // ==========================================================================
  // Derived state from tabState (reactive!)
  // ==========================================================================

  // AI Group expansion - check directly from tabState
  const isAIGroupExpanded = useCallback(
    (aiGroupId: string): boolean => {
      return tabState?.expandedAIGroupIds.has(aiGroupId) ?? false;
    },
    [tabState]
  );

  const toggleAIGroupExpansion = useCallback(
    (aiGroupId: string): void => {
      if (!tabId) return;
      toggleAIGroupExpansionForTab(tabId, aiGroupId);
    },
    [tabId, toggleAIGroupExpansionForTab]
  );

  const expandAIGroup = useCallback(
    (aiGroupId: string): void => {
      if (!tabId) return;
      expandAIGroupForTab(tabId, aiGroupId);
    },
    [tabId, expandAIGroupForTab]
  );

  // Display item expansion - derive from tabState
  const getExpandedDisplayItemIds = useCallback(
    (aiGroupId: string): Set<string> => {
      return tabState?.expandedDisplayItemIds.get(aiGroupId) ?? new Set<string>();
    },
    [tabState]
  );

  const toggleDisplayItemExpansion = useCallback(
    (aiGroupId: string, itemId: string): void => {
      if (!tabId) return;
      toggleDisplayItemExpansionForTab(tabId, aiGroupId, itemId);
    },
    [tabId, toggleDisplayItemExpansionForTab]
  );

  const expandDisplayItem = useCallback(
    (aiGroupId: string, itemId: string): void => {
      if (!tabId) return;
      expandDisplayItemForTab(tabId, aiGroupId, itemId);
    },
    [tabId, expandDisplayItemForTab]
  );

  // Subagent trace expansion - derive from tabState
  const isSubagentTraceExpanded = useCallback(
    (subagentId: string): boolean => {
      return tabState?.expandedSubagentTraceIds.has(subagentId) ?? false;
    },
    [tabState]
  );

  const toggleSubagentTraceExpansion = useCallback(
    (subagentId: string): void => {
      if (!tabId) return;
      toggleSubagentTraceExpansionForTab(tabId, subagentId);
    },
    [tabId, toggleSubagentTraceExpansionForTab]
  );

  const expandSubagentTrace = useCallback(
    (subagentId: string): void => {
      if (!tabId) return;
      expandSubagentTraceForTab(tabId, subagentId);
    },
    [tabId, expandSubagentTraceForTab]
  );

  // Context panel - derive directly from tabState (reactive!)
  const isContextPanelVisible = tabState?.showContextPanel ?? false;

  const setContextPanelVisible = useCallback(
    (visible: boolean): void => {
      if (!tabId) return;
      setContextPanelVisibleForTab(tabId, visible);
    },
    [tabId, setContextPanelVisibleForTab]
  );

  // Context phase selection - derive from tabState
  const selectedContextPhase = tabState?.selectedContextPhase ?? null;

  const setSelectedContextPhase = useCallback(
    (phase: number | null): void => {
      if (!tabId) return;
      setSelectedContextPhaseForTab(tabId, phase);
    },
    [tabId, setSelectedContextPhaseForTab]
  );

  // Scroll position - derive from tabState
  const savedScrollTop = tabState?.savedScrollTop;

  const saveScrollPosition = useCallback(
    (scrollTop: number): void => {
      if (!tabId) return;
      saveScrollPositionForTab(tabId, scrollTop);
    },
    [tabId, saveScrollPositionForTab]
  );

  // Initialize tab UI state (call once when tab is mounted)
  const initializeTabUI = useCallback((): void => {
    if (!tabId) return;
    initTabUIState(tabId);
  }, [tabId, initTabUIState]);

  return {
    // Current tab ID
    tabId,

    // AI Group expansion
    isAIGroupExpanded,
    toggleAIGroupExpansion,
    expandAIGroup,

    // Display item expansion
    getExpandedDisplayItemIds,
    toggleDisplayItemExpansion,
    expandDisplayItem,

    // Subagent trace expansion
    isSubagentTraceExpanded,
    toggleSubagentTraceExpansion,
    expandSubagentTrace,

    // Context panel
    isContextPanelVisible,
    setContextPanelVisible,

    // Context phase selection
    selectedContextPhase,
    setSelectedContextPhase,

    // Scroll position
    savedScrollTop,
    saveScrollPosition,

    // Initialization
    initializeTabUI,
  };
}
