/**
 * @module components/RangeFacet
 */
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import cx from 'classnames';
import MapArray from 'components/common/MapArray';
import Button from 'components/Button';
import Text from 'components/Text';
import Grid from 'components/common/Grid';
import Checkbox from 'components/common/Checkbox';
import content from 'components/RangeFacet/content';
import useTranslations from 'helpers/useTranslations';
import { useConfig } from '@findify/react-connect';
import styles from 'components/RangeFacet/styles.css';
import Loadable from 'react-loadable';
import chunks from 'helpers/chunks';
const Slider = Loadable({
    loader: chunks.components.rangeSlider,
    loading: () => null,
});
const PriceInput = ({ theme, currency, min, max, onBlur, resetOn, precision, reference, label }) => {
    const handleWrapperClick = useCallback(() => {
        if (reference.current)
            reference.current?.focus();
    }, [reference]);
    const handleKeyPress = useCallback((e) => {
        if (e.key === 'Enter')
            onBlur(e);
    }, []);
    useEffect(() => {
        if (reference.current)
            reference.current.value = null;
    }, [resetOn]);
    const step = useMemo(() => precision
        ? `0.${Array.from({ length: precision }, (_, i) => i + 1 === precision ? '1' : '0').join('')}`
        : '1', []);
    return (<div className={theme.inputWrap} onClick={handleWrapperClick}>
      <span className={theme.currency}>{currency}</span>
      <input type="number" inputMode="numeric" pattern="[0-9]*" className={theme.input} max={max} min={min} onBlur={onBlur} onKeyPress={handleKeyPress} ref={reference} step={step} aria-label={label}/>
      <div className={theme.border}/>
    </div>);
};
export default ({ theme = styles, config: facetConfig, facet, hidden, isMobile, }) => {
    const { config } = useConfig();
    const translate = useTranslations();
    const minInput = useRef(null);
    const maxInput = useRef(null);
    const [[from, to], setState] = useState([]);
    const [selectedItems, notSelectedItems] = useMemo(() => [
        facetConfig.get('pullSelected')
            ? facet.get('values').filter((i) => i.get('selected'))
            : facet.get('values'),
        facetConfig.get('pullSelected')
            ? facet.get('values').filter((i) => !i.get('selected'))
            : facet.get('values'),
    ], [facet]);
    /** Invoked when minimum range is changed */
    const onChangeMin = useCallback((e) => {
        const _value = parseFloat(e.target.value);
        if (isNaN(_value))
            return;
        const value = Number(_value > (to || facet.get('max'))
            ? to || facet.get('max')
            : _value < facet.get('min')
                ? facet.get('min')
                : _value).toFixed(facetConfig.get('precision', 0));
        e.target.value = value;
        setState((s) => [value, s[1]]);
    }, [from, to]);
    /** Invoked when maximum range is changed */
    const onChangeMax = useCallback((e) => {
        const _value = parseFloat(e.target.value);
        if (isNaN(_value))
            return;
        const value = Number(_value < (from || facet.get('min'))
            ? from || facet.get('min')
            : _value > facet.get('max')
                ? facet.get('max')
                : _value).toFixed(facetConfig.get('precision', 0));
        e.target.value = value;
        setState((s) => [s[0], value]);
    }, [from, to]);
    const onSubmit = useCallback((e) => {
        e.preventDefault();
        if (!from && !to)
            return;
        facet.setValue({ from, to });
        setState([]);
        if (minInput.current && maxInput.current) {
            minInput.current.value = maxInput.current.value = '';
        }
    }, [from, to]);
    const onSliderChange = useCallback(([min, max]) => {
        const range = facet.get('max') - facet.get('min');
        const minValue = ((range / 100) * min || facet.get('min')).toFixed(facetConfig.get('precision', 0));
        const maxValue = ((facet.get('max') / 100) * max).toFixed(facetConfig.get('precision', 0));
        if (minInput.current && maxInput.current) {
            minInput.current.value = minValue;
            maxInput.current.value = maxValue;
        }
        setState([minValue, maxValue]);
    }, []);
    return (<div className={theme.root} id={`facet-${facet.get('name')}`} role="region" hidden={hidden}>
      <MapArray display-if={facetConfig.get('pullSelected')} array={selectedItems} factory={Checkbox} content={content} config={config} isMobile={isMobile}/>

      <MapArray array={notSelectedItems} factory={Checkbox} content={content} config={config} isMobile={isMobile}/>

      <Grid wrapperComponent="form" onSubmit={onSubmit} columns="3|fit|3|auto" className={cx(theme.range, theme.inputBlock)}>
        <PriceInput theme={theme} currency={config.getIn(['currency', 'symbol'])} max={to} min={facet.get('min')} resetOn={facet} onBlur={onChangeMin} reference={minInput} precision={facetConfig.get('precision', 0)} label="fromprice"/>

        <div className={theme.divider}>-</div>

        <PriceInput theme={theme} currency={config.getIn(['currency', 'symbol'])} min={from} max={facet.get('max')} resetOn={facet} onBlur={onChangeMax} reference={maxInput} precision={facetConfig.get('precision', 0)} label="toprice"/>
        <Button className={theme.submit} type="submit" onClick={onSubmit}>
          <Text primary uppercase>
            {translate('facets.submit')}
          </Text>
        </Button>
      </Grid>
      <Slider display-if={config.get('slider')} className={theme.slider} thumbClassName={theme.thumb} trackClassName={theme.track} defaultValue={[0, 100]} onChange={onSliderChange}/>
    </div>);
};
