/* eslint-disable react/destructuring-assignment */
import React from "react";
import { useDefaultValue } from "../form/controlled";
import { noop } from "../_util/noop";
import { flatten } from "../_util/flatten";
import {
  RangeSliderProps,
  SingleSliderProps,
  SliderProps,
} from "./SliderProps";
import { SliderTrack } from "./SliderTrack";

export const Slider = React.forwardRef(function Slider(
  props: SliderProps,
  ref: React.Ref<HTMLDivElement>
) {
  const { min = 0, max, range } = props;

  const rebuildValidRange = range => {
    const validRange = Array.isArray(range) ? range : [min, max];

    if (typeof validRange[0] !== "number" || validRange[0] < min) {
      validRange[0] = min;
    }

    if (typeof validRange[1] !== "number" || validRange[1] > max) {
      validRange[1] = max;
    }

    return validRange as [number, number];
  };

  let validRange: SliderProps["range"];
  if (props.rangeMode === true) {
    validRange = rebuildValidRange(range);
    return <RangeSlider ref={ref} {...props} range={validRange} />;
  }

  // 单值类型支持多区间
  validRange = Array.isArray(range) && range.length > 0 ? range : [];
  if (
    Array.isArray(range) &&
    (typeof range[0] === "number" || typeof range[1] === "number")
  ) {
    validRange = [range as any];
  }

  validRange = (validRange as any)
    .filter(item => Array.isArray(item))
    .map(item => rebuildValidRange(item));

  return <SingleSlider ref={ref} {...props} range={validRange} />;
});

Slider.displayName = "Slider";

const SingleSlider = React.forwardRef(function SingleSlider(
  props: SingleSliderProps,
  ref: React.Ref<HTMLDivElement>
) {
  const { range, dotValues = [], min = 0, max } = props;
  const defaultValues = flatten([...dotValues, ...range]).sort((a, b) =>
    a > b ? 1 : -1
  );
  let defaultDefaultValue = defaultValues.length > 0 ? defaultValues[0] : 0;
  defaultDefaultValue = defaultDefaultValue < min ? min : defaultDefaultValue;
  defaultDefaultValue = defaultDefaultValue > max ? max : defaultDefaultValue;
  const { value, onChange, onUpdate = noop } = useDefaultValue(
    props,
    defaultDefaultValue
  );

  return (
    <SliderTrack
      ref={ref}
      {...props}
      value={[props.min || 0, value]}
      onUpdate={value => {
        onUpdate(value[1]);
      }}
      onChange={(value, context) => {
        onChange(value[1], context);
      }}
    />
  );
});

SingleSlider.displayName = "SingleSlider";

const RangeSlider = React.forwardRef(function RangeSlider(
  props: RangeSliderProps,
  ref: React.Ref<HTMLDivElement>
) {
  const defaultDefaultValue = props.range[0] || 0;
  const { value, onChange } = useDefaultValue(props, [
    defaultDefaultValue,
    defaultDefaultValue,
  ]);

  return (
    <SliderTrack
      ref={ref}
      {...props}
      value={value}
      onChange={(value, context) => {
        onChange(value, context);
      }}
    />
  );
});

RangeSlider.displayName = "RangeSlider";
