import React, { createContext, useContext, useState, useCallback, useMemo, ReactNode } from "react";
import { TableRegistration, TableOptionsContextValue } from "@/types/table-options";
import { useActiveTab } from "./ActiveTabContext";

const TableOptionsContext = createContext<TableOptionsContextValue | undefined>(undefined);

export const TableOptionsProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
  const [registeredTables, setRegisteredTables] = useState<Map<string, TableRegistration>>(new Map());
  const [selectedTableId, setSelectedTableId] = useState<string | null>(null);

  /**
   * 테이블 등록
   */
  const registerTable = useCallback((registration: TableRegistration) => {
    setRegisteredTables((prev) => {
      const newMap = new Map(prev);
      newMap.set(registration.tableId, registration);

      // 첫 번째 테이블이면 자동 선택
      if (newMap.size === 1) {
        setSelectedTableId(registration.tableId);
      }

      return newMap;
    });
  }, []);

  /**
   * 테이블 등록 해제
   * 주의:
   * 1. selectedTableId를 의존성으로 사용하면 무한 루프 발생 가능
   * 2. 재등록 시에도 unregister가 호출되므로 selectedTableId를 변경하면 안됨
   */
  const unregisterTable = useCallback(
    (tableId: string) => {
      setRegisteredTables((prev) => {
        const newMap = new Map(prev);
        newMap.delete(tableId);
        return newMap;
      });

      // 🚫 selectedTableId를 변경하지 않음
      // 이유: useEffect 재실행 시 cleanup → register 순서로 호출되는데,
      // cleanup에서 selectedTableId를 null로 만들면 필터 설정이 초기화됨
      // 다른 테이블이 선택되어야 하면 TableSearchWidget에서 자동 선택함
    },
    [], // 의존성 없음 - 무한 루프 방지
  );

  /**
   * 특정 테이블 조회
   */
  const getTable = useCallback(
    (tableId: string) => {
      return registeredTables.get(tableId);
    },
    [registeredTables],
  );

  /**
   * 테이블 데이터 건수 업데이트
   */
  const updateTableDataCount = useCallback((tableId: string, count: number) => {
    setRegisteredTables((prev) => {
      const table = prev.get(tableId);
      if (table) {
        // 기존 테이블 정보에 dataCount만 업데이트
        const updatedTable = { ...table, dataCount: count };
        const newMap = new Map(prev);
        newMap.set(tableId, updatedTable);
        return newMap;
      }
      return prev;
    });
  }, []);

  // ActiveTab context 사용 (optional - 에러 방지)
  const activeTabContext = useActiveTab();

  /**
   * 현재 활성 탭의 테이블만 반환
   */
  const getActiveTabTables = useCallback(() => {
    const allTables = Array.from(registeredTables.values());
    const activeTabIds = activeTabContext.getAllActiveTabIds();

    // 활성 탭이 없으면 탭에 속하지 않은 테이블만 반환
    if (activeTabIds.length === 0) {
      return allTables.filter((table) => !table.parentTabId);
    }

    // 활성 탭에 속한 테이블 + 탭에 속하지 않은 테이블
    return allTables.filter((table) => !table.parentTabId || activeTabIds.includes(table.parentTabId));
  }, [registeredTables, activeTabContext]);

  /**
   * 특정 탭의 테이블만 반환
   */
  const getTablesForTab = useCallback(
    (tabId: string) => {
      const allTables = Array.from(registeredTables.values());
      return allTables.filter((table) => table.parentTabId === tabId);
    },
    [registeredTables],
  );

  return (
    <TableOptionsContext.Provider
      value={{
        registeredTables,
        registerTable,
        unregisterTable,
        getTable,
        updateTableDataCount,
        selectedTableId,
        setSelectedTableId,
        getActiveTabTables,
        getTablesForTab,
      }}
    >
      {children}
    </TableOptionsContext.Provider>
  );
};

/**
 * Context Hook
 */
export const useTableOptions = () => {
  const context = useContext(TableOptionsContext);
  if (!context) {
    throw new Error("useTableOptions must be used within TableOptionsProvider");
  }
  return context;
};
