import * as React from "react";
import { useState, useEffect } from "react";
import { get } from "lodash";
import Switch from "@material-ui/core/Switch";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Grid from "@material-ui/core/Grid";
// import Typography from "@material-ui/core/Typography";
import IconButton from "@material-ui/core/IconButton";
import Slider from "@material-ui/core/Slider";
import RemoveIcon from "@material-ui/icons/Remove";
import AddIcon from "@material-ui/icons/Add";

import { isNumber } from "@sc/plugins/utilities";
import { ButtonSliderGroupProps } from "./types";

/**
 * Renders two buttons and an optional slider
 *
 * Used for use cases like incrementing/decrementing a property, or setting a precise value (using the slider)
 */
export const ButtonSliderGroup: React.FC<ButtonSliderGroupProps> = ({
  value = 0,
  minValue = 0,
  maxValue,
  showAutoCheck = false,
  showMaxCheck = false,
  showSlider = false,
  label,
  toolTip,
  button1 = {
    value: "SHRINK",
    style: {},
  },
  button2 = {
    value: "GROW",
    style: {},
  },
  // originalValue,
  autoCheckValue,
  isMax = false,
  isAuto = false,
  __testSliderValue = 1,
  onChange = () => false,
}) => {
  const [sliderValue, setSliderValue] = useState<number>(value);
  const [initialValue, setInitialValue] = useState<number>(value);
  const [maxIsChecked, setMaxIsChecked] = useState<boolean>(isMax);
  const [autoIsChecked, setAutoIsChecked] = useState<boolean>(isAuto);

  const handleChange = (
    newValue: number | React.ReactText,
    skipUncheck: boolean = false
  ) => {
    let value = newValue;
    if (newValue > maxValue && isNumber(newValue)) value = maxValue;
    if (newValue < minValue && isNumber(newValue)) value = minValue;

    setSliderValue(value as number);

    // Should immediately uncheck the AutoCheck and MaxCheck checkbox when the button is clicked or slider is changed
    if (!skipUncheck) {
      setMaxIsChecked(false);
      setAutoIsChecked(false);
    }

    if (newValue === maxValue) setMaxIsChecked(true);

    onChange(value, sliderValue);
  };

  const handleMaxCheck = (
    event: React.ChangeEvent<HTMLInputElement>,
    checked: boolean
  ) => {
    // Should set the value to the maxCheckValue prop's value when the [Max] checkbox is checked
    setMaxIsChecked(checked);
    if (checked) {
      setInitialValue(sliderValue);
      handleChange(maxValue, true);
    } else {
      handleChange(initialValue);
    }
  };

  const handleAutoCheck = (
    event: React.ChangeEvent<HTMLInputElement>,
    checked: boolean
  ) => {
    // Should set the value to the autoCheckValue prop's value when the [Auto] checkbox is checked
    setAutoIsChecked(checked);
    if (checked) {
      setInitialValue(sliderValue);
      handleChange(autoCheckValue, true);
    } else {
      handleChange(initialValue);
    }
  };

  useEffect(() => {
    // handleChange(null, sliderValue);
  }, []);

  return (
    <fieldset data-testid="ButtonSliderGroup" title={toolTip}>
      <legend>{label}</legend>
      <Grid container spacing={2}>
        <Grid item>
          <IconButton
            data-testid="ButtonSliderGroup-Button1"
            onClick={() => handleChange(button1.value)}
            style={{ ...button1.style }}
          >
            {get(button1, "icon") || <RemoveIcon />}
          </IconButton>
        </Grid>

        {showSlider && (
          <Grid item xs>
            <Slider
              data-testid="ButtonSliderGroup-slider"
              value={sliderValue}
              onChange={(e, v) => handleChange(v)}
              aria-labelledby="continuous-slider"
              max={maxValue}
              min={minValue}
            />
          </Grid>
        )}
        <Grid item>
          <IconButton
            data-testid="ButtonSliderGroup-Button2"
            onClick={() => handleChange(button2.value)}
            style={{ ...button2.style }}
          >
            {get(button2, "icon") || <AddIcon />}
          </IconButton>
        </Grid>
      </Grid>

      {showMaxCheck && (
        <FormControlLabel
          control={
            <Switch
              name="MaxCheck"
              onChange={handleMaxCheck}
              data-testid="ButtonSliderGroup-maxCheck"
              checked={maxIsChecked}
            />
          }
          label="Max"
        />
      )}

      {showAutoCheck && (
        <FormControlLabel
          control={
            <Switch
              name="AutoSize"
              onChange={handleAutoCheck}
              data-testid="ButtonSliderGroup-autoCheck"
              checked={autoIsChecked}
            />
          }
          label="Auto Size"
        />
      )}

      {/* This is for (jest) testing purposes */}
      {__testSliderValue && (
        <div
          data-testid="__testSliderValueUpdate"
          onClick={() => handleChange(__testSliderValue)}
        />
      )}
    </fieldset>
  );
};

export default ButtonSliderGroup;
