import {
  Box,
  Button,
  Card,
  Grid2 as Grid,
  MenuItem,
  Select,
  ToggleButton,
  ToggleButtonGroup,
  Typography
} from "@mui/material";
import { Component, Device } from "models";
import { Gate } from "models/Gate";
import { pond } from "protobuf-ts/pond";
import { useGlobalState, useGateAPI } from "providers";
import { useEffect, useState } from "react";
import { useMobile, useSnackbar } from "hooks";
import { UnitMeasurement } from "models/UnitMeasurement";
import { quack } from "protobuf-ts/quack";
import GateDeviceInteraction from "./GateDeviceInteraction";
import GateSVG from "./GateSVG";
import GateGraphs from "./GateGraphs";
//import { ToggleButton, ToggleButtonGroup } from "@material-ui/lab";
import { getThemeType } from "theme";
import ButtonGroup from "common/ButtonGroup";

interface Props {
  gate: Gate;
  comprehensiveDevice: pond.ComprehensiveDevice;
  linkedCompList: Component[];
  drawerView?: boolean;
}



export default function GateDevice(props: Props) {
  const { gate, comprehensiveDevice, linkedCompList, drawerView } = props;
  const [{as}] = useGlobalState();
  const [device, setDevice] = useState<Device>(Device.create());
  const [componentOptions, setComponentOptions] = useState<Map<string, Component>>(
    new Map<string, Component>()
  );
  const gateAPI = useGateAPI();
  const [tempKey, setTempKey] = useState("");
  const [pressureKey, setPressureKey] = useState("");
  const [ambientKey, setAmbientKey] = useState("");
  const { openSnack } = useSnackbar();
  const [{ user }] = useGlobalState();
  const [interactionDialog, setInteractionDialog] = useState(false);
  const [densityTemp, setDensityTemp] = useState(0);
  const isMobile = useMobile();
  const [pcaState, setPCAState] = useState(false);
  const [pcaFanOn, setPCAFanOn] = useState(false);
  const [detail, setDetail] = useState<"sensors" | "analytics">("analytics");
  const [lastAmbient, setLastAmbient] = useState(0);
  const [lastTemps, setLastTemps] = useState({ t1: 0, t2: 0 });
  const [lastPressures, setLastPressures] = useState({ p1: 0, p2: 0 });

  // const StyledToggleButtonGroup = withStyles(theme => ({
  //   grouped: {
  //     margin: theme.spacing(-0.5),
  //     border: "none",
  //     padding: theme.spacing(1),
  //     "&:not(:first-child):not(:last-child)": {
  //       borderRadius: 24,
  //       marginRight: theme.spacing(0.5),
  //       marginLeft: theme.spacing(0.5)
  //     },
  //     "&:first-child": {
  //       borderRadius: 24,
  //       marginLeft: theme.spacing(0.25)
  //     },
  //     "&:last-child": {
  //       borderRadius: 24,
  //       marginRight: theme.spacing(0.25)
  //     }
  //   },
  //   root: {
  //     backgroundColor: darken(
  //       theme.palette.background.paper,
  //       getThemeType() === "light" ? 0.05 : 0.25
  //     ),
  //     borderRadius: 24,
  //     content: "border-box"
  //   }
  // }))(ToggleButtonGroup);

  // const StyledToggle = withStyles({
  //   root: {
  //     backgroundColor: "transparent",
  //     overflow: "visible",
  //     content: "content-box",
  //     "&$selected": {
  //       backgroundColor: "gold",
  //       color: "black",
  //       borderRadius: 24,
  //       fontWeight: "bold"
  //     },
  //     "&$selected:hover": {
  //       backgroundColor: "rgb(255, 255, 0)",
  //       color: "black",
  //       borderRadius: 24
  //     }
  //   },
  //   selected: {}
  // })(ToggleButton);

  useEffect(() => {
    if (comprehensiveDevice.device) {
      setDevice(Device.any(comprehensiveDevice.device));
    }
    if (comprehensiveDevice.components) {
      let components: Map<string, Component> = new Map<string, Component>();
      setAmbientKey("");
      setTempKey("");
      setPressureKey("");
      comprehensiveDevice.components.forEach(comp => {
        let c = Component.any(comp);
        if (linkedCompList.some(el => el.key() === c.key())) {
          components.set(c.key(), c);
          //determine the positioned components using the gates preferences for it components
          switch (gate.preferences[c.key()]) {
            case pond.GateComponentType.GATE_COMPONENT_TYPE_AMBIENT:
              setAmbientKey(c.key());
              c.status.measurement.forEach(um => {
                let measurement = UnitMeasurement.any(um, user);
                if (measurement.type === quack.MeasurementType.MEASUREMENT_TYPE_TEMPERATURE) {
                  if (measurement.values.length > 1 && measurement.values[0].values.length > 0) {
                    setDensityTemp(measurement.values[0].values[0]);
                  }
                }
              });
              break;
            case pond.GateComponentType.GATE_COMPONENT_TYPE_TEMP:
              setTempKey(c.key());
              break;
            case pond.GateComponentType.GATE_COMPONENT_TYPE_PRESSURE:
              setPressureKey(c.key());
              if (
                c.status.measurement[0] &&
                c.status.measurement[0].values[0] &&
                c.status.measurement[0].values[0].values[1]
              ) {
                setPCAFanOn(c.status.measurement[0].values[0].values[1] > 250); //apx 1 iwg
              }
              break;
            default:
              // type is unknown, do nothing
              break;
          }
        }
      });
      setComponentOptions(components);
    }
  }, [comprehensiveDevice, gate, linkedCompList, user]);

  const gateComponentUpdate = (componentKey: string, gateCompType: pond.GateComponentType) => {
    if (componentKey !== "") {
      gateAPI
        .updatePrefs(
          gate.key,
          "component",
          device.id() + ":" + componentKey,
          gateCompType,
          [gate.key],
          ["gate"],
          as
        )
        .then(resp => {
          openSnack("Component Prefence Updated");
        });
    }
  };

  useEffect(() => {
    let tempComponent = componentOptions.get(tempKey);
    let t1 = 0;
    let t2 = 0;
    if (tempComponent) {
      tempComponent.status.measurement.forEach(um => {
        let measurement = UnitMeasurement.any(um, user);
        if (
          measurement.type === quack.MeasurementType.MEASUREMENT_TYPE_TEMPERATURE &&
          measurement.values.length > 0
        ) {
          let nodeVals = measurement.values[0].values;
          if (nodeVals.length > 1) {
            t1 = nodeVals[0]; //uses the first node
            t2 = nodeVals[1]; //uses second node node
          }
        }
      });
    }
    setLastTemps({ t1, t2 });
  }, [componentOptions, tempKey, user]);

  useEffect(() => {
    let ambientComponent = componentOptions.get(ambientKey);
    let temp = 0;
    if (ambientComponent) {
      ambientComponent.status.measurement.forEach(um => {
        let measurement = UnitMeasurement.any(um, user);
        if (measurement.type === quack.MeasurementType.MEASUREMENT_TYPE_TEMPERATURE) {
          if (measurement.values.length > 0 && measurement.values[0].values.length > 0) {
            temp = measurement.values[0].values[0];
          }
        }
      });
    }
    setLastAmbient(temp);
  }, [componentOptions, ambientKey, user]);

  useEffect(() => {
    let pressureComponent = componentOptions.get(pressureKey);
    let p1 = 0;
    let p2 = 0;
    if (pressureComponent) {
      pressureComponent.status.measurement.forEach(um => {
        let measurement = UnitMeasurement.any(um, user);
        if (
          measurement.type === quack.MeasurementType.MEASUREMENT_TYPE_PRESSURE &&
          measurement.values.length > 0
        ) {
          let nodeVals = measurement.values[0].values;
          if (nodeVals.length > 1) {
            p1 = nodeVals[0];
            p2 = nodeVals[1];
          }
        }
      });
    }
    setLastPressures({ p1, p2 });
  }, [componentOptions, pressureKey, user]);

  const ambientSelector = () => {
    return (
      <Select
        id="ambientSelect"
        variant="standard"
        value={ambientKey}
        style={{ fontSize: 8 }}
        onChange={e => {
          var key = e.target.value as string;
          gateComponentUpdate(key, pond.GateComponentType.GATE_COMPONENT_TYPE_AMBIENT);
          setAmbientKey(key);
          if (tempKey === key) {
            setTempKey("");
          }
          if (pressureKey === key) {
            setPressureKey("");
          }
        }}
        displayEmpty>
        <MenuItem value="">
          <em>Select Ambient Sensor</em>
        </MenuItem>
        {Array.from(componentOptions.values()).map(c => {
          return (
            <MenuItem key={c.key()} value={c.key()}>
              {c.name()}
            </MenuItem>
          );
        })}
      </Select>
    );
  };

  const tempSelector = () => {
    return (
      <Select
        id="tempSelect"
        variant="standard"
        value={tempKey}
        style={{ fontSize: 8 }}
        onChange={e => {
          gateComponentUpdate(
            e.target.value as string,
            pond.GateComponentType.GATE_COMPONENT_TYPE_TEMP
          );
          setTempKey(e.target.value as string);
          if (pressureKey === e.target.value) {
            setPressureKey("");
          }
          if (ambientKey === e.target.value) {
            setAmbientKey("");
          }
        }}
        displayEmpty>
        <MenuItem value="">
          <em>Select Temperature Chain</em>
        </MenuItem>
        {Array.from(componentOptions.values()).map(c => {
          return (
            <MenuItem key={c.key()} value={c.key()}>
              {c.name()}
            </MenuItem>
          );
        })}
      </Select>
    );
  };

  const pressureSelector = () => {
    return (
      <Select
        id="pressureSelect"
        variant="standard"
        value={pressureKey}
        style={{ fontSize: 8 }}
        onChange={e => {
          gateComponentUpdate(
            e.target.value as string,
            pond.GateComponentType.GATE_COMPONENT_TYPE_PRESSURE
          );
          setPressureKey(e.target.value as string);
          if (tempKey === e.target.value) {
            setTempKey("");
          }
          if (ambientKey === e.target.value) {
            setAmbientKey("");
          }
        }}
        displayEmpty>
        <MenuItem value="">
          <em>Select Pressure Chain</em>
        </MenuItem>
        {Array.from(componentOptions.values()).map(c => {
          return (
            <MenuItem key={c.key()} value={c.key()}>
              {c.name()}
            </MenuItem>
          );
        })}
      </Select>
    );
  };

  return (
    <Grid
      container
      direction="row"
      alignContent="center"
      width="100%"
      //alignItems="center"
      >
      <Grid size={{ sm: 12, lg: isMobile || drawerView ? 12 : 4}} style={{ padding: 10 }}>
        <Box
          paddingLeft={1}
          display="flex"
          justifyContent="space-between"
          alignItems="center"
          marginBottom={2}>
          <Typography style={{ fontWeight: 650, fontSize: 20 }}>{device.name()}</Typography>
          <ButtonGroup 
            toggle
            buttons={[
              {
                title: "Analysis",
                function: () => setDetail("analytics")
              },
              {
                title: "Sensors",
                function: () => setDetail("sensors")
              }
            ]}
          />
          {/* <ToggleButtonGroup value={detail} exclusive size="small" aria-label="detail">
            <ToggleButton
              onClick={() => setDetail("analytics")}
              value={"analytics"}
              aria-label="Analysis Graphs">
              Analysis
            </ToggleButton>
            <ToggleButton
              onClick={() => setDetail("sensors")}
              value={"sensors"}
              aria-label="Sensor Graphs">
              Sensors
            </ToggleButton>
          </ToggleButtonGroup> */}
        </Box>
        <Card raised>
          <GateSVG
            finalTemp={
              gate.gateMutations[device.id().toString()] &&
              !isNaN(gate.gateMutations[device.id().toString()].temp)
                ? gate.gateMutations[device.id().toString()].temp
                : 0
            }
            ambientTemp={lastAmbient}
            innerTemps={lastTemps}
            innerPressures={lastPressures}
            ambientSelector={ambientSelector}
            tempChainSelector={tempSelector}
            pressureChainSelector={pressureSelector}
            pcaState={pcaState}
            pcaFanState={pcaFanOn}
            checkInTime={device.status.lastActive}
          />
          <Button
            variant="contained"
            color="primary"
            fullWidth
            onClick={() => {
              setInteractionDialog(true);
            }}>
            Set Interactions
          </Button>
        </Card>
        <GateDeviceInteraction
          open={interactionDialog}
          gate={gate}
          compDevice={comprehensiveDevice}
          densityTemp={densityTemp}
          close={canceled => {
            setInteractionDialog(false);
          }}
        />
      </Grid>
      <Grid size={{ sm: 12, lg: isMobile || drawerView ? 12 : 8}} style={{ padding: 10 }}>
        <GateGraphs
          gate={gate}
          display={detail}
          compMap={componentOptions}
          setPCAState={(state: boolean) => {
            setPCAState(state);
          }}
          ambient={ambientKey}
          pressure={pressureKey}
          device={device.id()}
        />
      </Grid>
    </Grid>
  );
}
