import {
  Box,
  IconButton,
  Theme,
  Grid2 as Grid,
  DialogTitle,
  DialogContent,
  DialogContentText,
  DialogActions,
  Button,
  Tooltip,
  Drawer,
  Menu,
  MenuItem,
  ListItemIcon,
  ListItemText,
  Tab,
  Tabs,
  Card,
  Accordion,
  AccordionSummary,
  AccordionDetails,
  Typography,
} from "@mui/material";
import BinActions from "bin/BinActions";
import BinHistory from "bin/BinHistory";
import { useComponentAPI, useMobile } from "hooks";
import { Bin as IBin, binScope } from "models";
import { pond, quack } from "protobuf-ts/pond";
import { useBinAPI, useGlobalState } from "providers";
import React, { useCallback, useEffect, useRef, useState } from "react";
import PageContainer from "./PageContainer";
import { Component, Device, Interaction } from "models";
import BinLightIcon from "assets/products/bindapt/binLight.png";
import BinDarkIcon from "assets/products/bindapt/binDark.png";
import NotesIcon from "@mui/icons-material/Notes";
import ResponsiveDialog from "common/ResponsiveDialog";
import ObjectTeams from "teams/ObjectTeams";
import BindaptIcon from "products/Bindapt/BindaptIcon";
import Close from "@mui/icons-material/Close";
import Chat from "chat/Chat";
import TasksIcon from "products/Construction/TasksIcon";
import FieldsIcon from "products/AgIcons/FieldsIcon";
import BinComponentTypes from "bin/BinComponentTypes";
import { Plenum } from "models/Plenum";
import { GrainCable } from "models/GrainCable";
// import { Controller } from "models/Controller";
import { Pressure } from "models/Pressure";
import { CheckCircle, ExpandMore, Warning } from "@mui/icons-material";
import BinGraphs from "bin/graphs/BinGraphs";
import BinTour from "bin/BinTour";
import { getBinModel } from "common/DataImports/BinCables/BinCableImporter";
import DevicePresetController from "device/presets/devicePresetController";
import { DevicePreset } from "models/DevicePreset";
import BinVisualizerV2 from "bin/BinVisualizerV2";
import { Ambient } from "models/Ambient";
import moment from "moment";
import BinStorageConditions from "bin/BinStorageConditions";
import BinConditioningCard from "bin/BinConditioningCard";
import { makeStyles } from "@mui/styles";
import { useNavigate, useParams } from "react-router-dom";
import { Controller } from "models/Controller";
import TaskViewer from "tasks/TaskViewer";
import ButtonGroup from "common/ButtonGroup";
import BinTransactions from "bin/BinTransactions";
import { CO2 } from "models/CO2";
import ObjectInteractions from "objects/objectInteractions/ObjectInteractions";

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((theme: Theme) => {
  const themeType = theme.palette.mode;
  const activeBG = theme.palette.secondary.main;
  return ({
    cardContent: {
      padding: theme.spacing(1),
      height: "100%",
      display: "flex",
      flexDirection: "column",
      flexGrow: 1
    },
    boxContent: {
      display: "flex",
      flexDirection: "column",
      flexGrow: 2
    },
    img: {
      height: "28px",
      width: "auto !important",
      margin: "auto"
    },
    spacer: {
      width: "32px",
      height: "32px",
      padding: "auto",
      display: "flex",
      justifyContent: "center",
      alignItems: "center"
    },
    icon: {
      border: "1px solid grey",
      marginBottom: "0.75rem",
      marginRight: "0.5rem"
    },
    avatar: {
      color: themeType === "light" ? theme.palette.common.black : theme.palette.common.white,
      backgroundColor: "transparent",
      width: theme.spacing(5),
      height: theme.spacing(5),
      border: "1px solid",
      borderColor: theme.palette.divider
    },
    active: {
      color: theme.palette.getContrastText(activeBG),
      backgroundColor: "gold",
      width: theme.spacing(5),
      height: theme.spacing(5),
      border: 0,
      "&:hover": {
        backgroundColor: "gold"
      }
    },
    customIcon: {
      padding: theme.spacing(0.5)
    },
    drawerPaper: {
      height: "100%",
      width: "30%"
    },
    menuPaper: {
      borderRadius: "20px"
    },
    tab: {}
  });
});

interface Props {
  binKey?: string;
  displayMobile?: boolean;
  fromMap?: boolean;
}

export default function Bin(props: Props) {
  const { binKey, displayMobile, fromMap } = props;
  const warningThreshold = 6;
  const isMobile = useMobile();
  const classes = useStyles();
  // const match = useRouteMatch<MatchParams>();
  // const binID = binKey ?? match.params.binID;
  const binID = binKey ?? useParams<{ binID: string }>()?.binID ?? "";
  const binAPI = useBinAPI();
  const [{ user, as }] = useGlobalState();
  const [binLoading, setBinLoading] = useState(false);
  const loadRef = useRef<boolean>(false);
  const [bin, setBin] = useState<IBin>(IBin.create());
  const [tab, setTab] = useState<String>("Bin");
  const [value, setValue] = React.useState(0);
  const [devices, setDevices] = useState<Device[]>([]);
  const [components, setComponents] = useState<Map<string, Component>>(new Map());
  const [interactions, setInteractions] = useState<Interaction[]>([]);
  const [plenumError, setPlenumError] = useState<boolean>(false);
  const [teamDialog, setTeamDialog] = useState<boolean>(false);
  // const history = useHistory();
  const navigate = useNavigate()
  const [noteDrawer, setNoteDrawer] = useState(false);
  const [taskDrawer, setTaskDrawer] = useState(false);
  const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
  const [permissions, setPermissions] = useState<pond.Permission[]>([]);
  const [preferences, setPreferences] = useState<Map<string, pond.BinComponentPreferences>>();
  const [plenums, setPlenums] = useState<Plenum[]>([]);
  const [ambients, setAmbients] = useState<Ambient[]>([]);
  const [grainCables, setGrainCables] = useState<GrainCable[]>([]);
  const [pressures, setPressures] = useState<Pressure[]>([]);
  const [headspaceCO2, setHeadspaceCO2] = useState<CO2[]>([]);
  const [heaters, setHeaters] = useState<Controller[]>([]);
  const [fans, setFans] = useState<Controller[]>([]);
  const [activeDetails, setActiveDetails] = useState([0])
  const [detail, setDetail] = useState<
    "inventory" | "sensors" | "analytics" | "presets" | "alerts" | "transactions"
  >("inventory");
  const [mobileTab, setMobileTab] = useState(0);
  const componentAPI = useComponentAPI();
  const [{ showErrors }] = useGlobalState();
  const [compositionNameMap, setCompositionNameMap] = useState<Map<string, string>>(new Map());

  const [componentDevices, setComponentDevices] = useState<Map<string, number>>(
    new Map<string, number>()
  );
  const [interactionDevices, setInteractionDevices] = useState<Map<string, number>>(
    new Map<string, number>()
  );
  const [binPresets, setBinPresets] = useState<DevicePreset[]>([]);
  const [missedReadings, setMissedReadings] = useState(0);

  const handleChange = (_event: React.ChangeEvent<{}>, newValue: number) => {
    setValue(newValue);
  };

  const load = useCallback(() => {
    if (loadRef.current || user.id() === "") return;
    setBinLoading(true);
    loadRef.current = true;
    //add the presets to the bin page data load
    binAPI
      .getBinPageData(binID, user.id(), showErrors, as)
      .then(resp => {
        if (resp.data.grainCompositionNames) {
          let tempMap: Map<string, string> = new Map();
          Object.keys(resp.data.grainCompositionNames).forEach(key => {
            tempMap.set(key, resp.data.grainCompositionNames[key]);
          });
          tempMap.set("correction", "Unknown Source");
          setCompositionNameMap(tempMap);
        }

        let devs: Device[] = [];
        let p = new Map<string, pond.BinComponentPreferences>();
        Object.keys(resp.data.preferences).forEach(k => {
          let prefKey = k.split(":")[1] ? k.split(":")[1] : k;
          p.set(prefKey, pond.BinComponentPreferences.fromObject(resp.data.preferences[k]));
        });
        setPreferences(p);
        let r: pond.GetBinPageDataResponse = pond.GetBinPageDataResponse.fromObject(resp.data);
        setBin(IBin.any(resp.data.bin));
        let newComponentDevices = new Map<string, number>();
        let attachedDevIds: number[] = [];
        if (resp.data.componentDevices)
          Object.keys(resp.data.componentDevices).forEach(k => {
            newComponentDevices.set(k, resp.data.componentDevices[k]);
            //make a list of all of the ids for devices that components are currently attached
            if (!attachedDevIds.includes(resp.data.componentDevices[k])) {
              attachedDevIds.push(resp.data.componentDevices[k]);
            }
          });
        setComponentDevices(newComponentDevices);

        let newInteractionDevices = new Map<string, number>();
        if (r.interactionDevices)
          Object.keys(r.interactionDevices).forEach(k => {
            newInteractionDevices.set(k, r.interactionDevices[k]);
          });
        setInteractionDevices(newInteractionDevices);

        if (resp.data.interactions) {
          setInteractions(resp.data.interactions.map((i: pond.Interaction) => Interaction.any(i)));
        } else {
          setInteractions([]);
        }
        //go through the devices and if the device has an attached component include it in the device list
        if (resp.data.devices && resp.data.devices[0]) {
          resp.data.devices.forEach((dev: any) => {
            let device = Device.create(dev);
            if (attachedDevIds.includes(device.id())) {
              devs.push(Device.create(dev));
            }
          });
          setDevices(devs);
        }
        if (resp.data.components) {
          let compMap: Map<string, Component> = new Map();
          resp.data.components.forEach((comp: pond.Component) => {
            if (comp && comp.settings) {
              let c = Component.any(comp);
              compMap.set(comp.settings.key, c);
            }
          });
          setComponents(compMap);
        }
        if (resp.data.presets) {
          setBinPresets(
            resp.data.presets.map((preset: pond.DevicePreset) => DevicePreset.create(preset))
          );
        }
        setPermissions(r.permissions ? r.permissions : []);
        setBinLoading(false);
        loadRef.current = false;
      })
      .finally(() => {
        setBinLoading(false);
        loadRef.current = false;
      });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [binID, user.id(), binAPI, showErrors, as]);

  useEffect(() => {
    load();
  }, [load]);

  const setBinComponents = useCallback(() => {
    if (!preferences) return;
    var unassigned: Component[] = [];
    var plenums: Plenum[] = [];
    var ambients: Ambient[] = [];
    var grainCables: GrainCable[] = [];
    var fans: Controller[] = [];
    var heaters: Controller[] = [];
    var pressures: Pressure[] = [];
    var headspaceCo2: CO2[] = [];
    var mostMissed: number = 0;
    let now = moment();

    components.forEach(comp => {
      let pref = preferences.get(comp.key());
      if (pref) {
        if (pref.type) {
          if (pref.type === pond.BinComponent.BIN_COMPONENT_PLENUM)
            plenums.push(Plenum.create(comp));
          if (pref.type === pond.BinComponent.BIN_COMPONENT_AMBIENT)
            ambients.push(Ambient.create(comp));
          if (pref.type === pond.BinComponent.BIN_COMPONENT_GRAIN_CABLE) {
            //check cable for missed measurements
            let cable = GrainCable.create(comp);
            let lastRead = moment(cable.lastReading);
            let elapsedMS = now.diff(lastRead);
            if (elapsedMS > cable.settings.measurementPeriodMs) {
              let missedReadings = Math.floor(elapsedMS / cable.settings.measurementPeriodMs);
              if (missedReadings > mostMissed) {
                mostMissed = missedReadings;
              }
            }
            grainCables.push(cable);
          }
          if (pref.type === pond.BinComponent.BIN_COMPONENT_HEATER)
            heaters.push(Controller.create(comp));
          if (pref.type === pond.BinComponent.BIN_COMPONENT_FAN) fans.push(Controller.create(comp));
          if (pref.type === pond.BinComponent.BIN_COMPONENT_PRESSURE)
            pressures.push(Pressure.create(comp));
          if (pref.type === pond.BinComponent.BIN_COMPONENT_HEADSPACE) {
            if (comp.type() === quack.ComponentType.COMPONENT_TYPE_CO2) {
              //check if there are missed readings from the co2 and compare them to what we already had
              let coComp = CO2.create(comp)
              let lastRead = moment(coComp.lastReading);
              let elapsedMS = now.diff(lastRead);
              if (elapsedMS > coComp.settings.measurementPeriodMs) {
                let missedReadings = Math.floor(elapsedMS / coComp.settings.measurementPeriodMs);
                if (missedReadings > mostMissed) {
                  mostMissed = missedReadings;
                }
              }
              headspaceCo2.push(coComp);
            }
          }
        } else {
          unassigned.push(comp);
        }
      }
    });
    setMissedReadings(mostMissed);
    setPlenums(plenums);
    setGrainCables(grainCables);
    setPressures(pressures);
    setAmbients(ambients);
    setHeaters(heaters);
    setFans(fans);
    setHeadspaceCO2(headspaceCo2);
  }, [components, preferences]);

  const reLoadSingleComponent = (componentKey: string) => {
    let dev = componentDevices.get(componentKey);
    if (dev) {
      componentAPI.get(dev, componentKey, undefined, undefined, as).then(resp => {
        let compMap = components;
        let comp = Component.any(resp.data);
        compMap.set(comp.key(), comp);
        setComponents(compMap);
        setBinComponents();
      });
    }
  };

  useEffect(() => {
    setBinComponents();
  }, [setBinComponents]);

  const showPlenumError = () => {
    return (
      <ResponsiveDialog open={plenumError} onClose={() => setPlenumError(false)}>
        <DialogContent>
          <DialogTitle>No Plenum Sensor Detected</DialogTitle>
          <DialogContentText>
            Cooldown and drying mode both require a plenum sensor measuring the temperature and
            humidity of the air entering the bin. If you would like to change device interactions
            manually, you will have to do so in the device page.
          </DialogContentText>
          <DialogActions>
            <Button onClick={() => setPlenumError(false)} color="primary">
              Close
            </Button>
          </DialogActions>
        </DialogContent>
      </ResponsiveDialog>
    );
  };

  // const changeBinMode = (newBinMode: pond.BinMode) => {
  //   const fallback = bin.settings.mode;
  //   let updatedBin = bin;
  //   let hasPlenum = false;

  //   // If we aren't doing storage mode, make sure it has a plenum
  //   hasPlenum = plenums.length > 0;

  //   if (hasPlenum || newBinMode === pond.BinMode.BIN_MODE_STORAGE) {
  //     updatedBin.settings.mode = newBinMode;
  //     binAPI
  //       .updateBin(bin.key(), updatedBin.settings)
  //       .then(() => {
  //         openSnack("Bin Mode was successfully updated");
  //       })
  //       .catch(() => {
  //         updatedBin.settings.mode = fallback;
  //         openSnack("Error occurred while changing Bin Mode");
  //       })
  //       .finally(() => {
  //         refresh();
  //       });
  //   } else {
  //     updatedBin.settings.mode = pond.BinMode.BIN_MODE_STORAGE;
  //     setPlenumError(true);
  //     return false;
  //   }
  //   return true;
  // };

  const refresh = (_showSnack?: boolean) => {
    // binAPI.getBin(bin.key()).then(resp => {
    //   let bin = IBin.any(resp.data);
    //   setBin(bin);
    //   if (showSnack) {
    //     openSnack("Bin data refreshed");
    //   }
    // });
    load();
  };

  const switchToTab = (to: String) => {
    setTab(to);
  };

  const showBin = () => {
    if ((isMobile || displayMobile) && tab !== "Bin") {
      return false;
    }
    return true;
  };

  const showNotes = () => {
    if ((isMobile || displayMobile) && tab !== "Notes") {
      return false;
    }
    return true;
  };

  const showTasks = () => {
    if ((isMobile || displayMobile) && tab !== "Tasks") {
      return false;
    }
    return true;
  };

  const notesAndHistory = (drawer?: boolean) => {
    if (showNotes()) {
      return (
        <React.Fragment>
          <Tabs
            value={value}
            indicatorColor="primary"
            textColor="primary"
            onChange={handleChange}
            aria-label="disabled tabs example"
            centered={!(isMobile || displayMobile)}
            style={{
              marginLeft: isMobile || displayMobile || drawer ? "auto" : "none"
              //marginTop: isMobile || displayMobile || drawer ? "-3rem" : "0.25rem"
            }}>
            <Tab label="Notes" />
            <Tab label="History" />
          </Tabs>
          <TabPanelMine value={value} index={0}>
            <Box height={isMobile || displayMobile ? "80vh" : "90vh"} padding={2}>
              <Chat parent={binID} parentType={"bin"} type={pond.NoteType.NOTE_TYPE_BIN} />
            </Box>
          </TabPanelMine>
          <TabPanelMine value={value} index={1}>
            <BinHistory drawer={drawer} binID={binID} />
          </TabPanelMine>
        </React.Fragment>
      );
    }
    return null;
  };

  const tasks = () => {
    if (showTasks()) {
      return (
        <React.Fragment>
          <TaskViewer drawerView objectKey={binID} loadKeys={[binID]} />
        </React.Fragment>
      );
    }
    return null;
  };

  const goToDevice = (dev: Device) => {
    if (fromMap) {
      navigate("/bins/" + binID + "/devices/" + dev.id(), { replace: true });
    } else {
      navigate(window.location.pathname + "/devices/" + dev.id(), { replace: true });
    }
  };

  const goToYard = (bin: IBin) => {
    navigate("/visualFarm", { state: {
        long: bin.getLocation()?.longitude,
        lat: bin.getLocation()?.latitude
      }
    });
  };

  const deviceMenu = () => {
    return (
      <Menu
        id="groupMenu"
        anchorEl={anchorEl}
        open={Boolean(anchorEl)}
        onClose={() => setAnchorEl(null)}
        keepMounted
        classes={{ paper: classes.menuPaper }}
        disableAutoFocusItem>
        {devices.map(dev => (
          <MenuItem key={dev.id()} onClick={() => goToDevice(dev)}>
            <ListItemIcon>
              <BindaptIcon />
            </ListItemIcon>
            <ListItemText primary={dev.name()} />
          </MenuItem>
        ))}
      </Menu>
    );
  };

  const tabs = () => {
    return (
      <Box marginTop={1} marginBottom={1}>
        <Grid
          container
          direction="row"
          justifyContent="space-between"
          alignContent="center"
          alignItems="center">
          <Grid >
            <IconButton
              onClick={() => switchToTab("Bin")}
              size="small"
              style={{
                marginRight: "0.5rem"
              }}
              component="span"
              className={tab === "Bin" ? classes.active : classes.avatar}>
              <div className={classes.spacer}>
                <img
                  className={classes.img}
                  src={tab !== "Bin" ? BinLightIcon : BinDarkIcon}
                  alt="icon"
                />
              </div>
            </IconButton>
            <IconButton
              onClick={() =>
                isMobile || displayMobile ? switchToTab("Notes") : setNoteDrawer(true)
              }
              size="small"
              style={{
                marginRight: "0.5rem"
              }}
              className={tab === "Notes" ? classes.active : classes.avatar}
              component="span">
              <div className={classes.spacer}>
                <NotesIcon />
              </div>
            </IconButton>
            <IconButton
              onClick={() =>
                isMobile || displayMobile ? switchToTab("Tasks") : setTaskDrawer(true)
              }
              size="small"
              style={{
                marginRight: "0.5rem"
              }}
              className={tab === "Tasks" ? classes.active : classes.avatar}
              component="span">
              <div className={classes.spacer}>
                <TasksIcon type={tab === "Tasks" ? "dark" : "light"} />
              </div>
            </IconButton>
            {devices.length > 1 ? (
              <Tooltip key="devices" title="devices">
                <IconButton
                  key="devButton"
                  onClick={(event: React.MouseEvent<HTMLButtonElement>) =>
                    setAnchorEl(event.currentTarget)
                  }
                  size="small"
                  style={{
                    marginRight: "0.5rem"
                  }}
                  className={classes.avatar}
                  component="span">
                  <BindaptIcon />
                </IconButton>
              </Tooltip>
            ) : (
              devices.map(dev => (
                <Tooltip key={dev.id()} title={dev.name()}>
                  <IconButton
                    key={dev.id()}
                    onClick={() => goToDevice(dev)}
                    size="small"
                    style={{
                      marginRight: "0.5rem"
                    }}
                    className={classes.avatar}
                    component="span">
                    <div className={classes.spacer}>
                      <BindaptIcon />
                    </div>
                  </IconButton>
                </Tooltip>
              ))
            )}
            {bin.binMapped() && !fromMap && (
              <Tooltip key={"goToMap"} title={"Go to Yard"}>
                <IconButton
                  onClick={() => {
                    goToYard(bin);
                  }}
                  size="small"
                  style={{
                    marginRight: "0.5rem"
                  }}
                  className={classes.avatar}
                  component="span">
                  <FieldsIcon />
                </IconButton>
              </Tooltip>
            )}
          </Grid>
          {tab === "Bin" && (
            <Grid>
              <BinActions
                bin={bin}
                permissions={permissions}
                refreshCallback={() => {
                  load();
                }}
                userID={user.id()}
                components={components}
                setComponents={setComponents}
                updateBinStatus={updateStatus}
              />
            </Grid>
          )}
        </Grid>
      </Box>
    );
  };

  const overview = () => {
    return (
      <BinVisualizerV2
        plenums={plenums}
        pressures={pressures}
        ambient={ambients[0]}
        cables={grainCables}
        bin={bin}
        loading={binLoading}
        components={components}
        componentDevices={componentDevices}
        devices={devices}
        afterUpdate={refresh}
        refresh={refresh}
        preferences={preferences}
        permissions={permissions}
        updateComponentCallback={componentKey => {
          reLoadSingleComponent(componentKey);
        }}
        binPresets={binPresets}
      />
    );
  };

  const blank = () => {
    return true;
  };

  const objectTeams = () => {
    let scope = binScope(binID);
    return (
      <ObjectTeams
        scope={scope}
        label="Teams"
        permissions={permissions}
        isDialogOpen={teamDialog}
        refreshCallback={blank}
        closeDialogCallback={() => setTeamDialog(false)}
      />
    );
  };

  const updateStatus = (componentKeys: string[], removed?: boolean) => {
    componentKeys.forEach(compKey => {
      let comp = components.get(compKey);
      if (comp) {
        //determine what part of the status to update based on the component
        //for lidar
        if (comp.type() === quack.ComponentType.COMPONENT_TYPE_LIDAR) {
          //determine how to update the status based on if added or removed
          if (removed) {
            bin.status.distance = 0;
          } else {
            if (
              comp.lastMeasurement[0] &&
              comp.lastMeasurement[0].values[0] &&
              comp.lastMeasurement[0].values[0].values[0]
            ) {
              bin.status.distance = comp.lastMeasurement[0].values[0].values[0];
            }
          }
        }
      }
    });
    //update the bins status with the new values based on the components changed
    binAPI.updateBinStatus(bin.key(), bin.status, as);
  };

  const binComponents = (preferences: Map<string, pond.BinComponentPreferences>) => {
    return (
      <Card raised style={{ marginTop: 15 }}>
        <Accordion elevation={0}>
          <AccordionSummary expandIcon={<ExpandMore />}>
            <Typography style={{ fontWeight: 650 }}>Bin Components</Typography>
          </AccordionSummary>
          <AccordionDetails>
            <BinComponentTypes
              bin={bin.key()}
              updateBinStatus={updateStatus}
              components={components}
              setComponents={setComponents}
              preferences={preferences}
              setPreferences={setPreferences}
            />
          </AccordionDetails>
        </Accordion>
      </Card>
    );
  };

  const desktopView = () => {
    return (
      <Card sx={{ padding: 1 }}>
        <Grid container spacing={2} direction={"row"} justifyContent="center" alignItems="stretch">
          <Grid size={{ xs: 12, sm: 12, md: 12, lg: 4 }}>
            <Box
              paddingX={1}
              marginBottom={1}
              display="flex"
              alignItems="center"
              justifyContent="space-between"
              style={{ background: "gold", borderRadius: 25 }}>
              <Box display="flex" alignItems="center">
                <Typography style={{ fontWeight: 650, fontSize: 20, color: "black" }}>
                  {bin.name()}
                </Typography>
                <Typography variant="subtitle2" style={{ paddingLeft: 5, color: "black" }}>
                  {" - " +
                    (bin.settings.specs?.modelId
                      ? getBinModel(bin.settings.specs.modelId)?.Manufacturer +
                        " " +
                        getBinModel(bin.settings.specs.modelId)?.Model
                      : "Custom")}
                </Typography>
              </Box>
              <Box>{componentState()}</Box>
            </Box>
            {overview()}
            {preferences && binComponents(preferences)}
          </Grid>
          <Grid id="tour-conditions" size={{ xs: 12, sm: 12, md: 12, lg: 2.6 }}>
            {(bin.settings.mode === pond.BinMode.BIN_MODE_DRYING ||
              bin.settings.mode === pond.BinMode.BIN_MODE_HYDRATING ||
              bin.settings.mode === pond.BinMode.BIN_MODE_COOLDOWN) && (
              <BinConditioningCard
                mode={bin.settings.mode}
                interactions={interactions}
                interactionDevices={interactionDevices}
                plenums={plenums}
                ambients={ambients}
                fans={fans}
                heaters={heaters}
                grain={bin.grain()}
                customGrain={bin.customGrain()}
              />
            )}
            <Box marginTop={2}>
              <BinStorageConditions bin={bin} headspaceCO2={headspaceCO2} cables={grainCables} />
            </Box>
          </Grid>
          <Grid id="tour-details" size={{ xs: 12, sm: 12, md: 12, lg: 5.3 }}>
            <Box id="tour-graph-tabs" paddingBottom={2} display="flex">
              <ButtonGroup
                toggle
                toggledButtons={activeDetails}
                buttons={[
                  {
                    title: "Inventory",
                    function: () => {
                      setDetail("inventory")
                      setActiveDetails([0])
                    }
                  },
                  {
                    title: "Sensors",
                    function: () => {
                      setDetail("sensors")
                      setActiveDetails([1])
                    }
                  },
                  {
                    title: "Analysis",
                    function: () => {
                      setDetail("analytics")
                      setActiveDetails([2])
                    }
                  },
                  {
                    title: "Alerts",
                    function: () => {
                      setDetail("alerts")
                      setActiveDetails([3])
                    }
                  },
                  {
                    title: "Presets",
                    function: () => {
                      setDetail("presets")
                      setActiveDetails([4])
                    }
                  },
                  {
                    title: "Transactions",
                    function: () => {
                      setDetail("transactions")
                      setActiveDetails([5])
                    }
                  }
                ]}
              />
            </Box>
            {detail === "alerts" && (
              <Box>
                <ObjectInteractions
                  linkedComponents={components}
                  componentDevices={componentDevices}
                  devices={devices}
                  objectKey={bin.key()}
                  objectType={pond.ObjectType.OBJECT_TYPE_BIN}
                  permissions={permissions}
                />
              </Box>
            )}
            {detail === "presets" && (
              <Box>
                <DevicePresetController
                  objectKey={bin.key()}
                  objectType={pond.ObjectType.OBJECT_TYPE_BIN}
                  presets={binPresets}
                  refreshCallback={presets => {
                    setBinPresets(presets);
                  }}
                />
              </Box>
            )}
            {detail === "transactions" &&
            <Box>
              <BinTransactions bin={bin} permissions={permissions} refresh={refresh}/>
            </Box>
            }
            {(detail === "inventory" || detail === "sensors" || detail === "analytics") && (
              <Box>
                <BinGraphs
                  bin={bin}
                  binLoading={binLoading}
                  plenums={plenums}
                  cables={grainCables}
                  pressures={pressures}
                  fans={fans}
                  componentDevices={componentDevices}
                  display={detail}
                  compMap={components}
                  compositionNameMap={compositionNameMap}
                  />
              </Box>
            )}
          </Grid>
        </Grid>
      </Card>
    );
  };

  const mobileView = () => {
    return (
      <Card style={{ padding: 2, width: "100%" }}>
        <Tabs
          style={{ marginBottom: 5 }}
          value={mobileTab}
          indicatorColor="secondary"
          //textColor="secondary"
          onChange={(_, newVal) => {
            setMobileTab(newVal);
          }}
          aria-label="bin tabs"
          variant="scrollable"
          // scrollButtons="on"
        >
          <Tab
            classes={{ root: classes.tab }}
            label="Bin"
            style={{ fontWeight: mobileTab === 0 ? 650 : 500 }}
          />
          <Tab label="Inventory" style={{ fontWeight: mobileTab === 1 ? 650 : 500 }} />
          <Tab label="Sensors" style={{ fontWeight: mobileTab === 2 ? 650 : 500 }} />
          <Tab label="Analysis" style={{ fontWeight: mobileTab === 3 ? 650 : 500 }} />
          <Tab label="Alerts" style={{ fontWeight: mobileTab === 4 ? 650 : 500 }} />
          <Tab label="Presets" style={{ fontWeight: mobileTab === 5 ? 650 : 500 }} />
          <Tab label="Transactions" style={{ fontWeight: mobileTab === 6 ? 650 : 500 }} />
        </Tabs>
        <TabPanelMine value={mobileTab} index={0}>
          {overview()}
          {(bin.settings.mode === pond.BinMode.BIN_MODE_DRYING ||
            bin.settings.mode === pond.BinMode.BIN_MODE_HYDRATING) && (
            <Box style={{ marginTop: 15 }}>
              <BinConditioningCard
                mode={bin.settings.mode}
                interactions={interactions}
                interactionDevices={interactionDevices}
                plenums={plenums}
                ambients={ambients}
                fans={fans}
                heaters={heaters}
                grain={bin.grain()}
                customGrain={bin.customGrain()}
              />
            </Box>
          )}
          <Box style={{ marginTop: 15 }}>
            <BinStorageConditions bin={bin} headspaceCO2={headspaceCO2} cables={grainCables} />
          </Box>
          {preferences && binComponents(preferences)}
        </TabPanelMine>
        {/*TODO-CS need to find a better way to do this rather than have 3 seperate panels with the same thing */}
        <TabPanelMine value={mobileTab} index={1}>
          <BinGraphs
            bin={bin}
            binLoading={binLoading}
            plenums={plenums}
            cables={grainCables}
            pressures={pressures}
            fans={fans}
            componentDevices={componentDevices}
            display={"inventory"}
            compMap={components}
            compositionNameMap={compositionNameMap}
          />
        </TabPanelMine>
        <TabPanelMine value={mobileTab} index={2}>
          <BinGraphs
            bin={bin}
            binLoading={binLoading}
            plenums={plenums}
            cables={grainCables}
            pressures={pressures}
            fans={fans}
            componentDevices={componentDevices}
            display={"sensors"}
            compositionNameMap={compositionNameMap}
            compMap={components}
          />
        </TabPanelMine>
        <TabPanelMine value={mobileTab} index={3}>
          <BinGraphs
            bin={bin}
            binLoading={binLoading}
            plenums={plenums}
            cables={grainCables}
            pressures={pressures}
            fans={fans}
            componentDevices={componentDevices}
            display={"analytics"}
            compositionNameMap={compositionNameMap}
            compMap={components}
          />
        </TabPanelMine>
        <TabPanelMine value={mobileTab} index={4}>
          <Box>
            <ObjectInteractions
              linkedComponents={components}
              componentDevices={componentDevices}
              devices={devices}
              objectKey={bin.key()}
              objectType={pond.ObjectType.OBJECT_TYPE_BIN}
              permissions={permissions}
            />
          </Box>
        </TabPanelMine>
        <TabPanelMine value={mobileTab} index={5}>
          <DevicePresetController
            objectKey={bin.key()}
            objectType={pond.ObjectType.OBJECT_TYPE_BIN}
            presets={binPresets}
            refreshCallback={presets => {
              setBinPresets(presets);
            }}
          />
        </TabPanelMine>
        <TabPanelMine value={mobileTab} index={6}>
          <BinTransactions bin={bin} permissions={permissions} refresh={refresh}/>
        </TabPanelMine>
      </Card>
    );
  };

  const componentState = () => {
    const hasCables = grainCables.length > 0
    const hasCO2 = headspaceCO2.length > 0
    return (
      <Box display="flex" alignContent="center" alignItems="center">
        {hasCables || hasCO2 ?
          <React.Fragment>
            <Typography
              align="center"
              style={{
                marginRight: 10,
                fontWeight: 650,
                fontSize: 15,
                textAlign: "center",
                color: "black"
              }}>
              {missedReadings < 3
                ? "Active"
                : missedReadings <= warningThreshold
                ? "Missing"
                : "Inactive"}
            </Typography>
            {missedReadings < 3 ? (
              <CheckCircle style={{ color: "green" }} />
              ) : missedReadings <= warningThreshold ? (
                <Warning style={{ color: "yellow" }} />
                ) : (
                  <Warning style={{ color: "red" }} />
                )}
          </React.Fragment>
        :
          <Typography
          align="center"
          style={{
            marginRight: 10,
            fontWeight: 650,
            fontSize: 15,
            textAlign: "center",
            color: "black"
          }}>
            Unmonitored
          </Typography>
        }
      </Box>
    );
  };

  return (
    <PageContainer >
      {showPlenumError()}
      <Box
        paddingBottom={isMobile || displayMobile ? 1 : 2}
        paddingX={1}
      >
        {tabs()}
        {isMobile && (
          <Box
            paddingX={1}
            marginBottom={1}
            display="flex"
            alignItems="center"
            justifyContent="space-between"
            style={{ background: "gold", borderRadius: 25 }}>
            <Box display="flex" alignItems="center">
              <Typography style={{ fontWeight: 650, fontSize: 18, color: "black" }}>
                {bin.name()}
              </Typography>
              <Typography variant="subtitle2" style={{ paddingLeft: 5, color: "black" }}>
                {" - " +
                  (bin.settings.specs?.modelId
                    ? getBinModel(bin.settings.specs.modelId)?.Manufacturer +
                      " " +
                      getBinModel(bin.settings.specs.modelId)?.Model
                    : "Custom")}
              </Typography>
            </Box>
            <Box>{componentState()}</Box>
          </Box>
        )}
        <Grid container spacing={1} direction="column" justifyContent="center" alignItems="stretch">
          {showBin() && (isMobile || displayMobile ? mobileView() : desktopView())}
          {isMobile || displayMobile ? (
            notesAndHistory(displayMobile)
          ) : (
            <Drawer
              open={noteDrawer}
              anchor="right"
              classes={{ paper: classes.drawerPaper }}
              onClose={() => setNoteDrawer(false)}>
              <IconButton style={{ width: 50 }} onClick={() => setNoteDrawer(false)}>
                <Close />
              </IconButton>
              {notesAndHistory(true)}
            </Drawer>
          )}
          {isMobile || displayMobile ? (
            tasks()
          ) : (
            <Drawer
              BackdropProps={{ invisible: true }}
              style={{ zIndex: 1099 }}
              open={taskDrawer}
              anchor="right"
              classes={{ paper: classes.drawerPaper }}
              onClose={() => setTaskDrawer(false)}>
              <Box>
                <IconButton style={{ width: 50 }} onClick={() => setTaskDrawer(false)}>
                  <Close />
                </IconButton>
                <TaskViewer drawerView objectKey={binID} loadKeys={[binID]} />
              </Box>
            </Drawer>
          )}
        </Grid>
      </Box>
      {objectTeams()}
      {deviceMenu()}
      <BinTour 
        setDetailTabState={(detail, buttonIndex) => {
          setDetail(detail)
          setActiveDetails([buttonIndex])
        }}/>
    </PageContainer>
  );
}
