utils_utils.js

import {ErrorCode} from '../../exception/exceptionDesc.js';
import {Component_A} from '../basic/as-component.js';

/**
 * Formats the options string into an array of option objects.
 * @param {Any} optionItemsString - The option items to be formatted.For example, `text1|value1`
 * @returns {object[]} The formatted options array.
 */
export function formatOptionsString(optionItemsString) {
  if (typeof optionItemsString !== 'string' || optionItemsString.trim() === '') return [];

  var items = optionItemsString.split(';');
  return items.map((item) => {
    // Handle empty items
    if (item.trim() === '') return {text: '', value: ''};
    var kv = item.split('|');
    if (kv.length != 2) {
      Logger.e('parseOptionItemString', ErrorCode.FailedToFormatOptions, 'Failed to format options', item);
      throw new Error(ErrorCode.FailedToFormatOptions, {
        cause: `Failed to format options. Invalid item: ${item}`,
      });
    }
    return {
      text: kv[0] ? Component_A.tParse(kv[0].replace(/^\n+/, '')) : '',
      value: kv[1],
    };
  });
}

/**
 * Formats the options string into an array of option objects.
 * @param {Any} optionItemsString - The option items to be formatted.For example, `text1|value1`
 * @param {Func} errorCallback - The error handling function.
 * @param {String} componentName - The name of the target component.
 * @returns {object[]} The formatted options array.
 */
export function generateOptionsString(optionItemsArray, errorCallback, componentName) {
  if (!Array.isArray(optionItemsArray) || optionItemsArray.length === 0) return '';

  try {
    return optionItemsArray
      .map((item) => {
        return `${item.text}|${item.value}`;
      })
      .join(';');
  } catch (error) {
    if (typeof errorCallback === 'function') {
      errorCallback(error, componentName || 'Generate Options String');
    } else {
      Logger.e(
        'generateOptionsString',
        ErrorCode.FailedToFormatOptions,
        `The component name is ${componentName}`,
        error,
      );
      throw ErrorCode.FailedToFormatOptions;
    }
  }
}

/**
 * dynamicOptions function to get options based on the configuration.
 * If the mode is 'fixed', it formats the provided optionItems string.
 * Otherwise, it retrieves the options from a variable path.
 * @param {Any} optionItems - The option items to be formatted.For example, `text1|value1`
 * @param {object} optionsConfig - The configuration for dynamic options.
 * @param {Func} successCallback - The success handling function.
 * @returns {object[]} The formatted options array.
 */
export async function initDynamicOptions(optionsConfig, successCallback) {
  if (!optionsConfig || (optionsConfig && optionsConfig.mode == 'fixed')) {
    // successCallback(optionItems);
  } else {
    const variablePath = optionsConfig.variablePath;
    const type = optionsConfig.type;
    switch (optionsConfig.mode) {
      case 'sync':
        // Handle sync mode
        switch (type) {
          default:
            API.VARIABLEMONITOR.monitorVariable(
              {
                type: type,
                task: variablePath[0],
                module: variablePath[1],
                name: variablePath[2],
              },
              (vvv) => {
                var formated = vvv.replace(/true/gi, 'true').replace(/false/gi, 'false');
                let arr = JSON.parse(formated) || [];
                if (type != 'string') {
                  arr = arr.map((item) => JSON.stringify(item));
                }
                successCallback(
                  arr.map((item) => {
                    return {
                      text: item,
                      value: item,
                    };
                  }),
                );
              },
            );
            break;
        }
        break;
      case 'initialize':
        // Handle initialize mode
        switch (type) {
          default:
            // var ret = await API.RAPID.getVariableValue(variablePath[1], variablePath[2], variablePath[0]);
            var variableData = await RWS.Rapid.getData(variablePath[0], variablePath[1], variablePath[2]);
            var ret = await variableData.getRawValue();
            ret = ret.replace(/true/gi, 'true').replace(/false/gi, 'false');
            var arr = JSON.parse(ret) || [];
            if (type != 'string') {
              arr = arr.map((item) => JSON.stringify(item));
            }
            var formated = arr.map((item, index) => {
              return {
                text: item,
                value: item,
              };
            });
            successCallback(formated);
        }
        break;
      default:
        // Handle unknown mode
        break;
    }
  }
}

/**
 * Counts the number of decimal places in a given number.
 * @param {number} num - The number to be evaluated. For example, `123.456`.
 * @returns {number} The number of decimal places. Returns 0 if there are no decimal places.
 *
 * @example
 * // Returns 3
 * getDecimalPlaces(123.456);
 *
 * @example
 * // Returns 6
 * getDecimalPlaces(123.456789);
 *
 * @example
 * // Returns 0
 * getDecimalPlaces(123);
 */
export function getDecimalPlaces(n) {
  if (typeof n !== 'number') return 0;
  const numStr = n.toString();

  const decimalPointIndex = numStr.indexOf('.');

  if (decimalPointIndex === -1) {
    return 0;
  }

  return numStr.length - decimalPointIndex - 1;
}

/**
 * Checks whether the current browser version sipports a CSS feature.
 * @returns {boolean} True if the browser supports the feature, otherwise returns false.
 */
export function checkCssSupport(key, value) {
  if (typeof CSS !== 'undefined' && CSS.supports) {
    return CSS.supports(key, value);
  }
  return false;
}