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 [greenLightKey, setGreenLightKey] = useState("");
  const [redLightKey, setRedLightKey] = 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 });

  useEffect(() => {
    //addresses of controller LEDs on a V1 device
    let redAddr = "3-1-512";
    let greenAddr = "3-1-1024";
    if (comprehensiveDevice.device) {
      setDevice(Device.any(comprehensiveDevice.device));

      //check if the device is a MiPCA V2 device since the lEDs will have different addresses
      let dev = Device.create(comprehensiveDevice.device);
      if (dev.settings.product === pond.DeviceProduct.DEVICE_PRODUCT_MIPCA_V2) {
        redAddr = "3-1-256";
        greenAddr = "3-1-512";
      }
    }
    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] > 996); //apx 4 iwg
              // }
              break;
            default:
              // type is unknown, do nothing
              break;
          }
        }
        if (c.locationString() === redAddr && c.subType() === 1) {
          setRedLightKey(c.key());
        } else if (c.locationString() === greenAddr && c.subType() === 1) {
          setGreenLightKey(c.key());
        }
      });
      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={(isMobile) ? "column" : "row"}
      width="100%"
      //alignItems="center"
      >
      <Grid width={"100%"} size={{ sm: 12, lg: isMobile || drawerView ? 12 : 4}} style={{ padding: 10 }}>
        <Box
          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")
              }
            ]}
          />
        </Box>
        <Card>
          <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={gate.status.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}
          tempChain={tempKey}
          redKey={redLightKey}
          greenKey={greenLightKey}
          device={device.id()}
        />
      </Grid>
    </Grid>
  );
}
