/**
 * 🔥 성능 최적화: 버튼 데이터플로우 서비스
 *
 * 즉시 응답 + 백그라운드 실행 패턴으로
 * 사용자에게 최고의 성능을 제공합니다.
 */

import {
  ButtonActionType,
  ExtendedButtonTypeConfig,
  ButtonDataflowConfig,
  DataflowExecutionResult,
  DataflowCondition,
} from "@/types";
import { dataflowConfigCache } from "./dataflowCache";
import { dataflowJobQueue, JobPriority } from "./dataflowJobQueue";
import { apiClient } from "@/lib/api/client";

export interface OptimizedExecutionResult {
  jobId: string;
  immediateResult?: any;
  isBackground?: boolean;
  timing?: "before" | "after" | "replace";
}

export interface QuickValidationResult {
  success: boolean;
  message?: string;
  canExecuteImmediately: boolean;
  actions?: any[]; // 조건 만족 시 실행할 액션들
}

/**
 * 제어 데이터 소스 타입
 */
export type ControlDataSource = "form" | "table-selection" | "both";

/**
 * 확장된 제어 컨텍스트
 */
export interface ExtendedControlContext {
  // 기존 폼 데이터
  formData: Record<string, any>;

  // 테이블 선택 데이터
  selectedRows?: any[];
  selectedRowsData?: any[];

  // 제어 데이터 소스 타입
  controlDataSource: ControlDataSource;

  // 기타 컨텍스트
  buttonId: string;
  componentData?: any;
  timestamp: string;
  clickCount?: number;
}

/**
 * 🔥 최적화된 버튼 데이터플로우 서비스
 *
 * 핵심 원칙:
 * 1. 즉시 응답 우선 (0-100ms)
 * 2. 복잡한 작업은 백그라운드
 * 3. 캐시 활용으로 속도 향상
 * 4. 스마트한 타이밍 제어
 */
export class OptimizedButtonDataflowService {
  /**
   * 🔥 메인 엔트리포인트: 즉시 응답 + 백그라운드 실행
   */
  static async executeButtonWithDataflow(
    buttonId: string,
    actionType: ButtonActionType,
    buttonConfig: ExtendedExtendedButtonTypeConfig,
    contextData: Record<string, any>,
    companyCode: string,
  ): Promise<OptimizedExecutionResult> {
    const { enableDataflowControl, dataflowTiming } = buttonConfig;

    // 🔥 제어관리가 비활성화된 경우: 즉시 실행
    if (!enableDataflowControl) {
      const result = await this.executeOriginalAction(actionType, buttonConfig, contextData);
      return {
        jobId: "immediate",
        immediateResult: result,
        timing: undefined,
      };
    }

    // 🔥 타이밍별 즉시 응답 전략
    switch (dataflowTiming) {
      case "before":
        return await this.executeBeforeTiming(buttonId, actionType, buttonConfig, contextData, companyCode);

      case "after":
        return await this.executeAfterTiming(buttonId, actionType, buttonConfig, contextData, companyCode);

      case "replace":
        return await this.executeReplaceTiming(buttonId, actionType, buttonConfig, contextData, companyCode);

      default:
        // 기본값은 after
        return await this.executeAfterTiming(buttonId, actionType, buttonConfig, contextData, companyCode);
    }
  }

  /**
   * 🔥 After 타이밍: 즉시 기존 액션 + 백그라운드 제어관리
   *
   * 가장 일반적이고 안전한 패턴
   * - 기존 액션 즉시 실행 (50-200ms)
   * - 제어관리는 백그라운드에서 처리
   */
  private static async executeAfterTiming(
    buttonId: string,
    actionType: ButtonActionType,
    buttonConfig: ExtendedButtonTypeConfig,
    contextData: Record<string, any>,
    companyCode: string,
  ): Promise<OptimizedExecutionResult> {
    // 🔥 Step 1: 기존 액션 즉시 실행
    const immediateResult = await this.executeOriginalAction(actionType, buttonConfig, contextData);

    // 🔥 Step 2: 제어관리는 백그라운드에서 실행
    const enrichedContext = {
      ...contextData,
      originalActionResult: immediateResult,
    };

    const jobId = dataflowJobQueue.enqueue(
      buttonId,
      actionType,
      buttonConfig,
      enrichedContext,
      companyCode,
      "normal", // 일반 우선순위
    );

    return {
      jobId,
      immediateResult,
      isBackground: true,
      timing: "after",
    };
  }

  /**
   * 🔥 Before 타이밍: 빠른 검증 + 기존 액션
   *
   * 검증 목적으로 주로 사용
   * - 간단한 검증: 즉시 처리
   * - 복잡한 검증: 백그라운드 처리
   */
  private static async executeBeforeTiming(
    buttonId: string,
    actionType: ButtonActionType,
    buttonConfig: ExtendedButtonTypeConfig,
    contextData: Record<string, any>,
    companyCode: string,
  ): Promise<OptimizedExecutionResult> {
    // 🔥 설정 캐시에서 빠르게 로드
    const dataflowConfig = buttonConfig.dataflowConfig || (await dataflowConfigCache.getConfig(buttonId));

    if (!dataflowConfig) {
      // 설정이 없으면 기존 액션만 실행
      const result = await this.executeOriginalAction(actionType, buttonConfig, contextData);
      return { jobId: "immediate", immediateResult: result, timing: "before" };
    }

    // 간단한 검증인지 판단
    const isSimpleValidation = await this.isSimpleValidationOnly(dataflowConfig);

    if (isSimpleValidation) {
      // 🔥 간단한 검증: 메모리에서 즉시 처리 (1-10ms)
      const validationResult = await this.executeQuickValidation(dataflowConfig, contextData);

      if (!validationResult.success) {
        return {
          jobId: "validation_failed",
          immediateResult: {
            success: false,
            message: validationResult.message,
          },
          timing: "before",
        };
      }

      // 검증 통과 시 기존 액션 실행
      const actionResult = await this.executeOriginalAction(actionType, buttonConfig, contextData);

      return {
        jobId: "immediate",
        immediateResult: actionResult,
        timing: "before",
      };
    } else {
      // 🔥 복잡한 검증: 사용자에게 알림 후 백그라운드 처리
      const jobId = dataflowJobQueue.enqueue(
        buttonId,
        actionType,
        buttonConfig,
        contextData,
        companyCode,
        "high", // 높은 우선순위 (사용자 대기 중)
      );

      return {
        jobId,
        immediateResult: {
          success: true,
          message: "검증 중입니다. 잠시만 기다려주세요.",
          processing: true,
        },
        isBackground: true,
        timing: "before",
      };
    }
  }

  /**
   * 🔥 Replace 타이밍: 제어관리로 완전 대체
   *
   * 기존 액션 대신 제어관리만 실행
   * - 간단한 제어: 즉시 실행
   * - 복잡한 제어: 백그라운드 실행
   */
  private static async executeReplaceTiming(
    buttonId: string,
    actionType: ButtonActionType,
    buttonConfig: ExtendedButtonTypeConfig,
    contextData: Record<string, any>,
    companyCode: string,
  ): Promise<OptimizedExecutionResult> {
    const dataflowConfig = buttonConfig.dataflowConfig || (await dataflowConfigCache.getConfig(buttonId));

    if (!dataflowConfig) {
      throw new Error("Replace 모드이지만 제어관리 설정이 없습니다.");
    }

    // 간단한 제어관리인지 판단
    const isSimpleControl = this.isSimpleControl(dataflowConfig);

    if (isSimpleControl) {
      // 🔥 간단한 제어: 즉시 실행
      try {
        const result = await this.executeSimpleDataflow(dataflowConfig, contextData, companyCode);

        return {
          jobId: "immediate",
          immediateResult: result,
          timing: "replace",
        };
      } catch (error) {
        return {
          jobId: "immediate",
          immediateResult: {
            success: false,
            message: "제어관리 실행 중 오류가 발생했습니다.",
            error: error.message,
          },
          timing: "replace",
        };
      }
    } else {
      // 🔥 복잡한 제어: 백그라운드 실행
      const jobId = dataflowJobQueue.enqueue(buttonId, actionType, buttonConfig, contextData, companyCode, "normal");

      return {
        jobId,
        immediateResult: {
          success: true,
          message: "사용자 정의 작업을 처리 중입니다...",
          processing: true,
        },
        isBackground: true,
        timing: "replace",
      };
    }
  }

  /**
   * 🔥 간단한 조건인지 판단
   *
   * 메모리에서 즉시 처리 가능한 조건:
   * - 조건 5개 이하
   * - 단순 비교 연산자만 사용
   * - 그룹핑 없음
   */
  private static async isSimpleValidationOnly(config: ButtonDataflowConfig): Promise<boolean> {
    if (config.controlMode !== "advanced") {
      return true; // 간편 모드는 일단 간단하다고 가정
    }

    const conditions = config.directControl?.conditions || [];

    return (
      conditions.length <= 5 &&
      conditions.every((c) => c.type === "condition" && ["=", "!=", ">", "<", ">=", "<="].includes(c.operator || ""))
    );
  }

  /**
   * 🔥 간단한 제어관리인지 판단
   */
  private static isSimpleControl(config: ButtonDataflowConfig): boolean {
    if (config.controlMode === "simple") {
      return true; // 간편 모드는 대부분 간단
    }

    const actions = config.directControl?.actions || [];
    const conditions = config.directControl?.conditions || [];

    // 액션 3개 이하, 조건 5개 이하면 간단한 제어로 판단
    return actions.length <= 3 && conditions.length <= 5;
  }

  /**
   * 🔥 빠른 검증 (메모리에서 즉시 처리) - 확장된 버전
   */
  private static async executeQuickValidation(
    config: ButtonDataflowConfig,
    data: Record<string, any>,
  ): Promise<QuickValidationResult> {
    if (config.controlMode === "simple") {
      // 간편 모드는 일단 통과 (실제 검증은 백그라운드에서)
      return {
        success: true,
        canExecuteImmediately: true,
      };
    }

    const conditions = config.directControl?.conditions || [];

    for (const condition of conditions) {
      if (condition.type === "condition") {
        const fieldValue = data[condition.field!];
        const isValid = this.evaluateSimpleCondition(fieldValue, condition.operator!, condition.value);

        if (!isValid) {
          return {
            success: false,
            message: `조건 불만족: ${condition.field} ${condition.operator} ${condition.value}`,
            canExecuteImmediately: true,
          };
        }
      }
    }

    return {
      success: true,
      canExecuteImmediately: true,
    };
  }

  /**
   * 🔥 확장된 조건 검증 (폼 + 테이블 선택 데이터)
   */
  static async executeExtendedValidation(
    config: ButtonDataflowConfig,
    context: ExtendedControlContext,
  ): Promise<QuickValidationResult> {
    console.log("🔍 executeExtendedValidation 시작:", {
      controlMode: config.controlMode,
      controlDataSource: context.controlDataSource,
      selectedRowsData: context.selectedRowsData,
      formData: context.formData,
      directControlConditions: config.directControl?.conditions,
      selectedDiagramId: config.selectedDiagramId,
      selectedRelationshipId: config.selectedRelationshipId,
      fullConfig: config,
    });

    // 🔥 simple 모드에서도 조건 검증을 수행해야 함
    // if (config.controlMode === "simple") {
    //   return {
    //     success: true,
    //     canExecuteImmediately: true,
    //   };
    // }

    let conditions = config.directControl?.conditions || [];

    // 🔥 관계도 방식인 경우 실제 API에서 조건 가져오기
    if (conditions.length === 0 && config.selectedDiagramId && config.selectedRelationshipId) {
      console.log("🔍 관계도 방식에서 실제 조건 로딩:", {
        selectedDiagramId: config.selectedDiagramId,
        selectedRelationshipId: config.selectedRelationshipId,
      });

      try {
        // 관계도에서 실제 조건을 가져오는 API 호출
        const response = await apiClient.get(
          `/test-button-dataflow/diagrams/${config.selectedDiagramId}/relationships/${config.selectedRelationshipId}/preview`,
        );

        if (response.data.success && response.data.data) {
          const previewData = response.data.data;

          // control.conditions에서 실제 조건 추출
          if (previewData.control && previewData.control.conditions) {
            conditions = previewData.control.conditions.filter((cond: any) => cond.type === "condition");
            console.log("✅ 관계도에서 control 조건 로딩 성공:", {
              totalConditions: previewData.control.conditions.length,
              filteredConditions: conditions.length,
              conditions,
            });
          } else {
            console.warn("⚠️ 관계도 control에 조건이 설정되지 않았습니다:", previewData);
          }

          // 🔧 control.conditions가 비어있으면 plan.actions[].conditions에서 조건 추출
          if (conditions.length === 0 && previewData.plan && previewData.plan.actions) {
            console.log("🔍 control 조건이 없어서 액션별 조건 확인:", previewData.plan.actions);

            previewData.plan.actions.forEach((action: any, index: number) => {
              if (action.conditions && Array.isArray(action.conditions) && action.conditions.length > 0) {
                conditions.push(...action.conditions);
                console.log(
                  `✅ 액션 ${index + 1}(${action.name})에서 조건 ${action.conditions.length}개 로딩:`,
                  action.conditions,
                );
              }
            });

            if (conditions.length > 0) {
              console.log("✅ 총 액션별 조건 로딩 성공:", {
                totalConditions: conditions.length,
                conditions: conditions,
              });
            }
          }

          // plan.actions에서 실제 액션도 저장 (조건 만족 시 실행용)
          if (previewData.plan && previewData.plan.actions) {
            // config에 액션 정보 임시 저장
            (config as any)._relationshipActions = previewData.plan.actions;
            console.log("✅ 관계도에서 실제 액션 로딩 성공:", {
              totalActions: previewData.plan.actions.length,
              actions: previewData.plan.actions,
            });
          } else {
            console.warn("⚠️ 관계도에 액션이 설정되지 않았습니다:", {
              hasPlan: !!previewData.plan,
              planActions: previewData.plan?.actions,
              fullPreviewData: previewData,
            });
          }
        } else {
          console.warn("⚠️ 관계도 API 응답이 올바르지 않습니다:", response.data);
        }
      } catch (error) {
        console.error("❌ 관계도에서 조건 로딩 실패:", error);

        // API 실패 시 사용자에게 명확한 안내
        return {
          success: false,
          message: "관계도에서 조건을 불러올 수 없습니다. 관계도 설정을 확인해주세요.",
          canExecuteImmediately: true,
        };
      }
    }

    // 🔥 여전히 조건이 없으면 경고
    if (conditions.length === 0) {
      console.warn("⚠️ 제어 조건이 설정되지 않았습니다.");
      return {
        success: false,
        message: "제어 조건이 설정되지 않았습니다. 관계도에서 관계를 선택하거나 직접 조건을 추가해주세요.",
        canExecuteImmediately: true,
      };
    }

    console.log("🔍 조건 검증 시작:", conditions);

    for (const condition of conditions) {
      if (condition.type === "condition") {
        let dataToCheck: Record<string, any> = {};

        // 제어 데이터 소스에 따라 검증할 데이터 결정
        console.log("🔍 제어 데이터 소스 확인:", {
          controlDataSource: context.controlDataSource,
          hasFormData: Object.keys(context.formData).length > 0,
          hasSelectedRowsData: context.selectedRowsData && context.selectedRowsData.length > 0,
          selectedRowsData: context.selectedRowsData,
        });

        switch (context.controlDataSource) {
          case "form":
            dataToCheck = context.formData;
            console.log("📝 폼 데이터 사용:", dataToCheck);
            break;

          case "table-selection":
            // 선택된 첫 번째 행의 데이터 사용 (다중 선택 시)
            if (context.selectedRowsData && context.selectedRowsData.length > 0) {
              dataToCheck = context.selectedRowsData[0];
              console.log("📋 테이블 선택 데이터 사용:", dataToCheck);
            } else {
              console.warn("⚠️ 테이블에서 항목이 선택되지 않음");
              return {
                success: false,
                message: "테이블에서 항목을 선택해주세요.",
                canExecuteImmediately: true,
              };
            }
            break;

          case "both":
            // 폼 데이터와 선택된 데이터 모두 병합
            dataToCheck = {
              ...context.formData,
              ...(context.selectedRowsData?.[0] || {}),
            };
            console.log("🔄 폼 + 테이블 데이터 병합 사용:", dataToCheck);
            break;

          default:
            // 기본값이 없는 경우 자동 판단
            if (context.selectedRowsData && context.selectedRowsData.length > 0) {
              dataToCheck = context.selectedRowsData[0];
              console.log("🔄 자동 판단: 테이블 선택 데이터 사용:", dataToCheck);
            } else {
              dataToCheck = context.formData;
              console.log("🔄 자동 판단: 폼 데이터 사용:", dataToCheck);
            }
            break;
        }

        const fieldValue = dataToCheck[condition.field!];
        const isValid = this.evaluateSimpleCondition(fieldValue, condition.operator!, condition.value);

        console.log("🔍 조건 검증 결과:", {
          field: condition.field,
          operator: condition.operator,
          expectedValue: condition.value,
          actualValue: fieldValue,
          isValid,
          dataToCheck,
        });

        if (!isValid) {
          const sourceLabel = getDataSourceLabel(context.controlDataSource);
          const actualValueMsg = fieldValue !== undefined ? ` (실제값: ${fieldValue})` : " (값 없음)";

          return {
            success: false,
            message: `${sourceLabel} 조건 불만족: ${condition.field} ${condition.operator} ${condition.value}${actualValueMsg}`,
            canExecuteImmediately: true,
          };
        }
      }
    }

    // 🔥 모든 조건을 만족했으므로 액션 정보도 함께 반환
    const relationshipActions = (config as any)._relationshipActions || [];

    return {
      success: true,
      canExecuteImmediately: true,
      actions: relationshipActions,
    };
  }

  /**
   * 🔥 단순 조건 평가 (메모리에서 즉시)
   */
  private static evaluateSimpleCondition(fieldValue: any, operator: string, conditionValue: any): boolean {
    switch (operator) {
      case "=":
        return fieldValue === conditionValue;
      case "!=":
        return fieldValue !== conditionValue;
      case ">":
        return Number(fieldValue) > Number(conditionValue);
      case "<":
        return Number(fieldValue) < Number(conditionValue);
      case ">=":
        return Number(fieldValue) >= Number(conditionValue);
      case "<=":
        return Number(fieldValue) <= Number(conditionValue);
      case "LIKE":
        return String(fieldValue).toLowerCase().includes(String(conditionValue).toLowerCase());
      default:
        return true;
    }
  }

  /**
   * 🔥 간단한 데이터플로우 즉시 실행
   */
  private static async executeSimpleDataflow(
    config: ButtonDataflowConfig,
    contextData: Record<string, any>,
    companyCode: string,
  ): Promise<DataflowExecutionResult> {
    try {
      const response = await apiClient.post("/api/button-dataflow/execute-simple", {
        config,
        contextData,
        companyCode,
      });

      if (response.data.success) {
        return response.data.data as DataflowExecutionResult;
      } else {
        throw new Error(response.data.message || "Simple dataflow execution failed");
      }
    } catch (error) {
      console.error("Simple dataflow execution failed:", error);
      throw error;
    }
  }

  /**
   * 🔥 기존 액션 실행 (최적화)
   */
  private static async executeOriginalAction(
    actionType: ButtonActionType,
    buttonConfig: ExtendedButtonTypeConfig,
    contextData: Record<string, any>,
  ): Promise<any> {
    const startTime = performance.now();

    try {
      // 액션별 분기 처리
      switch (actionType) {
        case "save":
          return await this.executeSaveAction(buttonConfig, contextData);
        case "delete":
          return await this.executeDeleteAction(buttonConfig, contextData);
        case "search":
          return await this.executeSearchAction(buttonConfig, contextData);
        case "edit":
          return await this.executeEditAction(buttonConfig, contextData);
        case "add":
          return await this.executeAddAction(buttonConfig, contextData);
        case "reset":
          return await this.executeResetAction(buttonConfig, contextData);
        case "submit":
          return await this.executeSubmitAction(buttonConfig, contextData);
        case "close":
          return await this.executeCloseAction(buttonConfig, contextData);
        case "popup":
          return await this.executePopupAction(buttonConfig, contextData);
        case "navigate":
          return await this.executeNavigateAction(buttonConfig, contextData);
        default:
          return {
            success: true,
            message: `${actionType} 액션이 실행되었습니다.`,
          };
      }
    } catch (error) {
      console.error(`Action execution failed: ${actionType}`, error);
      return {
        success: false,
        message: `${actionType} 액션 실행 중 오류가 발생했습니다.`,
        error: error.message,
      };
    } finally {
      const executionTime = performance.now() - startTime;
      if (executionTime > 200) {
        console.warn(`🐌 Slow action: ${actionType} took ${executionTime.toFixed(2)}ms`);
      } else {
        console.log(`⚡ ${actionType} completed in ${executionTime.toFixed(2)}ms`);
      }
    }
  }

  /**
   * 개별 액션 구현들
   */
  private static async executeSaveAction(config: ExtendedButtonTypeConfig, data: Record<string, any>) {
    // TODO: 실제 저장 로직 구현
    return { success: true, message: "저장되었습니다." };
  }

  private static async executeDeleteAction(config: ExtendedButtonTypeConfig, data: Record<string, any>) {
    // TODO: 실제 삭제 로직 구현
    return { success: true, message: "삭제되었습니다." };
  }

  private static async executeSearchAction(config: ExtendedButtonTypeConfig, data: Record<string, any>) {
    // TODO: 실제 검색 로직 구현
    return { success: true, message: "검색되었습니다.", data: [] };
  }

  private static async executeEditAction(config: ExtendedButtonTypeConfig, data: Record<string, any>) {
    return { success: true, message: "수정 모드로 전환되었습니다." };
  }

  private static async executeAddAction(config: ExtendedButtonTypeConfig, data: Record<string, any>) {
    return { success: true, message: "추가 모드로 전환되었습니다." };
  }

  private static async executeResetAction(config: ExtendedButtonTypeConfig, data: Record<string, any>) {
    return { success: true, message: "초기화되었습니다." };
  }

  private static async executeSubmitAction(config: ExtendedButtonTypeConfig, data: Record<string, any>) {
    return { success: true, message: "제출되었습니다." };
  }

  private static async executeCloseAction(config: ExtendedButtonTypeConfig, data: Record<string, any>) {
    return { success: true, message: "닫기 액션이 실행되었습니다." };
  }

  private static async executePopupAction(config: ExtendedButtonTypeConfig, data: Record<string, any>) {
    return {
      success: true,
      message: "팝업이 열렸습니다.",
      popupUrl: config.navigateUrl,
      popupScreenId: config.popupScreenId,
    };
  }

  private static async executeNavigateAction(config: ExtendedButtonTypeConfig, data: Record<string, any>) {
    return {
      success: true,
      message: "페이지 이동이 실행되었습니다.",
      navigateUrl: config.navigateUrl,
      navigateTarget: config.navigateTarget,
    };
  }

  /**
   * 🔥 작업 상태 조회
   */
  static getJobStatus(jobId: string): { status: string; result?: any; progress?: number } {
    try {
      return dataflowJobQueue.getJobStatus(jobId);
    } catch (error) {
      return { status: "not_found" };
    }
  }

  /**
   * 🔥 성능 메트릭 조회
   */
  static getPerformanceMetrics(): {
    cache: any;
    queue: any;
  } {
    return {
      cache: dataflowConfigCache.getMetrics(),
      queue: dataflowJobQueue.getMetrics(),
    };
  }
}

/**
 * 데이터 소스 타입에 따른 한글 레이블 반환
 */
function getDataSourceLabel(dataSource: string | undefined): string {
  switch (dataSource) {
    case "form":
      return "폼";
    case "table-selection":
      return "테이블 선택 항목";
    case "table-all":
      return "테이블 전체";
    case "flow-selection":
      return "플로우 선택 항목";
    case "flow-step-all":
      return "플로우 스텝 전체";
    case "both":
      return "폼 + 테이블 선택";
    case "all-sources":
      return "모든 소스";
    default:
      return "데이터";
  }
}

// 🔥 전역 접근을 위한 싱글톤 서비스
export const optimizedButtonDataflowService = OptimizedButtonDataflowService;
