"use client";

import React, { createContext, useContext, useState, useCallback, useEffect, ReactNode } from "react";

export interface TabItem {
  id: string;
  screenId: number;
  menuObjid?: number;
  screenName: string;
  menuName?: string;
  parentMenuName?: string;
  isAdminMode?: boolean;
}

interface TabContextType {
  tabs: TabItem[];
  activeTabId: string | null;
  refreshKeys: Record<string, number>;
  openTab: (tab: Omit<TabItem, "id">, insertIndex?: number) => void;
  closeTab: (tabId: string) => void;
  closeOtherTabs: (tabId: string) => void;
  closeAllTabs: () => void;
  closeTabsToTheLeft: (tabId: string) => void;
  closeTabsToTheRight: (tabId: string) => void;
  switchTab: (tabId: string) => void;
  getActiveTab: () => TabItem | undefined;
  updateTabOrder: (newOrder: string[]) => void;
  refreshTab: (tabId: string) => void;
}

const TAB_STORAGE_KEY = "erp_open_tabs";
const ACTIVE_TAB_STORAGE_KEY = "erp_active_tab";

const TabContext = createContext<TabContextType | undefined>(undefined);

function generateTabId(screenId: number, menuObjid?: number): string {
  return `tab-${screenId}-${menuObjid || "default"}`;
}

function clearTabStateCache(tab: TabItem) {
  try {
    // 페이지 레벨 캐시 삭제
    sessionStorage.removeItem(`tab-cache-${tab.screenId}-${tab.menuObjid || "default"}`);

    // 페이지 스크롤 위치 캐시 삭제
    sessionStorage.removeItem(`page-scroll-${tab.screenId}-${tab.menuObjid || "default"}`);

    // 하위 컴포넌트 캐시 삭제 (category-mgr, category-widget)
    if (tab.menuObjid) {
      sessionStorage.removeItem(`category-mgr-${tab.menuObjid}`);
      sessionStorage.removeItem(`category-widget-${tab.menuObjid}`);
    }
    sessionStorage.removeItem(`category-mgr-${tab.screenId}`);
    sessionStorage.removeItem(`category-widget-${tab.screenId}`);

    // TSP: 하위 컴포넌트 캐시 일괄 삭제 (레거시 + 새 usePersistedState 훅)
    const prefixes = [
      `tsp-${tab.screenId}-`,
      `tabs-session-${tab.menuObjid || "g"}-`,
      `table-state-${tab.screenId}-`,
      `split-sel-${tab.screenId}-`,
      `catval-sel-${tab.screenId}-`,
      `category-mgr-${tab.menuObjid || tab.screenId}-`,
      `bom-tree-${tab.screenId}-`,
    ];
    const keysToRemove: string[] = [];
    for (let i = 0; i < sessionStorage.length; i++) {
      const key = sessionStorage.key(i);
      if (key && prefixes.some(p => key.startsWith(p))) {
        keysToRemove.push(key);
      }
    }
    keysToRemove.forEach(k => sessionStorage.removeItem(k));
  } catch { /* 무시 */ }
}

function loadTabsFromStorage(): { tabs: TabItem[]; activeTabId: string | null } {
  if (typeof window === "undefined") return { tabs: [], activeTabId: null };

  try {
    const tabsJson = sessionStorage.getItem(TAB_STORAGE_KEY);
    const activeTabId = sessionStorage.getItem(ACTIVE_TAB_STORAGE_KEY);
    const tabs = tabsJson ? JSON.parse(tabsJson) : [];
    return { tabs, activeTabId };
  } catch {
    return { tabs: [], activeTabId: null };
  }
}

function saveTabsToStorage(tabs: TabItem[], activeTabId: string | null) {
  if (typeof window === "undefined") return;

  try {
    sessionStorage.setItem(TAB_STORAGE_KEY, JSON.stringify(tabs));
    if (activeTabId) {
      sessionStorage.setItem(ACTIVE_TAB_STORAGE_KEY, activeTabId);
    } else {
      sessionStorage.removeItem(ACTIVE_TAB_STORAGE_KEY);
    }
  } catch {
    // sessionStorage 용량 초과 등 무시
  }
}

export function TabProvider({ children }: { children: ReactNode }) {
  const [tabs, setTabs] = useState<TabItem[]>([]);
  const [activeTabId, setActiveTabId] = useState<string | null>(null);
  const [initialized, setInitialized] = useState(false);
  const [refreshKeys, setRefreshKeys] = useState<Record<string, number>>({});

  // sessionStorage에서 복원
  useEffect(() => {
    const { tabs: savedTabs, activeTabId: savedActiveTabId } = loadTabsFromStorage();
    if (savedTabs.length > 0) {
      setTabs(savedTabs);
      const activeId = savedActiveTabId && savedTabs.some(t => t.id === savedActiveTabId) ? savedActiveTabId : savedTabs[0].id;
      setActiveTabId(activeId);

      // 활성 탭의 상태 캐시 삭제 (F5 시 활성 탭은 정상 새로고침)
      const activeTab = savedTabs.find(t => t.id === activeId);
      if (activeTab) {
        clearTabStateCache(activeTab);
      }
    }
    setInitialized(true);
  }, []);

  // 상태 변경 시 sessionStorage에 저장
  useEffect(() => {
    if (!initialized) return;
    saveTabsToStorage(tabs, activeTabId);
  }, [tabs, activeTabId, initialized]);

  const openTab = useCallback((tabData: Omit<TabItem, "id">, insertIndex?: number) => {
    const tabId = generateTabId(tabData.screenId, tabData.menuObjid);

    setTabs((prevTabs) => {
      const existingTab = prevTabs.find(t => t.screenId === tabData.screenId);
      if (existingTab) {
        setActiveTabId(existingTab.id);
        return prevTabs;
      }

      const newTab: TabItem = { ...tabData, id: tabId };
      setActiveTabId(tabId);

      if (insertIndex !== undefined && insertIndex >= 0 && insertIndex <= prevTabs.length) {
        const newTabs = [...prevTabs];
        newTabs.splice(insertIndex, 0, newTab);
        return newTabs;
      }
      return [...prevTabs, newTab];
    });
  }, []);

  const closeTab = useCallback((tabId: string) => {
    setTabs((prevTabs) => {
      const tabIndex = prevTabs.findIndex(t => t.id === tabId);
      if (tabIndex === -1) return prevTabs;

      clearTabStateCache(prevTabs[tabIndex]);

      const newTabs = prevTabs.filter(t => t.id !== tabId);

      setActiveTabId((prevActiveId) => {
        if (prevActiveId === tabId) {
          if (newTabs.length === 0) return null;
          const nextIndex = Math.min(tabIndex, newTabs.length - 1);
          return newTabs[nextIndex].id;
        }
        return prevActiveId;
      });

      return newTabs;
    });
  }, []);

  const closeOtherTabs = useCallback((tabId: string) => {
    setTabs((prevTabs) => {
      const keepTab = prevTabs.find(t => t.id === tabId);
      if (!keepTab) return prevTabs;
      prevTabs.filter(t => t.id !== tabId).forEach(clearTabStateCache);
      setActiveTabId(tabId);
      return [keepTab];
    });
  }, []);

  const closeAllTabs = useCallback(() => {
    setTabs((prevTabs) => {
      prevTabs.forEach(clearTabStateCache);
      return [];
    });
    setActiveTabId(null);
  }, []);

  const closeTabsToTheLeft = useCallback((tabId: string) => {
    setTabs((prevTabs) => {
      const tabIndex = prevTabs.findIndex(t => t.id === tabId);
      if (tabIndex <= 0) return prevTabs;

      prevTabs.slice(0, tabIndex).forEach(clearTabStateCache);
      const newTabs = prevTabs.slice(tabIndex);

      setActiveTabId((prevActiveId) => {
        if (prevActiveId && !newTabs.find(t => t.id === prevActiveId)) {
          return tabId;
        }
        return prevActiveId;
      });

      return newTabs;
    });
  }, []);

  const closeTabsToTheRight = useCallback((tabId: string) => {
    setTabs((prevTabs) => {
      const tabIndex = prevTabs.findIndex(t => t.id === tabId);
      if (tabIndex === -1) return prevTabs;

      prevTabs.slice(tabIndex + 1).forEach(clearTabStateCache);
      const newTabs = prevTabs.slice(0, tabIndex + 1);

      setActiveTabId((prevActiveId) => {
        if (prevActiveId && !newTabs.find(t => t.id === prevActiveId)) {
          return tabId;
        }
        return prevActiveId;
      });

      return newTabs;
    });
  }, []);

  const switchTab = useCallback((tabId: string) => {
    setActiveTabId(tabId);
  }, []);

  const getActiveTab = useCallback(() => {
    return tabs.find(t => t.id === activeTabId);
  }, [tabs, activeTabId]);

  const refreshTab = useCallback((tabId: string) => {
    const tab = tabs.find(t => t.id === tabId);
    if (tab) clearTabStateCache(tab);
    setRefreshKeys(prev => ({ ...prev, [tabId]: (prev[tabId] || 0) + 1 }));
  }, [tabs]);

  const updateTabOrder = useCallback((newOrder: string[]) => {
    setTabs((prevTabs) => {
      const tabMap = new Map(prevTabs.map(t => [t.id, t]));
      const reordered = newOrder
        .map(id => tabMap.get(id))
        .filter((t): t is TabItem => t !== undefined);
      // 드래그에 포함되지 않은 탭(오버플로우 등)은 뒤에 유지
      const remaining = prevTabs.filter(t => !newOrder.includes(t.id));
      return [...reordered, ...remaining];
    });
  }, []);

  return (
    <TabContext.Provider
      value={{
        tabs,
        activeTabId,
        refreshKeys,
        openTab,
        closeTab,
        closeOtherTabs,
        closeAllTabs,
        closeTabsToTheLeft,
        closeTabsToTheRight,
        switchTab,
        getActiveTab,
        updateTabOrder,
        refreshTab,
      }}
    >
      {children}
    </TabContext.Provider>
  );
}

export function useTab() {
  const context = useContext(TabContext);
  if (context === undefined) {
    throw new Error("useTab must be used within a TabProvider");
  }
  return context;
}
