text: import mustacheReplacer from './referenceData/mustacheReplacer';
  import { conditionBuilder } from './shared';
  
  const isBoolStr = (str) => {
    if (str === 'true') return true;
    if (str === 'false') return false;
  
    return str;
  };
  const isNumStr = (str) => (Number.isNaN(+str) ? str : +str);
  const comparisons = {
    eq: (a, b) => a === b,
    nq: (a, b) => a !== b,
    gt: (a, b) => isNumStr(a) > isNumStr(b),
    gte: (a, b) => isNumStr(a) >= isNumStr(b),
    lt: (a, b) => isNumStr(a) < isNumStr(b),
    lte: (a, b) => isNumStr(a) <= isNumStr(b),
    cnt: (a, b) => a?.includes(b) ?? false,
    itr: (a) => Boolean(isBoolStr(a)),
    ifl: (a) => !isBoolStr(a),
  };
  
  export default async function (conditionsArr, workflowData) {
    const result = {
      isMatch: false,
      replacedValue: {},
    };
  
    async function getConditionItemValue({ type, data }) {
      const copyData = JSON.parse(JSON.stringify(data));
  
      Object.keys(data).forEach((key) => {
        const { value, list } = mustacheReplacer(
          copyData[key],
          workflowData.refData
        );
  
        copyData[key] = value ?? '';
        Object.assign(result.replacedValue, list);
      });
  
      if (type === 'value') return copyData.value;
  
      if (type.startsWith('element')) {
        const conditionValue = await workflowData.sendMessage({
          type: 'condition-builder',
          data: {
            type,
            data: copyData,
          },
        });
  
        return conditionValue;
      }
  
      return '';
    }
    async function checkConditions(items) {
      let conditionResult = true;
      const condition = {
        value: '',
        operator: '',
      };
  
      for (const { category, data, type } of items) {
        if (!conditionResult) return conditionResult;
  
        if (category === 'compare') {
          const { needValue } = conditionBuilder.compareTypes.find(
            ({ id }) => id === type
          );
  
          if (!needValue) {
            conditionResult = comparisons[type](condition.value);
  
            return conditionResult;
          }
  
          condition.operator = type;
        } else if (category === 'value') {
          const conditionValue = await getConditionItemValue({ data, type });
          const { compareable } = conditionBuilder.valueTypes.find(
            ({ id }) => id === type
          );
  
          if (!compareable) {
            conditionResult = conditionValue;
          } else if (condition.operator) {
            conditionResult = comparisons[condition.operator](
              condition.value,
              conditionValue
            );
  
            condition.operator = '';
          }
  
          condition.value = conditionValue;
        }
      }
  
      return conditionResult;
    }
  
    for (const { conditions } of conditionsArr) {
      if (result.isMatch) return result;
  
      let isAllMatch = false;
  
      for (const { items } of conditions) {
        isAllMatch = await checkConditions(items, workflowData);
  
        if (!isAllMatch) break;
      }
  
      result.isMatch = isAllMatch;
    }
  
    return result;
  }
  