import { useState, useEffect, forwardRef, useImperativeHandle } from "react";
import {
  Checkbox,
  FormControl,
  FormControlLabel,
  FormGroup,
  FormLabel,
  Radio,
  RadioGroup,
  TextField,
} from '@material-ui/core';
import SearchSelect from "../../SearchSelect/SearchSelect";
import { useStatusContext } from "../../Contexts/StatusContext";
import { useUserContext } from "../../Contexts/UserContext";
import fleetsAPI from "../../../services/fleetsAPI";
import useStyles from "../../useStyles";

const DEFAULT_LOG_LEVEL = "info";
const DEFAULT_CANBUS_ENABLED = false;
const DEFAULT_DATA_LOGGER_ENABLED = false;
const DEFAULT_MAX_MEM_BUFFER_SIZE = 0;
const DEFAULT_MAX_DISK_BUFFER_SIZE = 0;
const DEFAULT_IDPS_ENABLED = true;

export default forwardRef(({
  ids = [],
  idCSV = "",
  fleet,
}, ref) => {
  const [fromFleet, setFromFleet] = useState(fleet);
  const [toFleet, setToFleet] = useState();
  const classnames = useStyles();
  const { setMessage } = useStatusContext();
  const { token: { idToken: { jwtToken: token } } } = useUserContext();



  const [selectedLogLevel, setSelectedLogLevel] = useState(DEFAULT_LOG_LEVEL);
  const [canbusEnabled, setCANBusEnabled] = useState(DEFAULT_CANBUS_ENABLED);
  const [idpsEnabled, setIDPSEnabled] = useState(DEFAULT_IDPS_ENABLED);
  const [dataLoggerEnabled, setDataLoggerEnabled] = useState(DEFAULT_DATA_LOGGER_ENABLED);
  const [maxMemBufferSize, setMaxMemBufferSize] = useState(DEFAULT_MAX_MEM_BUFFER_SIZE);
  const [maxDiskBufferSize, setMaxDiskBufferSize] = useState(DEFAULT_MAX_DISK_BUFFER_SIZE);

  const logLevel = [
    ["trace", "Trace"],
    ["debug", "Debug"],
    ["info", "Info"],
    ["warning", "Warning"],
    ["error", "Error"],
    ["critical", "Critical"],
  ];

  useImperativeHandle(ref, () => ({
    async submit() {
      const errorTracking = [false, false];

      if (toFleet) {
        const payload = {
          vins: ids,
          log_level: selectedLogLevel,
          canbus: {
            enabled: canbusEnabled,
            data_logger_enabled: canbusEnabled ? dataLoggerEnabled : false,
            max_mem_buffer_size: parseInt(maxMemBufferSize),
            max_disk_buffer_size: parseInt(maxDiskBufferSize),
          },
          idps_enabled: idpsEnabled,
        };

        await fleetsAPI
          .addFleetVehicles(toFleet, payload, token)
          .then((response) => {
            if (response.error) {
              errorTracking[0] = true;
              setMessage(`${response.error}: ${response.message}`);
            }

            if (response.vins) {
              setMessage(`Added ${response.vins.length} vehicles to ${toFleet}.`);
              return;
            }

            setMessage(`Something unexpected happened while attempting to add vehicles to fleet.`);
          })
          .catch((error) => {
            setMessage(JSON.stringify(error));
            return Promise.reject("Could not add vehicles to fleet.");
          });
      }

      if (fromFleet) {
        await fleetsAPI
          .deleteFleetVehicles(fromFleet, ids, token)
          .then((response) => {
            if (response.error) {
              errorTracking[1] = true;
              setMessage(`${response.error}: ${response.message}`);
            }

            if (response.message === "Deleted") {
              setMessage(`Removed ${ids.length} vehicles from ${fromFleet}.`);
              return;
            }
          })
          .catch((error) => {
            setMessage(JSON.stringify(error));
            return Promise.reject("Could not remove vehicles from fleet.");
          });
      }

      return {
        fromFleet,
        fromVehicles: errorTracking[1] ? [] : ids,
        toFleet,
        toVehicles: errorTracking[0] ? [] : ids,
      };
    },
  }));

  async function searchFleets(search) {
    return fleetsAPI
      .getFleets({
        search,
        limit: 10,
        offset: 0,
        order: `id desc`,
      }, token)
      .then(response => response.data.map(fleet => fleet.name))
      .catch(() => []);
  }

  const onLogLevelChange = (event) => {
    setSelectedLogLevel(event.target.value);
  }

  const onCANBusChange = (event) => {
    setCANBusEnabled(event.target.checked);
  }

  const onIDPSChange = (event) => {
    setIDPSEnabled(event.target.checked);
  }

  const onDataLoggerChange = (event) => {
    setDataLoggerEnabled(event.target.checked);
  }

  const onMaxMemBufferSizeChange = (event) => {
    setMaxMemBufferSize(event.target.value);
  }

  const onMaxDiskBufferSizeChange = (event) => {
    setMaxDiskBufferSize(event.target.value);
  }

  useEffect(() => {
    if (!toFleet) {
      setSelectedLogLevel(DEFAULT_LOG_LEVEL);
      setCANBusEnabled(DEFAULT_CANBUS_ENABLED);
      setIDPSEnabled(DEFAULT_IDPS_ENABLED);
      setDataLoggerEnabled(DEFAULT_DATA_LOGGER_ENABLED);
      setMaxMemBufferSize(DEFAULT_MAX_MEM_BUFFER_SIZE);
      setMaxDiskBufferSize(DEFAULT_MAX_DISK_BUFFER_SIZE);
    }
  }, [
    toFleet, setSelectedLogLevel, setCANBusEnabled, setIDPSEnabled,
    setDataLoggerEnabled, setMaxMemBufferSize, setMaxDiskBufferSize
  ]);

  useEffect(() => {
    if (!canbusEnabled) {
      setDataLoggerEnabled(DEFAULT_DATA_LOGGER_ENABLED);
      setMaxMemBufferSize(DEFAULT_MAX_MEM_BUFFER_SIZE);
      setMaxDiskBufferSize(DEFAULT_MAX_DISK_BUFFER_SIZE);
      setIDPSEnabled(DEFAULT_IDPS_ENABLED)
    }
  }, [
    canbusEnabled, setDataLoggerEnabled, setIDPSEnabled, setMaxMemBufferSize,
    setMaxDiskBufferSize,
  ]);

  useEffect(() => {
    if (!dataLoggerEnabled) {
      setMaxDiskBufferSize(DEFAULT_MAX_DISK_BUFFER_SIZE);
    }
  }, [
    dataLoggerEnabled, setMaxDiskBufferSize,
  ]);

  return (
    <div>
      <p>
        This operation will affect fleet membership for the following VINs: {idCSV}.
      </p>
      <p>
        VINs will be removed from the "From Fleet" and added to the "To Fleet". If you would
        like to only add or only remove the other field can be left blank.
      </p>
      <FormGroup row className={classnames.formGrid}>
        <FormControl variant="filled" className={classnames.formGridItem}>
          <SearchSelect
            label="Remove From Fleet"
            value={fromFleet}
            setValue={setFromFleet}
            getData={searchFleets}
            research={true}
          />
        </FormControl>
        <FormControl variant="filled" className={classnames.formGridItem}>
          <SearchSelect
            label="Add To Fleet"
            value={toFleet}
            setValue={setToFleet}
            getData={searchFleets}
            research={true}
          />
        </FormControl>
      </FormGroup>
      <FormGroup className={classnames.marginX}>
        <FormControl>
          <FormLabel id="demo-row-radio-buttons-group-label">Log Level</FormLabel>
          <RadioGroup
            aria-labelledby="demo-row-radio-buttons-group-label"
            value={selectedLogLevel}
            onChange={onLogLevelChange}
            row
          >
            {logLevel.map(([value, label]) => (
              <FormControlLabel
                key={value}
                value={value}
                control={<Radio size="small" />}
                label={label}
                disabled={!toFleet}
              />
            ))}
          </RadioGroup>
        </FormControl>
      </FormGroup>
      <FormGroup row className={classnames.marginX}>
        <FormControlLabel control={
          <Checkbox
            checked={canbusEnabled}
            onChange={onCANBusChange}
            disabled={!toFleet}
          />
        } label="CAN Bus Enabled" />
        <FormControlLabel control={
          <Checkbox
            checked={idpsEnabled}
            onChange={onIDPSChange}
            disabled={!toFleet}
          />
        } label="IDPS Enabled" />
        <FormControlLabel control={
          <Checkbox
            checked={dataLoggerEnabled}
            onChange={onDataLoggerChange}
            disabled={!canbusEnabled}
          />
        } label="Data Logger Enabled" />
      </FormGroup>
      <FormGroup row className={classnames.formGrid}>
        <TextField
          className={classnames.formGridItem}
          id="max_mem_buffer_size"
          label='Max Memory Buffer Size'
          value={maxMemBufferSize}
          onChange={onMaxMemBufferSizeChange}
          variant="outlined"
          inputProps={{ maxLength: "12" }}
          type="number"
          disabled={!canbusEnabled || !toFleet}
        />
        <TextField
          className={classnames.formGridItem}
          id="max_disk_buffer_size"
          label='Max Disk Buffer Size'
          value={maxDiskBufferSize}
          onChange={onMaxDiskBufferSizeChange}
          variant="outlined"
          inputProps={{ maxLength: "12" }}
          type="number"
          disabled={!dataLoggerEnabled || !toFleet}
        />
      </FormGroup>
    </div>
  );
});