// Copyright (c) 2021 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import React, {useCallback} from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import RangeSliderFactory from 'components/common/range-slider';
import {PanelLabel, SidePanelSection} from 'components/common/styled-components';
import {FormattedMessage} from 'localization';
import {ZOOM_LEVEL_LIMITS} from 'constants/default-settings';

const SliderWrapper = styled.div`
  position: relative;
`;

const TopRow = styled.div`
  display: flex;
  justify-content: space-between;
`;

LayerVisibilityByZoomFactory.deps = [RangeSliderFactory];

function LayerVisibilityByZoomFactory(RangeSlider) {
  const LayerVisibilityByZoom = ({
    updateLayerConfig,
    layer,
    rangeMinValue,
    rangeMaxValue,
    iconComponent,
    disabled
  }) => {
    const {config} = layer;
    const minLimit = rangeMinValue || ZOOM_LEVEL_LIMITS.min;
    const maxLimit = rangeMaxValue || ZOOM_LEVEL_LIMITS.max;

    const [zoomMin, setZoomMin] = React.useState(
      config.visibilityByZoom?.min
        ? config.visibilityByZoom?.min < minLimit
          ? minLimit
          : config.visibilityByZoom?.min
        : minLimit
    );
    const [zoomMax, setZoomMax] = React.useState(
      config.visibilityByZoom?.max
        ? config.visibilityByZoom?.max > maxLimit
          ? maxLimit
          : config.visibilityByZoom?.max
        : maxLimit
    );

    const _onChange = useCallback(
      val => {
        setZoomMin(val[0]);
        setZoomMax(val[1]);
        updateLayerConfig({visibilityByZoom: {min: val[0], max: val[1]}});
      },
      [updateLayerConfig]
    );

    const IconElement = () => iconComponent || null;

    return (
      <div>
        <SidePanelSection disabled={disabled}>
          <div className="layer-visibility__zoom">
            <TopRow>
              <PanelLabel>
                <FormattedMessage id={'layerVisibility.title'} />{' '}
                <IconElement data-test="icon-help-button" />
              </PanelLabel>
            </TopRow>
            <SliderWrapper>
              <RangeSlider
                range={[
                  rangeMinValue || ZOOM_LEVEL_LIMITS.min,
                  rangeMaxValue || ZOOM_LEVEL_LIMITS.max
                ]}
                value0={zoomMin}
                value1={zoomMax}
                min={minLimit}
                max={maxLimit}
                onChange={_onChange}
                isRanged={true}
                showTooltip
                showInput
                inputTheme="secondary"
                inputSize="tiny"
              />
            </SliderWrapper>
          </div>
        </SidePanelSection>
      </div>
    );
  };

  LayerVisibilityByZoom.propTypes = {
    updateLayerConfig: PropTypes.func.isRequired,
    rangeMinValue: PropTypes.number,
    rangeMaxValue: PropTypes.number,
    iconComponent: PropTypes.oneOfType([PropTypes.element, PropTypes.func])
  };

  return LayerVisibilityByZoom;
}

export default LayerVisibilityByZoomFactory;
