import { DataType, StringUtils } from "@sankhyalabs/core";
import { toString } from "@sankhyalabs/core/dist/dataunit/metadata/DataType";
import FilterItemType from "../filter-item-type.enum";
import { FilterOperand } from "../../../snk-personalized-filter/interfaces/index";
import { FilterNumberVariation } from "../editors/enum/filterNumberVariation";
const buildFilter = (item) => {
  switch (item.type) {
    case FilterItemType.DEFAULT_FILTER:
      return buildDefault(item);
    case FilterItemType.BINARY_SELECT:
      return buildBinary(item);
    case FilterItemType.MULTI_SELECT:
      return buildMultSelect(item);
    case FilterItemType.MULTI_LIST:
      return buildMultiList(item);
    case FilterItemType.PERIOD:
      return buildPeriod(item);
    case FilterItemType.SEARCH:
      return buildSearch(item);
    case FilterItemType.TEXT:
      return buildText(item);
    case FilterItemType.NUMBER:
      return buildNumber(item);
    case FilterItemType.PERSONALIZED:
      return buildPersonalized(item);
    case FilterItemType.CHECK_BOX_LIST:
      return buildCheckboxList(item);
    default:
      return undefined;
  }
};
export default buildFilter;
function buildDefault(item) {
  return { name: item.id, expression: item.props.expression, params: [] };
}
function buildBinary(item) {
  const { id, value, props } = item;
  const options = props.options;
  const selectedOption = options.find(opt => opt.name === value);
  return { name: id, expression: selectedOption.expression, params: [] };
}
function buildMultSelect(item) {
  const { id, value, props } = item;
  return { name: id, expression: props.expression, params: [{ name: id, dataType: DataType.TEXT, value }] };
}
function buildMultiList(item) {
  const { id, value, props } = item;
  const parsedValues = parseMultiListValues(value);
  if (parsedValues.length > 0) {
    return {
      name: id,
      expression: props.expression,
      params: [{
          name: id,
          dataType: DataType.TEXT,
          value: JSON.stringify(parsedValues)
        }]
    };
  }
}
function buildCheckboxList(item) {
  var _a;
  const { id, value, props } = item;
  const selectedOptionNames = Object.entries(value !== null && value !== void 0 ? value : {})
    .filter(([_, valueChecked]) => valueChecked === true)
    .map(([key, _]) => key);
  const selectedOptionsObject = (_a = props.options) === null || _a === void 0 ? void 0 : _a.filter(option => selectedOptionNames.includes(option.name));
  return { name: id, expression: buildCheckboxListExpression(selectedOptionsObject), params: [] };
}
function buildCheckboxListExpression(options) {
  let expression = "";
  options.forEach((option, index) => {
    var _a;
    expression += ` ${index > 0 ? ((_a = option.operand) !== null && _a !== void 0 ? _a : 'OR') : ''} ${option.expression}`;
  });
  return expression.trim();
}
function parseMultiListValues(multiListValue) {
  var _a, _b;
  const value = (_b = (_a = multiListValue === null || multiListValue === void 0 ? void 0 : multiListValue.elements) !== null && _a !== void 0 ? _a : multiListValue === null || multiListValue === void 0 ? void 0 : multiListValue.members) !== null && _b !== void 0 ? _b : multiListValue;
  return value.filter(item => item === null || item === void 0 ? void 0 : item.check).map(({ id }) => Number.isNaN(+id) ? String(id) : Number(id));
}
function buildPeriod(item) {
  const { id, value, props } = item;
  let { end, start } = value;
  if (typeof end === "string") {
    end = new Date(end);
  }
  if (typeof start === "string") {
    start = new Date(start);
  }
  const params = [];
  let expression;
  if (end && start) {
    expression = props.expression.fullfill;
    params.push({ name: `${id}.START`, dataType: DataType.DATE, value: toString(DataType.DATE, start) }, { name: `${id}.END`, dataType: DataType.DATE, value: toString(DataType.DATE, end) });
  }
  else {
    if (start) {
      expression = props.expression.onlystart;
      params.push({ name: id, dataType: DataType.DATE, value: toString(DataType.DATE, start) });
    }
    else {
      expression = props.expression.onlyend;
      params.push({ name: id, dataType: DataType.DATE, value: toString(DataType.DATE, end) });
    }
  }
  return { name: id, expression, params };
}
function buildSearch(item) {
  const { id, value, props } = item;
  const expression = props.expression;
  return { name: id, expression, params: [{ name: id, dataType: DataType.TEXT, value: toString(DataType.TEXT, value === null || value === void 0 ? void 0 : value.value) }] };
}
function buildText(item) {
  let { id, value, props } = item;
  const expression = props.expression;
  if (!StringUtils.isEmpty(props.likeAs)) {
    value = buildLikeValue(value, props.likeAs);
  }
  return { name: id, expression, params: [{ name: id, dataType: DataType.TEXT, value: toString(DataType.TEXT, value) }] };
}
function buildNumber(item) {
  const { id, value, props } = item;
  const variation = props.variation;
  if (variation === FilterNumberVariation.INTERVAL) {
    const { start, end } = value !== null && value !== void 0 ? value : { start: 0, end: 0 };
    if (!isNaN(start) && !isNaN(end)) {
      return {
        name: id,
        expression: props.intervalExpression.fullfill,
        params: [
          { name: `${id}.START`, dataType: DataType.NUMBER, value: toString(DataType.NUMBER, start) },
          { name: `${id}.END`, dataType: DataType.NUMBER, value: toString(DataType.NUMBER, end) }
        ]
      };
    }
    if (!isNaN(start)) {
      return {
        name: id,
        expression: props.intervalExpression.onlystart,
        params: [
          { name: id, dataType: DataType.NUMBER, value: toString(DataType.NUMBER, start) }
        ]
      };
    }
    if (!isNaN(end)) {
      return {
        name: id,
        expression: props.intervalExpression.onlyend,
        params: [
          { name: id, dataType: DataType.NUMBER, value: toString(DataType.NUMBER, end) }
        ]
      };
    }
  }
  const expression = props.expression;
  return { name: id, expression, params: [{ name: id, dataType: DataType.NUMBER, value: toString(DataType.NUMBER, value) }] };
}
function buildLikeValue(valueAsString, likeAs) {
  if (likeAs === "CONTANIS") {
    return `%${valueAsString}%`;
  }
  else if (likeAs === "STARTS_WITH") {
    return `${valueAsString}%`;
  }
  else if (likeAs === "ENDS_WITH") {
    return `%${valueAsString}`;
  }
  return valueAsString;
}
function buildPersonalized(item) {
  const { id, groupedItems = [] } = item;
  const activeFilters = groupedItems.filter(groupItem => !!groupItem.visible);
  const filters = activeFilters.map(item => {
    var _a;
    const expression = item.props.expression;
    const params = (((_a = item.props.personalizedFilter) === null || _a === void 0 ? void 0 : _a.parameters) || []).map((param, index) => {
      const valuesArray = Array.from(item.value || 0);
      const dataType = param.dataType;
      let paramValue = (index >= 0 && index < valuesArray.length ? valuesArray[index] : null);
      if (paramValue != undefined && typeof paramValue === "object" && "value" in paramValue) {
        paramValue = paramValue["value"];
      }
      if (paramValue == undefined && dataType === DataType.BOOLEAN) {
        paramValue = false;
      }
      return { name: param.name, dataType, value: typeof paramValue === "string" ? paramValue : toString(dataType, paramValue) };
    });
    return { expression, name: item.id, params };
  });
  const expression = filters.map(filter => `(${filter.expression})`).join(` ${FilterOperand.AND} `);
  const params = filters.flatMap(filter => filter.params);
  return { name: id, expression, params };
}
