/**
 * 조건부 표시 평가 유틸리티
 * 컴포넌트의 조건부 표시 설정을 평가하여 visible/disabled 상태를 반환합니다.
 */

import { ComponentData } from "@/types/screen";

export interface ConditionalResult {
  visible: boolean;
  disabled: boolean;
}

export interface ConditionalConfig {
  enabled: boolean;
  field: string;
  operator: "=" | "!=" | ">" | "<" | "in" | "notIn" | "isEmpty" | "isNotEmpty";
  value: string | string[];
  action: "show" | "hide" | "enable" | "disable";
}

/**
 * 조건부 표시를 평가합니다.
 * @param conditional - 컴포넌트의 조건부 설정
 * @param formData - 현재 폼 데이터
 * @param allComponents - 화면의 모든 컴포넌트 (필드 참조용)
 * @returns visible/disabled 상태
 */
export function evaluateConditional(
  conditional: ConditionalConfig | undefined,
  formData: Record<string, any>,
  allComponents: ComponentData[],
): ConditionalResult {
  // 조건부 설정이 없거나 비활성화된 경우 기본값 반환
  if (!conditional || !conditional.enabled) {
    return { visible: true, disabled: false };
  }

  const { field, operator, value, action } = conditional;

  // 필드가 설정되지 않은 경우 기본값 반환
  if (!field) {
    console.warn("[evaluateConditional] 조건 필드가 설정되지 않음");
    return { visible: true, disabled: false };
  }

  // 참조 필드의 현재 값 가져오기
  // field 값은 columnName 또는 id일 수 있으므로 양쪽으로 찾기
  const refComponent = allComponents.find((c) => {
    const columnName = (c as any)?.columnName;
    return c.id === field || columnName === field;
  });

  // formData에서 값 조회: columnName 우선, 없으면 field 값 직접 사용
  const fieldName = (refComponent as any)?.columnName || field;
  const fieldValue = formData[fieldName];

  // 조건 평가
  let conditionMet = false;
  switch (operator) {
    case "=":
      conditionMet = fieldValue === value || String(fieldValue) === String(value);
      break;
    case "!=":
      conditionMet = fieldValue !== value && String(fieldValue) !== String(value);
      break;
    case ">":
      conditionMet = Number(fieldValue) > Number(value);
      break;
    case "<":
      conditionMet = Number(fieldValue) < Number(value);
      break;
    case "in":
      if (Array.isArray(value)) {
        conditionMet = value.includes(fieldValue) || value.map(String).includes(String(fieldValue));
      }
      break;
    case "notIn":
      if (Array.isArray(value)) {
        conditionMet = !value.includes(fieldValue) && !value.map(String).includes(String(fieldValue));
      } else {
        conditionMet = true;
      }
      break;
    case "isEmpty":
      conditionMet =
        fieldValue === null ||
        fieldValue === undefined ||
        fieldValue === "" ||
        (Array.isArray(fieldValue) && fieldValue.length === 0);
      break;
    case "isNotEmpty":
      conditionMet =
        fieldValue !== null &&
        fieldValue !== undefined &&
        fieldValue !== "" &&
        !(Array.isArray(fieldValue) && fieldValue.length === 0);
      break;
    default:
      conditionMet = true;
  }

  // 액션에 따른 결과 반환
  switch (action) {
    case "show":
      // 조건이 참이면 표시, 거짓이면 숨김
      return { visible: conditionMet, disabled: false };
    case "hide":
      // 조건이 참이면 숨김, 거짓이면 표시
      return { visible: !conditionMet, disabled: false };
    case "enable":
      return { visible: true, disabled: !conditionMet };
    case "disable":
      return { visible: true, disabled: conditionMet };
    default:
      return { visible: true, disabled: false };
  }
}

