import {
  Button,
  DialogActions,
  DialogContent,
  DialogTitle,
  Grid2 as Grid,
  InputAdornment,
  List,
  ListItem,
  MenuItem,
  Tab,
  Tabs,
  TextField,
  Tooltip,
  Typography
} from "@mui/material";
import ResponsiveDialog from "common/ResponsiveDialog";
import { Component, Site } from "models";
import { ObjectHeater } from "models/ObjectHeater";
import { useGlobalState, useObjectHeaterAPI, useSiteAPI } from "providers";
import { useSnackbar } from "hooks";
import React, { useEffect, useState } from "react";
import { pond } from "protobuf-ts/pond";
import LinearMutationBuilder from "common/LinearMutationBuilder";
import { makeStyles } from "@mui/styles";

interface TabPanelProps {
  children?: React.ReactNode;
  index: any;
  value: any;
}

function TabPanelMine(props: TabPanelProps) {
  const { children, value, index, ...other } = props;

  return (
    <div
      role="tabpanel"
      hidden={value !== index}
      aria-labelledby={`simple-tab-${index}`}
      {...other}>
      {value === index && <React.Fragment>{children}</React.Fragment>}
    </div>
  );
}

const useStyles = makeStyles(() => ({
    dialogContent: {
      minHeight: "25vh"
    },
    tabSmall: {
      width: "100%",
      boxSizing: "border-box",
      flexShrink: 1,
      minWidth: "48px",
      marginTop: 0,
      paddingTop: 0
    }
  })
);

interface Props {
  open: boolean;
  componentsByDevice?: Map<string, Component[]>;
  close: (heater?: ObjectHeater) => void;
  heater?: ObjectHeater;
  sites?: Site[];
}

export default function ObjectHeaterSettings(props: Props) {
  const { open, close, heater, sites, componentsByDevice } = props;
  const objectHeaterAPI = useObjectHeaterAPI();
  const siteAPI = useSiteAPI();
  const [{ as }] = useGlobalState();
  const classes = useStyles();
  const [siteOptions, setSiteOptions] = useState<Site[]>([]);
  const [heaterName, setHeaterName] = useState("");
  const [heaterMake, setHeaterMake] = useState("");
  const [heaterModel, setHeaterModel] = useState("");
  const [siteKey, setSiteKey] = useState("");
  const [fuelType, setFuelType] = useState<pond.FuelType>(pond.FuelType.FUEL_TYPE_UNKNOWN);
  const [tankSize, setTankSize] = useState(0);
  const [fuelConsumption, setFuelConsumption] = useState(0);
  const [airCirculation, setAirCirculation] = useState(0);
  const { openSnack } = useSnackbar();
  const [currentTab, setCurrentTab] = useState(0);
  const [linearMutations, setLinearMutations] = useState<pond.LinearMutation[]>([]);
  const [newMutationDialog, setNewMutationDialog] = useState(false);
  const [existingMutation, setExistingMutation] = useState<pond.LinearMutation>();
  const [removeDialog, setRemoveDialog] = useState(false);

  const closeDialog = (heater?: ObjectHeater) => {
    close(heater);
  };

  //load the sites if not passed in
  useEffect(() => {
    if (sites) {
      setSiteOptions(sites);
    } else {
      siteAPI.listSites(0, 0, undefined, undefined, undefined, as).then(resp => {
        setSiteOptions(resp.data.sites.map(s => Site.any(s)));
      });
    }
  }, [sites, as, siteAPI]);
  //set the state variables
  useEffect(() => {
    setHeaterName("");
    setHeaterMake("");
    setHeaterModel("");
    setSiteKey("");
    setFuelType(pond.FuelType.FUEL_TYPE_UNKNOWN);
    setFuelConsumption(0);
    setTankSize(0);
    setAirCirculation(0);
    if (heater) {
      setHeaterName(heater.name);
      setHeaterMake(heater.settings.make);
      setHeaterModel(heater.settings.model);
      setSiteKey(heater.settings.siteKey);
      setFuelType(heater.settings.fuelType);
      setFuelConsumption(heater.settings.fuelConsumption);
      setTankSize(heater.settings.tankSize);
      setAirCirculation(heater.settings.airCirculation);
      setLinearMutations(heater.settings.mutations);
    }
  }, [heater]);

  const confirm = () => {
    if (heater) {
      let settings = heater.settings;
      settings.make = heaterMake;
      settings.model = heaterModel;
      settings.siteKey = siteKey;
      settings.tankSize = tankSize;
      settings.fuelType = fuelType;
      settings.fuelConsumption = fuelConsumption;
      settings.airCirculation = airCirculation;
      settings.mutations = linearMutations;
      objectHeaterAPI
        .updateObjectHeater(heater.key, heaterName, settings, as)
        .then(resp => {
          openSnack("Heater update");
          let updatedHeater = heater;
          updatedHeater.name = heaterName;
          updatedHeater.settings = settings;
          closeDialog(updatedHeater);
        })
        .catch(err => {
          openSnack("Failed to update heater");
        });
    } else {
      let settings: pond.ObjectHeaterSettings = pond.ObjectHeaterSettings.create({
        make: heaterMake,
        model: heaterModel,
        siteKey: siteKey,
        fuelType: fuelType,
        tankSize: tankSize,
        fuelConsumption: fuelConsumption,
        airCirculation: airCirculation,
        mutations: linearMutations
      });
      objectHeaterAPI
        .addObjectHeater(heaterName, settings, as)
        .then(resp => {
          openSnack("New heater added");
          let newHeater = ObjectHeater.create(
            pond.ObjectHeater.create({ key: resp.data.key, name: heaterName, settings: settings })
          );
          closeDialog(newHeater);
        })
        .catch(err => {
          openSnack("There was a problem adding your heater");
        });
    }
  };

  const removeHeater = () => {
    if (heater) {
      objectHeaterAPI
        .removeObjectHeater(heater.key, as)
        .then(resp => {
          openSnack("Heater Removed");
          setRemoveDialog(false);
          closeDialog();
        })
        .catch(err => {
          openSnack("Failed to remove heater");
        });
    }
  };

  const settingsContent = () => {
    return (
      <React.Fragment>
        <TextField
          label="Heater Name"
          fullWidth
          value={heaterName}
          onChange={e => {
            setHeaterName(e.target.value);
          }}
        />
        <TextField
          label="Site"
          fullWidth
          select
          value={siteKey}
          onChange={e => {
            setSiteKey(e.target.value);
          }}>
          {siteOptions.map(site => (
            <MenuItem key={site.key()} value={site.key()}>
              {site.siteName()}
            </MenuItem>
          ))}
        </TextField>
        <TextField
          label="Make"
          fullWidth
          value={heaterMake}
          onChange={e => {
            setHeaterMake(e.target.value);
          }}
        />
        <TextField
          label="Model"
          fullWidth
          value={heaterModel}
          onChange={e => {
            setHeaterModel(e.target.value);
          }}
        />
        <TextField
          label="Fuel Type"
          fullWidth
          select
          value={fuelType}
          onChange={e => {
            setFuelType(+e.target.value as pond.FuelType);
          }}>
          <MenuItem key="unknown" value={pond.FuelType.FUEL_TYPE_UNKNOWN}>
            Select Fuel Type
          </MenuItem>
          <MenuItem key="gas" value={pond.FuelType.FUEL_TYPE_GASOLINE}>
            Gasoline
          </MenuItem>
          <MenuItem key="diesel" value={pond.FuelType.FUEL_TYPE_DIESEL}>
            Diesel
          </MenuItem>
          <MenuItem key="propane" value={pond.FuelType.FUEL_TYPE_PROPANE}>
            Propane
          </MenuItem>
        </TextField>
        <TextField
          label="Tank Size"
          fullWidth
          type="number"
          value={tankSize}
          onChange={e => {
            setTankSize(+e.target.value);
          }}
          InputProps={{
            endAdornment: <InputAdornment position="end">G</InputAdornment>
          }}
        />
        <TextField
          label="Fuel Consumption"
          fullWidth
          type="number"
          value={fuelConsumption}
          onChange={e => {
            setFuelConsumption(+e.target.value);
          }}
          InputProps={{
            endAdornment: <InputAdornment position="end">G/hr</InputAdornment>
          }}
        />
        <TextField
          label="Air Circulation"
          fullWidth
          type="number"
          value={airCirculation}
          onChange={e => {
            setAirCirculation(+e.target.value);
          }}
          InputProps={{
            endAdornment: <InputAdornment position="end">CFM</InputAdornment>
          }}
        />
      </React.Fragment>
    );
  };

  const mutationsContent = () => {
    let mutations: JSX.Element[] = [];
    if (heater && heater.settings.mutations) {
      heater.settings.mutations.forEach((mut, i) => {
        mutations.push(
          <ListItem key={"mutation" + i}>
            <Grid
              container
              direction="row"
              alignContent="center"
              alignItems="center">
              <Grid size={5}>
                <Typography>{mut.mutationName}</Typography>
              </Grid>
              <Grid>
                <Button
                  variant="contained"
                  style={{ backgroundColor: "red" }}
                  onClick={() => {
                    let lm = linearMutations;
                    lm.splice(i, 1);
                    setLinearMutations([...lm]);
                  }}>
                  Remove
                </Button>
                <Button
                  style={{ marginLeft: 10 }}
                  variant="contained"
                  color="primary"
                  onClick={() => {
                    setExistingMutation(mut);
                    setNewMutationDialog(true);
                  }}>
                  Edit
                </Button>
              </Grid>
            </Grid>
          </ListItem>
        );
      });
    }
    let mutationList: JSX.Element = <List>{mutations}</List>;
    return (
      <React.Fragment>
        <Button
          variant="contained"
          color="primary"
          onClick={() => {
            setExistingMutation(undefined);
            setNewMutationDialog(true);
          }}>
          Add New Mutation
        </Button>
        <List>{mutationList}</List>
      </React.Fragment>
    );
  };

  const removeConfirmation = () => {
    return (
      <ResponsiveDialog open={removeDialog} onClose={() => setRemoveDialog(false)}>
        <DialogContent>Are you sure you would like to delete heater?</DialogContent>
        <DialogActions>
          <Button
            variant="contained"
            color="primary"
            onClick={() => {
              setRemoveDialog(false);
            }}>
            Cancel
          </Button>
          <Button
            variant="contained"
            color="primary"
            onClick={() => {
              removeHeater();
            }}>
            Delete
          </Button>
        </DialogActions>
      </ResponsiveDialog>
    );
  };

  return (
    <React.Fragment>
      {removeConfirmation()}
      <ResponsiveDialog
        open={open}
        onClose={() => {
          closeDialog();
        }}>
        <DialogTitle>Heater Settings</DialogTitle>
        <DialogContent>
          <Tabs
            value={currentTab}
            onChange={(_, value) => setCurrentTab(value)}
            indicatorColor="primary"
            textColor="primary"
            variant="fullWidth"
            aria-label="device tabs"
            classes={{ root: classes.tabSmall }}>
            <Tab label={"Heater Settings"} className={classes.tabSmall} />
            <Tab
              style={{ pointerEvents: "auto" }}
              label={
                componentsByDevice ? (
                  "Calculated Measurements"
                ) : (
                  <Tooltip title="Requires Connected Device">
                    <span>Calculated Measurements</span>
                  </Tooltip>
                )
              }
              className={classes.tabSmall}
              disabled={!componentsByDevice}
            />
          </Tabs>
          <TabPanelMine value={currentTab} index={0}>
            {settingsContent()}
          </TabPanelMine>
          <TabPanelMine value={currentTab} index={1}>
            {mutationsContent()}
          </TabPanelMine>
        </DialogContent>
        <DialogActions>
          <Grid container direction="row">
            <Grid>
              {heater && (
                <Button
                  variant="contained"
                  style={{ backgroundColor: "red" }}
                  onClick={() => {
                    setRemoveDialog(true);
                  }}>
                  Delete
                </Button>
              )}
            </Grid>
            <Grid></Grid>
          </Grid>
          <Button
            variant="contained"
            disabled={heaterName === ""}
            color="primary"
            onClick={() => {
              confirm();
            }}>
            {heater ? "Update" : "Create"}
          </Button>
        </DialogActions>
        {componentsByDevice && (
          <LinearMutationBuilder
            existingMutation={existingMutation}
            componentsByDevice={componentsByDevice}
            open={newMutationDialog}
            onClose={() => {
              setNewMutationDialog(false);
            }}
            onSubmit={newMutation => {
              let lm = linearMutations;
              lm.push(newMutation);
              setLinearMutations(lm);
            }}
          />
        )}
      </ResponsiveDialog>
    </React.Fragment>
  );
}
