"use client";

import React, { useState, useCallback, useEffect, useMemo } from "react";
import { Button } from "@/components/ui/button";
import { toast } from "react-hot-toast";
import { Loader2, CheckCircle2, AlertCircle, Clock, Workflow } from "lucide-react";
import { ComponentData, ButtonActionType } from "@/types/screen";
import {
  optimizedButtonDataflowService,
  OptimizedButtonDataflowService,
  ExtendedControlContext,
} from "@/lib/services/optimizedButtonDataflowService";
import { dataflowJobQueue } from "@/lib/services/dataflowJobQueue";
import { cn } from "@/lib/utils";
import { Badge } from "@/components/ui/badge";
import { executeButtonWithFlow, handleFlowExecutionResult } from "@/lib/utils/nodeFlowButtonExecutor";
import { useCurrentFlowStep } from "@/stores/flowStepStore";
import { ButtonIconRenderer, getButtonDisplayContent } from "@/lib/button-icon-map";

interface OptimizedButtonProps {
  component: ComponentData;
  onDataflowComplete?: (result: any) => void;
  onActionComplete?: (result: any) => void;
  formData?: Record<string, any>;
  companyCode?: string;
  disabled?: boolean;
  selectedRows?: any[];
  selectedRowsData?: any[];
  flowSelectedData?: any[];
  flowSelectedStepId?: number | null;
  
  // 🆕 테이블 전체 데이터 (table-all 모드용)
  tableAllData?: any[];
  
  // 🆕 플로우 스텝 전체 데이터 (flow-step-all 모드용)
  flowStepAllData?: any[];
  
  // 🆕 테이블 전체 데이터 로드 콜백 (필요 시 부모에서 제공)
  onRequestTableAllData?: () => Promise<any[]>;
  
  // 🆕 플로우 스텝 전체 데이터 로드 콜백 (필요 시 부모에서 제공)
  onRequestFlowStepAllData?: (stepId: number) => Promise<any[]>;
}

/**
 * 🔥 성능 최적화된 버튼 컴포넌트
 *
 * 핵심 기능:
 * 1. 즉시 응답 (0-100ms)
 * 2. 백그라운드 제어관리 처리
 * 3. 실시간 상태 추적
 * 4. 디바운싱으로 중복 클릭 방지
 * 5. 시각적 피드백
 */
export const OptimizedButtonComponent: React.FC<OptimizedButtonProps> = ({
  component,
  onDataflowComplete,
  onActionComplete,
  formData = {},
  companyCode = "DEFAULT",
  disabled = false,
  selectedRows = [],
  selectedRowsData = [],
  flowSelectedData = [],
  flowSelectedStepId = null,
  tableAllData = [],
  flowStepAllData = [],
  onRequestTableAllData,
  onRequestFlowStepAllData,
}) => {
  // 🔥 상태 관리
  const [isExecuting, setIsExecuting] = useState(false);
  const [executionTime, setExecutionTime] = useState<number | null>(null);
  const [backgroundJobs, setBackgroundJobs] = useState<Set<string>>(new Set());
  const [lastResult, setLastResult] = useState<any>(null);
  const [clickCount, setClickCount] = useState(0);

  const config = component.webTypeConfig;
  const buttonLabel = component.label || "버튼";
  const flowConfig = config?.flowVisibilityConfig;

  // 🆕 현재 플로우 단계 구독
  const currentStep = useCurrentFlowStep(flowConfig?.targetFlowComponentId);

  // 🆕 버튼 표시 여부 계산
  const shouldShowButton = useMemo(() => {
    // 플로우 제어 비활성화 시 항상 표시
    if (!flowConfig?.enabled) {
      return true;
    }

    // 플로우 단계가 선택되지 않은 경우 처리
    if (currentStep === null) {
      // 🔧 화이트리스트 모드일 때는 단계 미선택 시 숨김
      if (flowConfig.mode === "whitelist") {
        console.log("🔍 [OptimizedButton] 화이트리스트 모드 + 단계 미선택 → 숨김");
        return false;
      }
      // 블랙리스트나 all 모드는 표시
      return true;
    }

    const { mode, visibleSteps = [], hiddenSteps = [] } = flowConfig;

    let result = true;
    if (mode === "whitelist") {
      result = visibleSteps.includes(currentStep);
    } else if (mode === "blacklist") {
      result = !hiddenSteps.includes(currentStep);
    } else if (mode === "all") {
      result = true;
    }

    // 항상 로그 출력 (개발 모드뿐만 아니라)
    console.log("🔍 [OptimizedButton] 표시 체크:", {
      buttonId: component.id,
      buttonLabel,
      flowComponentId: flowConfig.targetFlowComponentId,
      currentStep,
      mode,
      visibleSteps,
      hiddenSteps,
      result: result ? "표시 ✅" : "숨김 ❌",
    });

    return result;
  }, [flowConfig, currentStep, component.id, buttonLabel]);

  // 🔥 디바운싱된 클릭 핸들러 (300ms)
  const handleClick = useCallback(async () => {
    if (isExecuting || disabled) return;

    // 클릭 카운트 증가 (통계용)
    setClickCount((prev) => prev + 1);

    setIsExecuting(true);
    const startTime = performance.now();

    try {
      // console.log(`🔘 Button clicked: ${component.id} (${config?.actionType})`);

      // 🔥 확장된 컨텍스트 데이터 수집
      const contextData = {
        ...formData,
        buttonId: component.id,
        componentData: component,
        timestamp: new Date().toISOString(),
        clickCount,
      };

      // 🔥 확장된 제어 컨텍스트 생성
      const extendedContext = {
        formData,
        selectedRows: selectedRows || [],
        selectedRowsData: selectedRowsData || [],
        flowSelectedData: flowSelectedData || [],
        flowSelectedStepId: flowSelectedStepId,
        controlDataSource: config?.dataflowConfig?.controlDataSource || "form",
        buttonId: component.id,
        componentData: component,
        timestamp: new Date().toISOString(),
        clickCount,
      };

      // 🔥 제어 전용 액션인지 확인
      const isControlOnlyAction = config?.actionType === "control";

      // console.log("🎯 OptimizedButtonComponent 실행:", {
        // actionType: config?.actionType,
        // isControlOnlyAction,
        // enableDataflowControl: config?.enableDataflowControl,
        // hasDataflowConfig: !!config?.dataflowConfig,
        // selectedRows,
        // selectedRowsData,
      // });

      if (config?.enableDataflowControl && config?.dataflowConfig) {
        // 🆕 노드 플로우 방식 실행
        if (config.dataflowConfig.controlMode === "flow" && config.dataflowConfig.flowConfig) {
          console.log("🔄 노드 플로우 방식 실행:", config.dataflowConfig.flowConfig);
          console.log("📊 전달될 데이터 확인:", {
            controlDataSource: config.dataflowConfig.controlDataSource,
            formDataKeys: Object.keys(formData),
            selectedRowsDataLength: selectedRowsData.length,
            flowSelectedDataLength: flowSelectedData.length,
            flowSelectedStepId,
          });

          // 🆕 데이터 소스에 따라 추가 데이터 로드
          let preparedTableAllData = tableAllData;
          let preparedFlowStepAllData = flowStepAllData;

          const dataSource = config.dataflowConfig.controlDataSource;
          
          // table-all 모드일 때 데이터 로드
          if (dataSource === "table-all" || dataSource === "all-sources") {
            if (tableAllData.length === 0 && onRequestTableAllData) {
              console.log("📊 테이블 전체 데이터 로드 중...");
              try {
                preparedTableAllData = await onRequestTableAllData();
                console.log(`✅ 테이블 전체 데이터 ${preparedTableAllData.length}건 로드 완료`);
              } catch (error) {
                console.error("❌ 테이블 전체 데이터 로드 실패:", error);
                toast.error("테이블 전체 데이터를 불러오지 못했습니다");
              }
            }
          }

          // flow-step-all 모드일 때 데이터 로드
          if ((dataSource === "flow-step-all" || dataSource === "all-sources") && flowSelectedStepId) {
            if (flowStepAllData.length === 0 && onRequestFlowStepAllData) {
              console.log(`📊 플로우 스텝 ${flowSelectedStepId} 전체 데이터 로드 중...`);
              try {
                preparedFlowStepAllData = await onRequestFlowStepAllData(flowSelectedStepId);
                console.log(`✅ 플로우 스텝 전체 데이터 ${preparedFlowStepAllData.length}건 로드 완료`);
              } catch (error) {
                console.error("❌ 플로우 스텝 전체 데이터 로드 실패:", error);
                toast.error("플로우 스텝 전체 데이터를 불러오지 못했습니다");
              }
            }
          }

          const flowResult = await executeButtonWithFlow(
            config.dataflowConfig.flowConfig,
            {
              buttonId: component.id,
              screenId: component.screenId,
              companyCode,
              userId: contextData.userId,
              formData,
              selectedRows: selectedRows || [],
              selectedRowsData: selectedRowsData || [],
              flowSelectedData: flowSelectedData || [],
              flowStepId: flowSelectedStepId || undefined,
              controlDataSource: config.dataflowConfig.controlDataSource,
              // 🆕 확장된 데이터 소스
              tableAllData: preparedTableAllData,
              flowStepAllData: preparedFlowStepAllData,
            },
            // 원래 액션 (timing이 before나 after일 때 실행)
            async () => {
              if (!isControlOnlyAction) {
                await executeOriginalAction(config?.actionType || "save", contextData);
              }
            },
          );

          handleFlowExecutionResult(flowResult, {
            buttonId: component.id,
            formData,
            onRefresh: onDataflowComplete,
          });

          if (onActionComplete) {
            onActionComplete(flowResult);
          }

          return;
        }

        // 🔥 기존 관계 방식 실행
        const validationResult = await OptimizedButtonDataflowService.executeExtendedValidation(
          config.dataflowConfig,
          extendedContext as ExtendedControlContext,
        );

        if (!validationResult.success) {
          toast.error(validationResult.message || "제어 조건을 만족하지 않습니다.");
          return;
        }

        // 🔥 제어 전용 액션이면 여기서 종료
        if (isControlOnlyAction) {
          toast.success("제어 조건을 만족합니다.");
          if (onActionComplete) {
            onActionComplete({ success: true, message: "제어 조건 통과" });
          }
          return;
        }

        // 🔥 최적화된 버튼 실행 (즉시 응답)
        await executeOptimizedButtonAction(contextData);
      } else if (isControlOnlyAction) {
        // 🔥 제어관리가 비활성화된 상태에서 제어 액션
        toast.warning(
          "제어관리를 먼저 활성화해주세요. 제어 액션을 사용하려면 버튼 설정에서 '제어관리 활성화'를 체크하고 조건을 설정해주세요.",
        );
        return;
      } else {
        // 🔥 기존 액션만 실행 (제어 액션 제외)
        await executeOriginalAction(config?.actionType || "save", contextData);
      }
    } catch (error) {
      // console.error("Button execution failed:", error);
      toast.error("버튼 실행 중 오류가 발생했습니다.");
      setLastResult({ success: false, error: error.message });
    } finally {
      const endTime = performance.now();
      const totalTime = endTime - startTime;
      setExecutionTime(totalTime);
      setIsExecuting(false);

      // 성능 로깅
      if (totalTime > 200) {
        // console.warn(`🐌 Slow button execution: ${totalTime.toFixed(2)}ms`);
      } else {
        // console.log(`⚡ Button execution: ${totalTime.toFixed(2)}ms`);
      }
    }
  }, [isExecuting, disabled, component.id, config?.actionType, config?.enableDataflowControl, formData, clickCount]);

  /**
   * 🔥 최적화된 버튼 액션 실행
   */
  const executeOptimizedButtonAction = async (contextData: Record<string, any>) => {
    const actionType = config?.actionType as ButtonActionType;

    if (!actionType) {
      throw new Error("액션 타입이 설정되지 않았습니다.");
    }

    // 🔥 API 호출 (즉시 응답)
    const result = await optimizedButtonDataflowService.executeButtonWithDataflow(
      component.id,
      actionType,
      config,
      contextData,
      companyCode,
    );

    const { jobId, immediateResult, isBackground, timing } = result;

    // 🔥 즉시 결과 처리
    if (immediateResult) {
      handleImmediateResult(actionType, immediateResult);
      setLastResult(immediateResult);

      // 사용자에게 즉시 피드백
      const message = getSuccessMessage(actionType, timing);
      if (immediateResult.success) {
        toast.success(message);
      } else {
        toast.error(immediateResult.message || "처리 중 오류가 발생했습니다.");
      }

      // 콜백 호출
      if (onActionComplete) {
        onActionComplete(immediateResult);
      }
    }

    // 🔥 백그라운드 작업 추적
    if (isBackground && jobId && jobId !== "immediate") {
      setBackgroundJobs((prev) => new Set([...prev, jobId]));

      // 백그라운드 작업 완료 대기 (선택적)
      if (timing === "before") {
        // before 타이밍은 결과를 기다려야 함
        await waitForBackgroundJob(jobId);
      } else {
        // after/replace 타이밍은 백그라운드에서 조용히 처리
        trackBackgroundJob(jobId);
      }
    }
  };

  /**
   * 🔥 즉시 결과 처리
   */
  const handleImmediateResult = (actionType: ButtonActionType, result: any) => {
    if (!result.success) return;

    switch (actionType) {
      case "save":
        // console.log("💾 Save action completed:", result);
        break;
      case "delete":
        // console.log("🗑️ Delete action completed:", result);
        break;
      case "search":
        // console.log("🔍 Search action completed:", result);
        break;
      case "add":
        // console.log("➕ Add action completed:", result);
        break;
      case "edit":
        // console.log("✏️ Edit action completed:", result);
        break;
      default:
        // console.log(`✅ ${actionType} action completed:`, result);
    }
  };

  /**
   * 🔥 성공 메시지 생성
   */
  const getSuccessMessage = (actionType: ButtonActionType, timing?: string): string => {
    const actionName = getActionDisplayName(actionType);

    switch (timing) {
      case "before":
        return `${actionName} 작업을 처리 중입니다...`;
      case "after":
        return `${actionName}이 완료되었습니다.`;
      case "replace":
        return `사용자 정의 작업을 처리 중입니다...`;
      default:
        return `${actionName}이 완료되었습니다.`;
    }
  };

  /**
   * 🔥 백그라운드 작업 추적 (polling 방식)
   */
  const trackBackgroundJob = (jobId: string) => {
    const pollInterval = 1000; // 1초
    let pollCount = 0;
    const maxPolls = 60; // 최대 1분

    const pollJobStatus = async () => {
      pollCount++;

      try {
        const status = optimizedButtonDataflowService.getJobStatus(jobId);

        if (status.status === "completed") {
          setBackgroundJobs((prev) => {
            const newSet = new Set(prev);
            newSet.delete(jobId);
            return newSet;
          });

          // 백그라운드 작업 완료 알림 (조용하게)
          if (status.result?.executedActions > 0) {
            toast.success(`추가 처리가 완료되었습니다. (${status.result.executedActions}개 액션)`, { duration: 2000 });
          }

          if (onDataflowComplete) {
            onDataflowComplete(status.result);
          }

          return;
        }

        if (status.status === "failed") {
          setBackgroundJobs((prev) => {
            const newSet = new Set(prev);
            newSet.delete(jobId);
            return newSet;
          });

          // console.error("Background job failed:", status.result);
          toast.error("백그라운드 처리 중 오류가 발생했습니다.", { duration: 3000 });
          return;
        }

        // 아직 진행 중이고 최대 횟수 미달 시 계속 polling
        if (pollCount < maxPolls && (status.status === "pending" || status.status === "processing")) {
          setTimeout(pollJobStatus, pollInterval);
        } else if (pollCount >= maxPolls) {
          // console.warn(`Background job polling timeout: ${jobId}`);
          setBackgroundJobs((prev) => {
            const newSet = new Set(prev);
            newSet.delete(jobId);
            return newSet;
          });
        }
      } catch (error) {
        // console.error("Failed to check job status:", error);
        setBackgroundJobs((prev) => {
          const newSet = new Set(prev);
          newSet.delete(jobId);
          return newSet;
        });
      }
    };

    // 첫 polling 시작
    setTimeout(pollJobStatus, 500);
  };

  /**
   * 🔥 백그라운드 작업 완료 대기 (before 타이밍용)
   */
  const waitForBackgroundJob = async (jobId: string): Promise<void> => {
    return new Promise((resolve, reject) => {
      const maxWaitTime = 30000; // 최대 30초 대기
      const pollInterval = 500; // 0.5초
      let elapsedTime = 0;

      const checkStatus = async () => {
        try {
          const status = optimizedButtonDataflowService.getJobStatus(jobId);

          if (status.status === "completed") {
            setBackgroundJobs((prev) => {
              const newSet = new Set(prev);
              newSet.delete(jobId);
              return newSet;
            });

            toast.success("모든 처리가 완료되었습니다.");

            if (onDataflowComplete) {
              onDataflowComplete(status.result);
            }

            resolve();
            return;
          }

          if (status.status === "failed") {
            setBackgroundJobs((prev) => {
              const newSet = new Set(prev);
              newSet.delete(jobId);
              return newSet;
            });

            toast.error("처리 중 오류가 발생했습니다.");
            reject(new Error(status.result?.error || "Unknown error"));
            return;
          }

          // 시간 체크
          elapsedTime += pollInterval;
          if (elapsedTime >= maxWaitTime) {
            reject(new Error("Processing timeout"));
            return;
          }

          // 계속 대기
          setTimeout(checkStatus, pollInterval);
        } catch (error) {
          reject(error);
        }
      };

      checkStatus();
    });
  };

  /**
   * 🔥 기존 액션 실행 (제어관리 없음)
   */
  const executeOriginalAction = async (
    actionType: ButtonActionType,
    contextData: Record<string, any>,
  ): Promise<any> => {
    // 🔥 제어 액션은 여기서 처리하지 않음 (이미 위에서 처리됨)
    if (actionType === "control") {
      // console.warn("제어 액션은 executeOriginalAction에서 처리되지 않아야 합니다.");
      return;
    }

    // 간단한 mock 처리 (실제로는 API 호출)
    await new Promise((resolve) => setTimeout(resolve, 100)); // 100ms 시뮬레이션

    const result = {
      success: true,
      message: `${getActionDisplayName(actionType)}이 완료되었습니다.`,
      actionType,
      timestamp: new Date().toISOString(),
    };

    setLastResult(result);
    toast.success(result.message);

    if (onActionComplete) {
      onActionComplete(result);
    }

    return result;
  };

  /**
   * 액션 타입별 표시명
   */
  const getActionDisplayName = (actionType: ButtonActionType): string => {
    const displayNames: Record<ButtonActionType, string> = {
      save: "저장",
      cancel: "취소",
      delete: "삭제",
      edit: "수정",
      copy: "복사",
      add: "추가",
      search: "검색",
      reset: "초기화",
      submit: "제출",
      close: "닫기",
      popup: "팝업",
      modal: "모달",
      newWindow: "새 창",
      navigate: "페이지 이동",
      control: "제어",
      transferData: "데이터 전달",
      quickInsert: "즉시 저장",
      approval: "결재",
    };
    return displayNames[actionType] || actionType;
  };

  /**
   * 버튼 상태에 따른 아이콘
   */
  const getStatusIcon = () => {
    if (isExecuting) {
      return <Loader2 className="h-4 w-4 animate-spin" />;
    }
    if (lastResult?.success === false) {
      return <AlertCircle className="h-4 w-4 text-destructive" />;
    }
    if (lastResult?.success === true) {
      return <CheckCircle2 className="h-4 w-4 text-emerald-500" />;
    }
    return null;
  };

  /**
   * 백그라운드 작업 상태 표시
   */
  const renderBackgroundStatus = () => {
    if (backgroundJobs.size === 0) return null;

    return (
      <div className="absolute -top-1 -right-1">
        <Badge variant="secondary" className="h-5 px-1 text-xs">
          <Clock className="mr-1 h-3 w-3" />
          {backgroundJobs.size}
        </Badge>
      </div>
    );
  };

  // 🆕 플로우 단계별 표시 제어
  if (!shouldShowButton) {
    // 레이아웃 동작에 따라 다르게 처리
    if (flowConfig?.layoutBehavior === "preserve-position") {
      // 위치 유지 (빈 공간, display: none)
      return <div style={{ display: "none" }} />;
    } else {
      // 완전히 렌더링하지 않음 (auto-compact, 빈 공간 제거)
      return null;
    }
  }

  // 색상이 설정되어 있으면 variant 스타일을 무시하고 직접 스타일 적용
  const hasCustomColors = config?.backgroundColor || config?.textColor;
  
  return (
    <div className="relative">
      <Button
        onClick={handleClick}
        disabled={isExecuting || disabled}
        variant={hasCustomColors ? undefined : (config?.variant || "default")}
        className={cn(
          "transition-all duration-200",
          isExecuting && "cursor-wait opacity-75",
          backgroundJobs.size > 0 && "border-primary/20 bg-accent",
          !hasCustomColors && "bg-primary text-primary-foreground hover:bg-primary/90",
        )}
        style={{
          ...(config?.backgroundColor && { backgroundColor: config.backgroundColor }),
          ...(config?.textColor && { color: config.textColor }),
          ...(config?.borderColor && { borderColor: config.borderColor }),
        }}
      >
        {/* 메인 버튼 내용 */}
        <div className="flex items-center space-x-2">
          {getStatusIcon()}
          <span>
            {isExecuting ? "처리 중..." : (
              <ButtonIconRenderer
                componentConfig={component.componentConfig}
                fallbackLabel={buttonLabel}
              />
            )}
          </span>
        </div>

        {/* 개발 모드에서 성능 정보 표시 */}
        {process.env.NODE_ENV === "development" && executionTime && (
          <span className="ml-2 text-xs opacity-60">{executionTime.toFixed(0)}ms</span>
        )}
      </Button>

      {/* 백그라운드 작업 상태 표시 */}
      {renderBackgroundStatus()}

      {/* 🆕 플로우 제어 활성화 표시 */}
      {flowConfig?.enabled && (
        <div className="absolute -right-1 -top-1">
          <Badge variant="outline" className="h-4 bg-white px-1 text-xs" title="플로우 단계별 표시 제어 활성화">
            <Workflow className="h-3 w-3" />
          </Badge>
        </div>
      )}

      {/* 제어관리 활성화 표시 */}
      {config?.enableDataflowControl && (
        <div className="absolute -right-1 -bottom-1">
          <Badge variant="outline" className="h-4 bg-white px-1 text-xs" title="제어관리 활성화">
            🔧
          </Badge>
        </div>
      )}
    </div>
  );
};

export default OptimizedButtonComponent;
