import DateFnsUtils from '@date-io/date-fns';
import { Button, Checkbox, CircularProgress, FormControlLabel, Grid } 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";
import { TrieSelect } from '../../Controls/TrieSelect';

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 displayTimeAsGMT = (date) => {
    return gmtTimezone
      ? date.toLocaleString("en-US", { timeZone: "Etc/GMT" })
      : date;
  }

  useEffect(() => {
    if (canSignals.length === selectedCanSignals.length) {
      setSelectAllCanSignals(true);
    } else {
      setSelectAllCanSignals(false);
    }
  }, [canSignals, selectedCanSignals, setSelectAllCanSignals]);

  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}>
          <TrieSelect
            label="All CAN Signals"
            classification="Signals"
            options={canSignals.map((signal => signal.signal_name))}
            onChange={setSelectedCanSignals}
          />
        </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;
