"use strict";

exports.__esModule = true;
exports.useNumberRangeFilter = useNumberRangeFilter;
var _react = require("react");
var _react2 = require("@wix/bex-core/react");
var _ToolbarCollectionContext = require("../ToolbarCollectionContext");
function getValidateAndFormatNumber({
  decimal,
  percision,
  min,
  max,
  translate
}) {
  const validateAndFormatNumber = value => {
    if (!value && value !== 0) {
      return {
        value: null,
        error: null
      };
    }
    let error = null;
    const num = decimal ? parseFloat(value.toString()) : value;
    if (isNaN(num)) {
      return {
        value: null,
        error
      };
    }
    if (min !== undefined && num < min) {
      error = translate('cairo.filtersPanel.numRange.minRange.consumer.error', {
        minAmount: min
      });
      return {
        value: min,
        error
      };
    }
    if (max !== undefined && num > max) {
      error = translate('cairo.filtersPanel.numRange.maxRange.consumer.error', {
        maxAmount: max
      });
      return {
        value: max,
        error
      };
    }
    return decimal ? {
      value: Number(num.toFixed(percision)),
      error
    } : {
      value: num,
      error
    };
  };
  return {
    validateAndFormatNumber
  };
}
function useInputState(initialValue) {
  const [value, setValue] = (0, _react.useState)(initialValue ?? null);
  const [error, setError] = (0, _react.useState)(null);
  return {
    value,
    setValue,
    error,
    setError
  };
}
function useDebounce(callback, delay) {
  const container = (0, _react2.useWixPatternsContainer)();
  const debouncedCallback = (0, _react.useCallback)(container.lodash.debounce(callback, delay), [callback, delay]);
  return debouncedCallback;
}
function useNumberRangeFilter({
  filter,
  decimal = false,
  min,
  max
}) {
  const {
    translate: t
  } = (0, _react2.useWixPatternsContainer)();
  const percision = decimal ? 2 : 0;
  const {
    collection
  } = (0, _react.useContext)(_ToolbarCollectionContext.ToolbarCollectionContext) ?? {};
  const {
    value: fromValue,
    setValue: setFromValue,
    error: fromError,
    setError: setFromError
  } = useInputState(filter.value.from);
  const {
    value: toValue,
    setValue: setToValue,
    error: toError,
    setError: setToError
  } = useInputState(filter.value.to);
  const step = decimal ? 0.1 : 1;
  const handleInputChange = ({
    from,
    to,
    isFrom = true
  }) => {
    if (isFrom) {
      setFromValue(from ?? null);
    } else {
      setToValue(to ?? null);
    }
  };
  const updateFilterValue = ({
    from,
    to
  }) => {
    const {
      validateAndFormatNumber
    } = getValidateAndFormatNumber({
      decimal,
      percision,
      min,
      max,
      translate: t
    });
    const {
      value: validatedFrom,
      error: fromError
    } = validateAndFormatNumber(from);
    const {
      value: validatedTo,
      error: toError
    } = validateAndFormatNumber(to);
    setFromError(null);
    setToError(null);
    if (fromError) {
      setFromError(fromError);
      return;
    }
    if (toError) {
      setToError(toError);
      return;
    }
    if (validatedFrom !== null && validatedTo !== null && validatedFrom > validatedTo) {
      var _filter$value;
      // Only set error for the most recently changed value
      if (fromValue !== ((_filter$value = filter.value) == null ? void 0 : _filter$value.from)) {
        setFromError(t('cairo.filtersPanel.numRange.minRange.error'));
      } else {
        setToError(t('cairo.filtersPanel.numRange.maxRange.error'));
      }
      return;
    }
    if (validatedFrom !== fromValue) {
      setFromValue(validatedFrom);
    }
    if (validatedTo !== toValue) {
      setToValue(validatedTo);
    }
    filter.changeValue({
      from: validatedFrom,
      to: validatedTo
    }, {
      emitEvents: ['beforeRefresh', 'refresh'],
      clickedValueKey: filter.itemKey({
        from: validatedFrom,
        to: validatedTo
      })
    });
  };
  const debouncedUpdateFilters = useDebounce(updateFilterValue, 500);
  (0, _react.useEffect)(() => {
    const from = typeof fromValue === 'number' ? parseFloat(fromValue.toFixed(percision)) : null;
    const to = typeof toValue === 'number' ? parseFloat(toValue.toFixed(percision)) : null;
    debouncedUpdateFilters({
      from,
      to
    });
    return () => {
      debouncedUpdateFilters.cancel();
    };
  }, [fromValue, toValue]);
  const onBeforeClearFilters = (0, _react.useCallback)(() => {
    setFromValue(null);
    setToValue(null);
  }, [setFromValue, setToValue]);
  (0, _react.useEffect)(() => {
    if (filter.value.from === null && filter.value.to === null) {
      onBeforeClearFilters();
    }
  }, [filter.value.from, filter.value.to, onBeforeClearFilters]);
  (0, _react.useEffect)(() => {
    if (!collection) {
      return;
    }
    // This is needed because we manage the filter value manually in order to have debounced filter updates
    collection.emitter.on('beforeClearFilters', onBeforeClearFilters);
    return () => {
      collection.emitter.off('beforeClearFilters', onBeforeClearFilters);
    };
  }, [collection == null ? void 0 : collection.emitter, onBeforeClearFilters]);
  const commonInputProps = {
    step,
    min,
    max
  };
  return {
    fromValue,
    toValue,
    handleInputChange,
    placeholder: {
      min: t('cairo.filtersPanel.numRange.minRange-from.placeholder'),
      max: t('cairo.filtersPanel.numRange.maxRange-to.placeholder')
    },
    commonInputProps,
    fromError,
    toError,
    t
  };
}
//# sourceMappingURL=useNumberRangeFilter.js.map