import React, { useEffect, useRef, useState } from "react";
import { Redirect } from "react-router";
import { useLocation } from "react-router-dom";
import {
  Button,
  Checkbox,
  FormControlLabel,
  FormGroup,
  FormLabel,
  Radio,
  RadioGroup,
  TextField,
  Select,
} from "@material-ui/core";

import useStyles from "../../useStyles";
import { useFleetContext, FleetProvider } from "../../Contexts/FleetContext";
import { useStatusContext } from "../../Contexts/StatusContext";
import { useUserContext } from "../../Contexts/UserContext";
import { logger } from "../../../services/monitoring";

const MainForm = () => {
  const queries = new URLSearchParams(useLocation().search);

  const { fleet, getFleet, updateFleet, busy } = useFleetContext();
  const {
    token: {
      idToken: { jwtToken: token },
    },
  } = useUserContext();
  const { setMessage, setTitle, setSitePath } = useStatusContext();
  const [redirect, setRedirect] = useState(null);
  const classes = useStyles();

  const [name, setName] = useState(queries.get("name") ?? "");
  const [oldName] = useState(name);
  const [selectedLogLevel, setSelectedLogLevel] = useState("info");
  const [canbusEnabled, setCANBusEnabled] = useState(true);
  const [idpsEnabled, setIDPSEnabled] = useState(true);
  const [dataLoggerEnabled, setDataLoggerEnabled] = useState(false);
  const [maxMemBufferSize, setMaxMemBufferSize] = useState(0);
  const [maxDiskBufferSize, setMaxDiskBufferSize] = useState(0);
  const [dtcEnabled, setDTCEnabled] = useState(true);
  const debugMaskEl = useRef(null);

  const [dtc_ttl, setDtcTTL] = useState(0);

  const dtcTtlList = [
    { value: 0, label: "Select How Long to Send DTCs" },
    { value: 43200, label: "12 Hours" },
    { value: 86400, label: "24 Hours" },
    { value: 172800, label: "48 Hours" },
    { value: 259200, label: "72 Hours" },
    { value: 604800, label: "1 Week" },
    { value: 1209600, label: "2 Weeks" },
    { value: 1814400, label: "3 Weeks" },
    { value: 2419200, label: "4 Weeks" },
    { value: 3024000, label: "5 Weeks" },
  ]

  const showDebugMask = (process.env.REACT_APP_ENABLE_DEBUGMASK === "1");

  useEffect(() => {
    setTitle("Update Fleet");
    setSitePath([
      {
        label: `Fleet ${name}`,
        link: "/fleets",
      },
      {
        label: "Update Fleet",
      },
    ]);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    (async () => {
      try {
        if (!name || !token) return;
        await getFleet(oldName, token);
      } catch (e) {
        setMessage(e.message);
        logger.warn(e.stack);
      }
    })();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [token]);

  useEffect(() => {
    setSelectedLogLevel(fleet.log_level ?? selectedLogLevel);

    if (fleet.canbus) {
      setCANBusEnabled(fleet.canbus.enabled ?? canbusEnabled);
      setDataLoggerEnabled(
        fleet.canbus.data_logger_enabled ?? dataLoggerEnabled
      );
      setMaxMemBufferSize(fleet.canbus.max_mem_buffer_size ?? maxMemBufferSize);
      setMaxDiskBufferSize(
        fleet.canbus.max_disk_buffer_size ?? maxDiskBufferSize
      );
      setDTCEnabled(fleet.canbus.dtc_enabled ?? dtcEnabled);
    }

    if (showDebugMask) {
      debugMaskEl.current.value = fleet.debug_mask ?? ""
    }

    setIDPSEnabled(fleet.idps_enabled ?? idpsEnabled);

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [fleet]);

  const onNameChange = (event) => {
    setName(event.target.value);
  };

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

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

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

  const changeDtcTTL = (event) => {
    setDtcTTL(event.target.value);
  }

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

  const onDtcEnabledChange = (event) => {
    setDTCEnabled(event.target.checked);
  }

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

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

  const onSubmit = async (event) => {
    try {
      event.preventDefault();
      const formData = {
        name: name,
        log_level: selectedLogLevel,
        canbus: {
          enabled: canbusEnabled,
          data_logger_enabled: canbusEnabled ? dataLoggerEnabled : false,
          max_mem_buffer_size: canbusEnabled ? parseInt(maxMemBufferSize) : 0,
          max_disk_buffer_size: canbusEnabled && dataLoggerEnabled ? parseInt(maxDiskBufferSize) : 0,
          dtc_enabled: dtcEnabled
        },
        debug_mask: debugMaskEl.current?.value,
        idps_enabled: idpsEnabled,
        dtc_ttl: +dtc_ttl,
      };

      const result = await updateFleet(oldName, formData, token);
      if (!result || result.error) return;

      setMessage(`Updated ${result.name}`);
      setRedirect(`/fleet/${result.name}`);
    } catch (e) {
      setMessage(e.message);
      logger.warn(e.stack);
    }
  };

  if (redirect && redirect.length > 0) {
    return <Redirect to={redirect} />;
  }

  return (
    <div className={classes.paper}>
      <form className={classes.form} noValidate action="{onSubmit}">
        <TextField
          id="name"
          name="name"
          label="Name"
          variant="outlined"
          margin="normal"
          inputProps={{
            maxLength: "255",
          }}
          value={name}
          required
          fullWidth
          onChange={onNameChange}
        />
        <FormLabel id="demo-row-radio-buttons-group-label">Log Level</FormLabel>
        <RadioGroup
          row
          aria-labelledby="demo-row-radio-buttons-group-label"
          name="log-level-group"
          value={selectedLogLevel}
          onChange={onLogLevelChange}
          margin="normal"
        >
          <FormControlLabel value="trace" control={<Radio />} label="Trace" />
          <FormControlLabel value="debug" control={<Radio />} label="Debug" />
          <FormControlLabel value="info" control={<Radio />} label="Info" />
          <FormControlLabel
            value="warning"
            control={<Radio />}
            label="Warning"
          />
          <FormControlLabel value="error" control={<Radio />} label="Error" />
          <FormControlLabel
            value="critical"
            control={<Radio />}
            label="Critical"
          />
        </RadioGroup>
        <FormLabel id="demo-row-radio-buttons-group-label">CAN Bus</FormLabel>
        <FormGroup>
          <FormControlLabel
            control={
              <Checkbox checked={canbusEnabled} onChange={onCANBusChange} />
            }
            label="CAN Bus Enabled"
          />
          <TextField
            id="max_mem_buffer_size"
            name="max_mem_buffer_size"
            label="Max Memory Buffer Size (0 uses default size)"
            value={maxMemBufferSize}
            onChange={onMaxMemBufferSizeChange}
            variant="outlined"
            margin="normal"
            inputProps={{
              maxLength: "12",
            }}
            type="number"
            disabled={!canbusEnabled}
            required
            fullWidth
          />
          <FormControlLabel
            control={
              <Checkbox
                checked={dataLoggerEnabled}
                onChange={onDataLoggerChange}
                disabled={!canbusEnabled}
              />
            }
            label="Data Logger Enabled"
          />
        </FormGroup>
        <TextField
          id="max_disk_buffer_size"
          name="max_disk_buffer_size"
          label="Max Disk Buffer Size (0 uses default size)"
          value={maxDiskBufferSize}
          onChange={onMaxDiskBufferSizeChange}
          variant="outlined"
          margin="normal"
          inputProps={{
            maxLength: "12",
          }}
          type="number"
          disabled={!dataLoggerEnabled}
          required
          fullWidth
        />
        <FormControlLabel control={
          <Checkbox
            checked={dtcEnabled}
            onChange={onDtcEnabledChange}
          />
        } label="DTC Enabled" />
        <div>
          <Select
            native
            value={dtc_ttl}
            variant="outlined"
            inputProps={{
              name: "send-command",
              id: "send-command",
            }}
            disabled={!dtcEnabled}
            onChange={changeDtcTTL}
          >
            {dtcTtlList.map((item, index) => (
              <option key={index} value={item.value}>
                {item.label}
              </option>
            ))}
          </Select>
        </div>
        {showDebugMask && (
          <TextField
            id="debug_mask"
            name="debug_mask"
            label="Debug Mask"
            InputLabelProps={{
              shrink: true
            }}
            defaultValue=""
            variant="outlined"
            margin="normal"
            inputProps={{
              maxLength: "255",
            }}
            fullWidth
            inputRef={debugMaskEl}
          />
        )}
        <FormControlLabel control={
          <Checkbox
            checked={idpsEnabled}
            onChange={onIDPSChange}
          />
        } label="IDPS Enabled" />
        <Button
          type="submit"
          disabled={busy}
          fullWidth
          variant="contained"
          color="primary"
          className={classes.submit}
          onClick={onSubmit}
        >
          Submit
        </Button>
      </form>
    </div>
  );
};

const FleetUpdateForm = (props) => (
  <FleetProvider>
    <MainForm {...props} />
  </FleetProvider>
);

export default FleetUpdateForm;
