import {
  Button,
  createStyles,
  DialogActions,
  DialogContent,
  FormControl,
  InputLabel,
  MenuItem,
  OutlinedInput,
  Select,
  Theme
} from "@mui/material";
import moment, { Moment } from "moment";
import React from "react";
import ReactDOM from "react-dom";
import { DateRangePreset, SetDefaultPreset } from "./DateRange";
import ResponsiveDialog from "common/ResponsiveDialog";
import { withStyles, WithStyles } from "@mui/styles";

const styles = (_theme: Theme) => createStyles({});

interface Props extends WithStyles<typeof styles> {
  startDate: Moment;
  endDate: Moment;
  live?: boolean;
  updateDateRange: (start: Moment, end: Moment, live: boolean) => void;
  label?: string;
  allowLive?: boolean;
}

type DateRange<TDate> = [TDate | null, TDate | null];

interface State {
  selectMenuOpen: boolean;
  dateRangeSelect: DateRangePreset;
  dateRangeDialogOpen: boolean;
  labelWidth: number;
  dateRange: DateRange<Moment>;
}

class DateSelect extends React.Component<Props, State> {
  InputLabelRef: any;
  constructor(props: Props) {
    super(props);
    const { startDate, endDate, live } = props;

    this.state = {
      selectMenuOpen: false,
      dateRangeSelect: this.determineSelectOption(startDate, endDate, live),
      dateRangeDialogOpen: false,
      labelWidth: 0,
      dateRange: [startDate, endDate]
    };
  }

  determineSelectOption = (
    startDate?: Moment,
    endDate?: Moment,
    live?: boolean
  ): DateRangePreset => {
    if (live) return "live";
    if (!startDate || !endDate) {
      return "pastDay";
    }

    let hourDiff = moment(endDate)
      .diff(moment(startDate), "hours", true)
      .toFixed(4);
    if (hourDiff === "1.0000") {
      return "pastHour";
    }
    if (hourDiff === "12.0000") {
      return "pastTwelveHours";
    }

    let dayDiff = moment(endDate)
      .diff(moment(startDate), "days", true)
      .toFixed(4);
    if (dayDiff === "1.0000") {
      return "pastDay";
    }

    if (dayDiff === "7.0000") {
      return "pastWeek";
    }

    let monthDiff = moment(endDate)
      .diff(moment(startDate), "months", true)
      .toFixed(4);
    if (monthDiff === "1.0000") {
      return "pastMonth";
    }

    return "selectRange";
  };

  componentDidMount() {
    let labelRef: any = ReactDOM.findDOMNode(this.InputLabelRef);
    if (typeof labelRef !== "undefined" && labelRef !== null) {
      this.setState({
        labelWidth: labelRef.offsetWidth
      });
    }
  }

  componentDidUpdate = (prevProps: Props) => {
    const { startDate, endDate, live } = this.props;
    if (
      prevProps.startDate !== startDate ||
      prevProps.endDate !== endDate ||
      prevProps.live !== live
    ) {
      this.setState({
        dateRange: [startDate, endDate],
        dateRangeSelect: this.determineSelectOption(startDate, endDate, live)
      });
    }
  };

  changeDateRangeSelect = (selection: DateRangePreset) => {
    let dateRangeDialogOpen = false;

    let start, end;
    switch (selection) {
      case "live":
        SetDefaultPreset(selection);
        this.props.updateDateRange(moment(), moment(), true);
        break;
      case "pastHour":
        SetDefaultPreset(selection);
        start = moment().subtract(1, "hours");
        end = moment();
        this.props.updateDateRange(start, end, false);
        break;
      case "pastTwelveHours":
        SetDefaultPreset(selection);
        start = moment().subtract(12, "hours");
        end = moment();
        this.props.updateDateRange(start, end, false);
        break;
      case "pastDay":
        SetDefaultPreset(selection);
        start = moment().subtract(1, "days");
        end = moment();
        this.props.updateDateRange(start, end, false);
        break;
      case "pastWeek":
        SetDefaultPreset(selection);
        start = moment().subtract(7, "days");
        end = moment();
        this.props.updateDateRange(start, end, false);
        break;
      case "pastMonth":
        SetDefaultPreset(selection);
        start = moment().subtract(1, "months");
        end = moment();
        this.props.updateDateRange(start, end, false);
        break;
      case "selectRange":
        dateRangeDialogOpen = true;
        break;
      default:
        break;
    }

    this.setState({
      dateRangeSelect: selection,
      dateRangeDialogOpen: dateRangeDialogOpen
    });
  };

  updateDateRange = (dateRange: DateRange<Moment>) => {
    this.setState({ dateRange });
  };

  submitCustomRange = () => {
    const { dateRange } = this.state;
    const startDate = dateRange[0] ? dateRange[0].clone() : moment();
    const endDate = dateRange[1] ? dateRange[1].clone() : moment();
    this.props.updateDateRange(startDate, endDate, false);
  };

  handleSubmitDateRange = () => {
    this.submitCustomRange();
    this.closeDateRangeDialog();
  };

  closeDateRangeDialog = () => {
    this.setState({ dateRangeDialogOpen: false });
  };

  customRangeLabel = (dateRange: DateRange<Moment>) => {
    const startDate = dateRange[0] ? dateRange[0].clone() : moment();
    const endDate = dateRange[1] ? dateRange[1].clone() : moment();
    const sameYear = startDate.get("year") === endDate.get("year");

    return sameYear
      ? startDate.format("MMM Do") + " to " + endDate.format("MMM Do")
      : startDate.format("MMM Do, Y") + " to " + endDate.format("MMM Do, Y");
  };

  openSelectMenu = () => {
    this.setState({ selectMenuOpen: true });
  };

  closeSelectMenu = () => {
    this.setState({ selectMenuOpen: false });
  };

  render() {
    const { label, allowLive } = this.props;
    const {
      selectMenuOpen,
      dateRangeSelect,
      dateRangeDialogOpen,
      dateRange,
    } = this.state;

    return (
      <React.Fragment>
        <FormControl margin="normal" variant="outlined" fullWidth>
          <InputLabel
            ref={ref => {
              this.InputLabelRef = ref;
            }}
            htmlFor="select-date-range">
            {label !== undefined ? label : "Show"}
          </InputLabel>
          <Select
            open={selectMenuOpen}
            onClose={this.closeSelectMenu}
            onOpen={this.openSelectMenu}
            value={dateRangeSelect}
            onChange={event => this.changeDateRangeSelect(event.target.value as DateRangePreset)}
            input={<OutlinedInput /*labelWidth={labelWidth}*/ />}>
            {allowLive && <MenuItem value="live">Live</MenuItem>}
            <MenuItem value="pastHour">Past Hour</MenuItem>
            <MenuItem value="pastTwelveHours">Past 12 Hours</MenuItem>
            <MenuItem value="pastDay">Past Day</MenuItem>
            <MenuItem value="pastWeek">Past Week</MenuItem>
            <MenuItem value="pastMonth">Past Month</MenuItem>
            <MenuItem value="selectRange">
              {selectMenuOpen ? "Select Range" : this.customRangeLabel(dateRange)}
            </MenuItem>
          </Select>
        </FormControl>
        <ResponsiveDialog
          open={dateRangeDialogOpen}
          onClose={this.closeDateRangeDialog}
          aria-labelledby="date-range-dialog">
          <DialogContent>
            {/* <StaticDateRangePicker
              disableFuture
              value={dateRange}
              onChange={date => this.updateDateRange(date)}
              renderInput={(startProps, endProps) => (
                <React.Fragment>
                  <TextField {...startProps} />
                  <DateRangeDelimiter> to </DateRangeDelimiter>
                  <TextField {...endProps} />
                </React.Fragment>
              )}
            /> */}
          </DialogContent>
          <DialogActions>
            <Button onClick={this.closeDateRangeDialog} color="primary">
              Close
            </Button>
            <Button onClick={this.handleSubmitDateRange} color="primary">
              Submit
            </Button>
          </DialogActions>
        </ResponsiveDialog>
      </React.Fragment>
    );
  }
}

export default withStyles(styles)(DateSelect);
