"use client";

import React, { useState, useEffect, useCallback } from "react";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Button } from "@/components/ui/button";
import { X, Loader2 } from "lucide-react";
import type { TabsComponent, TabItem, TabInlineComponent, ComponentData } from "@/types/screen-management";
import { cn } from "@/lib/utils";
import { useActiveTab } from "@/contexts/ActiveTabContext";
import { DynamicComponentRenderer } from "@/lib/registry/DynamicComponentRenderer";
import { screenApi } from "@/lib/api/screen";
import { ResponsiveGridRenderer } from "@/components/screen/ResponsiveGridRenderer";

// 확장된 TabItem 타입 (screenId 지원)
interface ExtendedTabItem extends TabItem {
  screenId?: number;
  screenName?: string;
}

interface TabsWidgetProps {
  component: TabsComponent;
  className?: string;
  style?: React.CSSProperties;
  menuObjid?: number;
  formData?: Record<string, any>;
  onFormDataChange?: (fieldName: string, value: any) => void;
  isDesignMode?: boolean;
  onComponentSelect?: (tabId: string, componentId: string) => void;
  selectedComponentId?: string;
  // 테이블 선택된 행 데이터 (버튼 활성화 및 수정/삭제 동작에 필요)
  selectedRowsData?: any[];
  onSelectedRowsChange?: (
    selectedRows: any[],
    selectedRowsData: any[],
    sortBy?: string,
    sortOrder?: "asc" | "desc",
    columnOrder?: string[],
  ) => void;
  // 추가 props (부모에서 전달받은 나머지 props)
  [key: string]: any;
}

export function TabsWidget({
  component,
  className,
  style,
  menuObjid,
  formData = {},
  onFormDataChange,
  isDesignMode = false,
  onComponentSelect,
  selectedComponentId,
  selectedRowsData: _externalSelectedRowsData,
  onSelectedRowsChange: externalOnSelectedRowsChange,
  ...restProps
}: TabsWidgetProps) {
  const { setActiveTab, removeTabsComponent } = useActiveTab();
  const {
    tabs = [],
    defaultTab,
    orientation = "horizontal",
    variant = "default",
    allowCloseable = false,
    persistSelection = false,
  } = component;

  const storageKey = `tabs-${component.id}-selected`;

  // 탭 내부 자체 selectedRowsData 상태 관리 (항상 로컬 상태 사용)
  // 부모에서 빈 배열 []이 전달되어도 로컬 상태를 우선하여 탭 내부 버튼이 즉시 인식
  const [localSelectedRowsData, setLocalSelectedRowsData] = useState<any[]>([]);

  // 선택 변경 핸들러: 로컬 상태 업데이트 + 부모 콜백 호출
  const handleSelectedRowsChange = useCallback(
    (
      selectedRows: any[],
      selectedRowsDataNew: any[],
      sortBy?: string,
      sortOrder?: "asc" | "desc",
      columnOrder?: string[],
    ) => {
      // 로컬 상태 업데이트 (탭 내부 버튼이 즉시 인식)
      setLocalSelectedRowsData(selectedRowsDataNew);

      // 부모 콜백 호출 (부모 상태도 업데이트)
      if (externalOnSelectedRowsChange) {
        externalOnSelectedRowsChange(selectedRows, selectedRowsDataNew, sortBy, sortOrder, columnOrder);
      }
    },
    [externalOnSelectedRowsChange],
  );

  // 초기 선택 탭 결정
  const getInitialTab = () => {
    if (persistSelection && typeof window !== "undefined") {
      const saved = localStorage.getItem(storageKey);
      if (saved && tabs.some((t) => t.id === saved)) {
        return saved;
      }
    }
    return defaultTab || tabs[0]?.id || "";
  };

  const [selectedTab, setSelectedTab] = useState<string>(getInitialTab());
  const [visibleTabs, setVisibleTabs] = useState<ExtendedTabItem[]>(tabs as ExtendedTabItem[]);
  const [mountedTabs, setMountedTabs] = useState<Set<string>>(() => new Set([getInitialTab()]));

  // 🆕 화면 진입 시 첫 번째 탭 자동 선택 및 마운트
  useEffect(() => {
    // 현재 선택된 탭이 유효하지 않거나 비어있으면 첫 번째 탭 선택
    const validTabs = (tabs as ExtendedTabItem[]).filter((tab) => !tab.disabled);
    const firstValidTabId = validTabs[0]?.id;

    if (firstValidTabId) {
      // 선택된 탭이 없거나 유효하지 않으면 첫 번째 탭으로 설정
      setSelectedTab((currentSelected) => {
        if (!currentSelected || !validTabs.some((t) => t.id === currentSelected)) {
          return firstValidTabId;
        }
        return currentSelected;
      });

      // 첫 번째 탭이 mountedTabs에 없으면 추가
      setMountedTabs((prev) => {
        const newSet = new Set(prev);
        // 첫 번째 탭 추가
        if (firstValidTabId && !newSet.has(firstValidTabId)) {
          newSet.add(firstValidTabId);
        }
        return newSet;
      });
    }
  }, [tabs]); // tabs가 변경될 때마다 실행

  // screenId 기반 화면 로드 상태
  const [screenLayouts, setScreenLayouts] = useState<Record<string, ComponentData[]>>({});
  const [screenLoadingStates, setScreenLoadingStates] = useState<Record<string, boolean>>({});
  const [screenErrors, setScreenErrors] = useState<Record<string, string>>({});
  // 탭별 화면 정보 (screenId, tableName) - 인라인 컴포넌트의 테이블 설정에서 추출
  const screenInfoMap = React.useMemo(() => {
    const map: Record<string, { id?: number; tableName?: string }> = {};
    for (const tab of tabs as ExtendedTabItem[]) {
      const inlineComponents = tab.components || [];
      if (inlineComponents.length > 0) {
        // 인라인 컴포넌트에서 테이블 컴포넌트의 selectedTable 추출
        const tableComp = inlineComponents.find(
          (c) => c.componentType === "v2-table-list" || c.componentType === "table-list",
        );
        const selectedTable = tableComp?.componentConfig?.selectedTable;
        if (selectedTable || tab.screenId) {
          map[tab.id] = {
            id: tab.screenId,
            tableName: selectedTable,
          };
        }
      }
    }
    return map;
  }, [tabs]);

  // 컴포넌트 탭 목록 변경 시 동기화
  useEffect(() => {
    setVisibleTabs((tabs as ExtendedTabItem[]).filter((tab) => !tab.disabled));
  }, [tabs]);

  // screenId가 있는 탭의 화면 레이아웃 로드
  useEffect(() => {
    const loadScreenLayouts = async () => {
      for (const tab of visibleTabs) {
        const extTab = tab as ExtendedTabItem;
        // screenId가 있고, 아직 로드하지 않았으며, 인라인 컴포넌트가 없는 경우만 로드
        if (
          extTab.screenId &&
          !screenLayouts[tab.id] &&
          !screenLoadingStates[tab.id] &&
          (!extTab.components || extTab.components.length === 0)
        ) {
          setScreenLoadingStates((prev) => ({ ...prev, [tab.id]: true }));
          try {
            const layoutData = await screenApi.getLayout(extTab.screenId);
            if (layoutData && layoutData.components) {
              setScreenLayouts((prev) => ({ ...prev, [tab.id]: layoutData.components }));
            }
          } catch (error) {
            console.error(`탭 "${tab.label}" 화면 로드 실패:`, error);
            setScreenErrors((prev) => ({ ...prev, [tab.id]: "화면을 불러올 수 없습니다." }));
          } finally {
            setScreenLoadingStates((prev) => ({ ...prev, [tab.id]: false }));
          }
        }
      }
    };

    loadScreenLayouts();
  }, [visibleTabs, screenLayouts, screenLoadingStates]);

  // 선택된 탭 변경 시 localStorage에 저장 + ActiveTab Context 업데이트
  useEffect(() => {
    if (persistSelection && typeof window !== "undefined") {
      localStorage.setItem(storageKey, selectedTab);
    }

    const currentTabInfo = visibleTabs.find((t) => t.id === selectedTab);
    if (currentTabInfo) {
      setActiveTab(component.id, {
        tabId: selectedTab,
        tabsComponentId: component.id,
        label: currentTabInfo.label,
      });
    }
  }, [selectedTab, persistSelection, storageKey, component.id, visibleTabs, setActiveTab]);

  // 컴포넌트 언마운트 시 ActiveTab Context에서 제거
  useEffect(() => {
    return () => {
      removeTabsComponent(component.id);
    };
  }, [component.id, removeTabsComponent]);

  // 탭 변경 핸들러
  const handleTabChange = (tabId: string) => {
    setSelectedTab(tabId);

    setMountedTabs((prev) => {
      if (prev.has(tabId)) return prev;
      const newSet = new Set(prev);
      newSet.add(tabId);
      return newSet;
    });
  };

  // 탭 닫기 핸들러
  const handleCloseTab = (tabId: string, e: React.MouseEvent) => {
    e.stopPropagation();

    const updatedTabs = visibleTabs.filter((tab) => tab.id !== tabId);
    setVisibleTabs(updatedTabs);

    if (selectedTab === tabId && updatedTabs.length > 0) {
      setSelectedTab(updatedTabs[0].id);
    }
  };

  // 탭 스타일 클래스
  const getTabsListClass = () => {
    const baseClass = orientation === "vertical" ? "flex-col" : "";
    const variantClass =
      variant === "pills" ? "bg-muted p-1 rounded-lg" : variant === "underline" ? "border-b" : "bg-muted p-1";
    return `${baseClass} ${variantClass}`;
  };

  // 탭 컨텐츠 렌더링 (screenId 또는 인라인 컴포넌트)
  const renderTabContent = (tab: ExtendedTabItem) => {
    const extTab = tab as ExtendedTabItem;
    const inlineComponents = tab.components || [];

    // 1. screenId가 있고 인라인 컴포넌트가 없는 경우 -> 화면 로드 방식
    if (extTab.screenId && inlineComponents.length === 0) {
      // 로딩 중
      if (screenLoadingStates[tab.id]) {
        return (
          <div className="flex h-full w-full items-center justify-center">
            <Loader2 className="text-primary h-8 w-8 animate-spin" />
            <span className="text-muted-foreground ml-2">화면을 불러오는 중...</span>
          </div>
        );
      }

      // 에러 발생
      if (screenErrors[tab.id]) {
        return (
          <div className="border-destructive/50 bg-destructive/5 flex h-full w-full items-center justify-center rounded border-2 border-dashed">
            <p className="text-destructive text-sm">{screenErrors[tab.id]}</p>
          </div>
        );
      }

      // 화면 레이아웃이 로드된 경우
      const loadedComponents = screenLayouts[tab.id];
      if (loadedComponents && loadedComponents.length > 0) {
        return renderScreenComponents(tab, loadedComponents);
      }

      // 아직 로드되지 않은 경우
      return (
        <div className="flex h-full w-full items-center justify-center">
          <Loader2 className="text-primary h-8 w-8 animate-spin" />
        </div>
      );
    }

    // 2. 인라인 컴포넌트가 있는 경우 -> 기존 v2 방식
    if (inlineComponents.length > 0) {
      return renderInlineComponents(tab, inlineComponents);
    }

    // 3. 둘 다 없는 경우
    return (
      <div className="flex h-full w-full items-center justify-center rounded border-2 border-dashed border-input bg-muted">
        <p className="text-muted-foreground text-sm">
          {isDesignMode ? "컴포넌트를 드래그하여 추가하세요" : "컴포넌트가 없습니다"}
        </p>
      </div>
    );
  };

  // screenId로 로드한 화면 컴포넌트 렌더링
  const renderScreenComponents = (tab: ExtendedTabItem, components: ComponentData[]) => {
    const InteractiveScreenViewerDynamic =
      require("@/components/screen/InteractiveScreenViewerDynamic").InteractiveScreenViewerDynamic;

    const canvasWidth = Math.max(
      ...components.map((c) => (c.position?.x || 0) + (c.size?.width || 200)),
      800,
    );
    const canvasHeight = Math.max(
      ...components.map((c) => (c.position?.y || 0) + (c.size?.height || 100)),
      400,
    );

    return (
      <ResponsiveGridRenderer
        components={components}
        canvasWidth={canvasWidth}
        canvasHeight={canvasHeight}
        renderComponent={(comp) => (
          <InteractiveScreenViewerDynamic
            component={comp}
            allComponents={components}
            formData={formData}
            onFormDataChange={onFormDataChange}
            screenInfo={screenInfoMap[tab.id]}
            menuObjid={menuObjid}
            parentTabId={tab.id}
            parentTabsComponentId={component.id}
          />
        )}
      />
    );
  };

  // 인라인 컴포넌트 렌더링 (v2 방식)
  const renderInlineComponents = (tab: ExtendedTabItem, components: TabInlineComponent[]) => {
    if (isDesignMode) {
      const maxBottom = Math.max(
        ...components.map((c) => (c.position?.y || 0) + (c.size?.height || 100)),
        300,
      );
      const maxRight = Math.max(
        ...components.map((c) => (c.position?.x || 0) + (c.size?.width || 200)),
        400,
      );

      return (
        <div
          className="relative"
          style={{ minHeight: maxBottom + 20, minWidth: maxRight + 20 }}
        >
          {components.map((comp: TabInlineComponent) => {
            const isSelected = selectedComponentId === comp.id;
            return (
              <div
                key={comp.id}
                className={cn("absolute cursor-move", isSelected && "ring-primary ring-2 ring-offset-2")}
                style={{
                  left: comp.position?.x || 0,
                  top: comp.position?.y || 0,
                  width: comp.size?.width || 200,
                  height: comp.size?.height || 100,
                }}
                onClick={(e) => {
                  if (onComponentSelect) {
                    e.stopPropagation();
                    onComponentSelect(tab.id, comp.id);
                  }
                }}
              >
                <DynamicComponentRenderer
                  {...restProps}
                  component={{
                    id: comp.id,
                    type: "component" as const,
                    componentType: comp.componentType,
                    label: comp.label,
                    position: comp.position,
                    size: comp.size,
                    componentConfig: comp.componentConfig || {},
                    style: comp.style,
                  } as any}
                  formData={formData}
                  onFormDataChange={onFormDataChange}
                  menuObjid={menuObjid}
                  isDesignMode={true}
                  isInteractive={false}
                  selectedRowsData={localSelectedRowsData}
                  onSelectedRowsChange={handleSelectedRowsChange}
                  parentTabId={tab.id}
                  parentTabsComponentId={component.id}
                  {...(screenInfoMap[tab.id]
                    ? { tableName: screenInfoMap[tab.id].tableName, screenId: screenInfoMap[tab.id].id }
                    : {})}
                />
              </div>
            );
          })}
        </div>
      );
    }

    // 런타임: ResponsiveGridRenderer 사용
    const canvasWidth = Math.max(
      ...components.map((c) => (c.position?.x || 0) + (c.size?.width || 200)),
      800,
    );
    const canvasHeight = Math.max(
      ...components.map((c) => (c.position?.y || 0) + (c.size?.height || 100)),
      400,
    );

    const componentDataList: ComponentData[] = components.map((comp) => ({
      id: comp.id,
      componentType: comp.componentType,
      label: comp.label,
      position: comp.position,
      size: comp.size,
      componentConfig: comp.componentConfig || {},
      style: comp.style,
      type: "component",
    })) as any;

    return (
      <ResponsiveGridRenderer
          components={componentDataList}
          canvasWidth={canvasWidth}
          canvasHeight={canvasHeight}
          renderComponent={(comp) => (
            <DynamicComponentRenderer
              {...restProps}
              component={comp}
              formData={formData}
              onFormDataChange={onFormDataChange}
              menuObjid={menuObjid}
              isDesignMode={false}
              isInteractive={true}
              selectedRowsData={localSelectedRowsData}
              onSelectedRowsChange={handleSelectedRowsChange}
              parentTabId={tab.id}
              parentTabsComponentId={component.id}
              {...(screenInfoMap[tab.id]
                ? { tableName: screenInfoMap[tab.id].tableName, screenId: screenInfoMap[tab.id].id }
                : {})}
            />
          )}
        />
    );
  };

  if (visibleTabs.length === 0) {
    return (
      <div className="flex h-full w-full items-center justify-center rounded border-2 border-dashed border-input bg-muted">
        <p className="text-muted-foreground text-sm">탭이 없습니다</p>
      </div>
    );
  }

  return (
    <div className={cn("flex h-full w-full flex-col pt-4", className)} style={style}>
      <Tabs
        value={selectedTab}
        onValueChange={handleTabChange}
        orientation={orientation}
        className="flex h-full w-full flex-col"
      >
        <div className="relative z-10">
          <TabsList className={getTabsListClass()}>
            {visibleTabs.map((tab) => (
              <div key={tab.id} className="relative">
                <TabsTrigger value={tab.id} disabled={tab.disabled} className="relative pr-8">
                  {tab.label}
                </TabsTrigger>
                {allowCloseable && (
                  <Button
                    onClick={(e) => handleCloseTab(tab.id, e)}
                    variant="ghost"
                    size="sm"
                    className="hover:bg-destructive/10 absolute top-1/2 right-1 h-5 w-5 -translate-y-1/2 p-0"
                  >
                    <X className="h-3 w-3" />
                  </Button>
                )}
              </div>
            ))}
          </TabsList>
        </div>

        <div className="relative flex-1 overflow-auto">
          {visibleTabs.map((tab) => {
            const shouldRender = mountedTabs.has(tab.id);
            const isActive = selectedTab === tab.id;

            return (
              <TabsContent
                key={tab.id}
                value={tab.id}
                forceMount
                className={cn("h-full overflow-auto", !isActive && "hidden")}
              >
                {shouldRender && renderTabContent(tab)}
              </TabsContent>
            );
          })}
        </div>
      </Tabs>
    </div>
  );
}
