import DateFnsUtils from '@date-io/date-fns';
import { Button, Checkbox, Chip, CircularProgress, FormControl, FormControlLabel, Grid, InputLabel, ListItemText, MenuItem, Select } from "@material-ui/core";
import { KeyboardDatePicker, KeyboardTimePicker, MuiPickersUtilsProvider } from '@material-ui/pickers';
import React, { useEffect, useState } from "react";
import { logger } from "../../../services/monitoring";
import { CANSignalsExportProvider, useCANSignalsExportContext } from "../../Contexts/CANSignalsExportContext";
import { useStatusContext } from "../../Contexts/StatusContext";
import { useUserContext } from "../../Contexts/UserContext";
import useStyles from "../../useStyles";

const MainForm = ({ id }) => {
  const classes = useStyles();
  const { setMessage } = useStatusContext();
  const { busy, canSignals, getCANSignalList, getDynamicColumnCANSignals } = useCANSignalsExportContext();

  const [selectedStartDate, setSelectedStartDate] = useState(new Date(Date.now() - 24 * 60 * 60 * 1000));
  const [selectedEndDate, setSelectedEndDate] = useState(new Date());
  const [selectedCanSignals, setSelectedCanSignals] = useState([]);
  const [selectAllCanSignals, setSelectAllCanSignals] = useState(false);
  const [gmtTimezone, setGmtTimezone] = useState(false);

  const {
    token: {
      idToken: { jwtToken: token },
    },
  } = useUserContext();

  const handleSubmit = async (event) => {
    event.preventDefault();
    let timestamp_start = Date.parse(selectedStartDate.toUTCString()) / 1000
    let timestamp_end = Date.parse(selectedEndDate.toUTCString()) / 1000
    try {
      await getDynamicColumnCANSignals(id, timestamp_start, timestamp_end, selectedCanSignals, selectAllCanSignals, token)
    } catch (e) {
      setMessage(e.message);
      logger.error(e.stack)
    }
  };

  const isSubmitDisabled = !selectedStartDate || !selectedEndDate || selectedCanSignals.length === 0;

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

  const handleDateChange = (value, dateType) => {
    const newDate = new Date(value);
    const oldDate = dateType === "start" ? selectedStartDate || new Date() : selectedEndDate || new Date();
    newDate.setHours(oldDate.getHours());
    newDate.setMinutes(oldDate.getMinutes());
    newDate.setSeconds(oldDate.getSeconds());
    if (dateType === "start") {
      setSelectedStartDate(newDate);
    } else {
      setSelectedEndDate(newDate);
    }
  };

  const handleTimeFromChange = (value) => {
    setSelectedStartDate(value);
  };
  const handleTimeToChange = (value) => {
    setSelectedEndDate(value);
  };

  const handleSelectedItemsChange = (event) => {
    const { value } = event.target;
    if (value.some(item => item === "Select All")) {
      setSelectAllCanSignals(true);
      if (selectedCanSignals.length === canSignals.length) {
        setSelectedCanSignals([]);
      } else {
        setSelectedCanSignals(canSignals.map(signal => signal.signal_name));
      }
    } else {
      setSelectAllCanSignals(false);
      setSelectedCanSignals(value);
    }
  };

  const displayTimeAsGMT = (date) => {
    return gmtTimezone
      ? date.toLocaleString("en-US", {timeZone: "Etc/GMT"})
      : date;
  }


  return (
    <div className={classes.paper}>
      <Grid container spacing={3} justifyContent="center">
        <Grid item xs={12}>
          <MuiPickersUtilsProvider utils={DateFnsUtils}>
            <Grid container justifyContent="space-between">
              <Grid item xs={6} md={3}>
                <KeyboardDatePicker
                  required
                  disableToolbar
                  variant="inline"
                  format="MM/dd/yyyy"
                  margin="normal"
                  id="date-picker-inline"
                  label="Date From"
                  value={displayTimeAsGMT(selectedStartDate)}
                  onChange={(value) => handleDateChange(value, "start")}
                  KeyboardButtonProps={{
                    'aria-label': 'change date',
                  }}
                />
              </Grid>
              <Grid item xs={6} md={3}>
                <KeyboardTimePicker
                  required
                  margin="normal"
                  variant="inline"
                  id="time-picker"
                  label="Time From"
                  value={displayTimeAsGMT(selectedStartDate)}
                  onChange={handleTimeFromChange}
                  KeyboardButtonProps={{
                    'aria-label': 'change time',
                  }}
                />
              </Grid>
              <Grid item xs={6} md={3}>
                <KeyboardDatePicker
                  required
                  disableToolbar
                  variant="inline"
                  format="MM/dd/yyyy"
                  margin="normal"
                  id="date-picker-inline"
                  label="Date To"
                  value={displayTimeAsGMT(selectedEndDate)}
                  onChange={(value) => handleDateChange(value, "end")}
                  KeyboardButtonProps={{
                    'aria-label': 'change date',
                  }}
                />
              </Grid>
              <Grid item xs={6} md={3}>
                <KeyboardTimePicker
                  required
                  margin="normal"
                  id="time-picker"
                  variant="inline"
                  label="Time To"
                  value={displayTimeAsGMT(selectedEndDate)}
                  onChange={handleTimeToChange}
                  KeyboardButtonProps={{
                    'aria-label': 'change time',
                  }}
                />
              </Grid>
              <Grid item xs={6} md={3}>
                <FormControlLabel
                  label="GMT"
                  control={
                    <Checkbox
                      checked={gmtTimezone}
                      onChange={() => setGmtTimezone((current) => !current)}
                    />
                  }
                />
              </Grid>
            </Grid>
          </MuiPickersUtilsProvider>
        </Grid>
        <Grid item xs={12}>
          <FormControl fullWidth required>
            <InputLabel id="select-can-signals-label">Select CAN signals</InputLabel>
            <Select
              labelId="select-can-signals-label"
              id="select-can-signals"
              multiple
              value={selectedCanSignals}
              onChange={handleSelectedItemsChange}
              fullWidth
              inputvariant="outlined"
              renderValue={(selected) => (
                <div className={classes.chips}>
                  {selected.map((value) => (
                    <Chip key={value} label={value} className={classes.chip} />
                  ))}
                </div>
              )}
            >
              <MenuItem value="Select All">
                <Checkbox checked={selectedCanSignals.length === canSignals.length} />
                <ListItemText primary="Select All" />
              </MenuItem>
              {canSignals.map((signal) => (
                <MenuItem key={signal.signal_name} value={signal.signal_name}>
                  <Checkbox checked={selectedCanSignals.indexOf(signal.signal_name) > -1} />
                  <ListItemText primary={signal.signal_name} />
                </MenuItem>
              ))}
            </Select>
          </FormControl>
        </Grid>
        <Grid item xs={12}>
          <Button
            variant="contained"
            color="primary"
            onClick={handleSubmit}
            disabled={isSubmitDisabled || busy}
            fullWidth
          >
            {busy ? <CircularProgress size={24} /> : "Submit"}
          </Button>
        </Grid>
      </Grid>
    </div>
  );
};

const CANSignalExport = (props) => (
  <CANSignalsExportProvider>
    <MainForm {...props} />
  </CANSignalsExportProvider>
);

export default CANSignalExport;
