import {
  Avatar,
  Box,
  Button,
  Card,
  CardContent,
  Grid2 as Grid,
  ListItemAvatar,
  ListItemText,
  Theme,
  Typography,
  //useTheme
} from "@mui/material";
import { GetDefaultDateRange } from "common/time/DateRange";
import UnitMeasurementSummary from "component/UnitMeasurementSummary";
import { useThemeType } from "hooks";
import { Component, Device } from "models";
import { ObjectHeater } from "models/ObjectHeater";
import { UnitMeasurement } from "models/UnitMeasurement";
import moment from "moment";
import { GetComponentIcon } from "pbHelpers/ComponentType";
import ObjectHeaterIcon from "products/Construction/ObjectHeaterIcon";
import { pond, quack } from "protobuf-ts/pond";
import { useGlobalState, useMutationAPI } from "providers";
import React, { useEffect, useState } from "react";
import FuelDark from "assets/components/fuelDark.png";
import FuelLight from "assets/components/fuelLight.png";
//import { useHistory } from "react-router";
import { useNavigate } from "react-router-dom";
import Link from "@mui/icons-material/Link";
import EventBlocker from "common/EventBlocker";
import { GetDeviceProductIcon } from "products/DeviceProduct";
import { makeStyles } from "@mui/styles";

interface Props {
  heaterData: pond.ObjectHeaterData;
  linkDevice: (heater: ObjectHeater, linkedDevices: pond.ComprehensiveDevice[]) => void;
}

const useStyles = makeStyles((theme: Theme) => ({
    avatarIcon: {
      width: theme.spacing(3),
      height: theme.spacing(3)
    },
    listAvatar: {
      minWidth: theme.spacing(5)
    },
    avatarImage: {
      width: theme.spacing(3),
      height: theme.spacing(3)
    },
    textOverflow: {
      whiteSpace: "nowrap",
      overflow: "hidden",
      textOverflow: "ellipsis",
      textTransform: "capitalize"
    },
    listText: {
      margin: 0,
      height: "100%"
    }
  })
);

export default function ObjectHeaterCard(props: Props) {
  const { heaterData, linkDevice } = props;
  const [heater, setHeater] = useState<ObjectHeater>(ObjectHeater.create());
  const [connectedDevice, setConnectedDevice] = useState<Device>();
  const mutationAPI = useMutationAPI();
  const [heaterComponent, setHeaterComponent] = useState<Component>();
  const [heaterTempComponent, setHeaterTempComponent] = useState<Component>();
  const [siteTempComponent, setSiteTempComponent] = useState<Component>();
  const [mutationsLoading, setMutationsLoading] = useState(false);
  const classes = useStyles();
  const themeType = useThemeType();
  const [{ user }] = useGlobalState();
  const [lastFuelCalc, setLastFuelCalc] = useState<pond.ValueAt>();
  const [lastFuelMutation, setLastFuelMutation] = useState<pond.LinearMutation>();
  const [allComponentsRecent, setAllComponentsRecent] = useState(true);
  //const history = useHistory();
  const navigate = useNavigate();
  //const theme = useTheme();

  useEffect(() => {
    let heater = ObjectHeater.any(heaterData.heater);
    setHeater(heater);
    if (!mutationsLoading && heater) {
      let fuelMutation: pond.LinearMutation | undefined;
      heater.settings.mutations.forEach(mutation => {
        if (mutation.mutation === pond.Mutator.MUTATOR_FUEL_LEVEL) {
          fuelMutation = mutation;
        }
      });
      if (fuelMutation !== undefined) {
        mutationAPI
          .linearMutation(
            fuelMutation,
            GetDefaultDateRange()
              .end.add(-1, "hour")
              .toISOString(),
            GetDefaultDateRange().end.toISOString()
          )
          .then(resp => {
            resp.data.values.forEach(val => {
              setLastFuelCalc(val);
            });
            setLastFuelMutation(fuelMutation);
            setMutationsLoading(false);
          });
      }
    }
    if (heaterData.devices[0]) {
      setConnectedDevice(Device.any(heaterData.devices[0].device));
      heaterData.devices[0].components.forEach(c => {
        //loop through the components and assign them accordingly
        let component = Component.any(c);
        if (
          component.type() === quack.ComponentType.COMPONENT_TYPE_BOOLEAN_OUTPUT &&
          component.subType() === quack.BooleanOutputSubtype.BOOLEAN_OUTPUT_SUBTYPE_HEATER
        ) {
          setHeaterComponent(component);
          component.lastMeasurement.forEach(um => {
            if (
              um.timestamps.length > 0 &&
              um.type === quack.MeasurementType.MEASUREMENT_TYPE_BOOLEAN
            ) {
              if (
                moment().diff(moment(um.timestamps[0]), "milliseconds") >
                component.settings.reportPeriodMs
              ) {
                setAllComponentsRecent(false);
              }
            }
          });
        }
        if (component.type() === quack.ComponentType.COMPONENT_TYPE_TEMPERATURE) {
          setHeaterTempComponent(component);
          component.lastMeasurement.forEach(um => {
            if (
              um.timestamps.length > 0 &&
              um.type === quack.MeasurementType.MEASUREMENT_TYPE_TEMPERATURE
            ) {
              if (
                moment().diff(moment(um.timestamps[0]), "milliseconds") >
                component.settings.reportPeriodMs
              ) {
                setAllComponentsRecent(false);
              }
            }
          });
        }
        if (component.type() === quack.ComponentType.COMPONENT_TYPE_DHT) {
          setSiteTempComponent(component);
          component.lastMeasurement.forEach(um => {
            if (
              um.timestamps.length > 0 &&
              um.type === quack.MeasurementType.MEASUREMENT_TYPE_BOOLEAN
            ) {
              if (
                moment().diff(moment(um.timestamps[0]), "milliseconds") >
                component.settings.reportPeriodMs
              ) {
                setAllComponentsRecent(false);
              }
            }
          });
        }
      });
    }
  }, [heaterData, mutationAPI]); //eslint-disable-line react-hooks/exhaustive-deps

  const goToHeater = () => {
    //history.push("/objectHeaters/" + heater.key);
    let path = "/objectHeaters/" + heater.key;
    navigate(path, { state: {heater: heater} });
  };

  const componentDisplay = (component?: Component) => {
    return (
      <Grid container direction="row" wrap="nowrap" alignContent="center" alignItems="center">
        {component ? (
          <React.Fragment>
            <Grid>
              <Avatar
                variant="square"
                alt="icon"
                src={GetComponentIcon(component.type(), component.subType(), themeType)}
                style={{ float: "left" }}
                className={classes.avatarIcon}
              />
            </Grid>
            <Grid style={{ paddingLeft: 5 }}>
              <UnitMeasurementSummary
                component={component}
                reading={UnitMeasurement.convertLastMeasurement(
                  component.lastMeasurement.map(um => UnitMeasurement.any(um, user))
                )}
                omitTime
                dense
                centered
                onlyRecent
              />
            </Grid>
          </React.Fragment>
        ) : (
          "Component Not Found"
        )}
      </Grid>
    );
  };

  //// TODO-CS: Make a mutator describer to put the get functions into ////
  const getMutationIcon = (mutation: pond.Mutator, themeType: string) => {
    if (mutation === pond.Mutator.MUTATOR_FUEL_LEVEL) {
      return themeType === "light" ? FuelDark : FuelLight;
    }
    return "";
  };

  const getMutationColour = (mutation: pond.Mutator) => {
    if (mutation === pond.Mutator.MUTATOR_FUEL_LEVEL) {
      return "lightBlue";
    }
    return "";
  };

  const getMutationUnit = (mutation: pond.Mutator) => {
    if (mutation === pond.Mutator.MUTATOR_FUEL_LEVEL) {
      return "%";
    }
    return "";
  };

  //// /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ ////

  const fuelMutationDisplay = () => {
    if (!lastFuelMutation) {
      return (
        <Grid container direction="row" wrap="nowrap" alignContent="center" alignItems="center">
          <Grid>
            <Avatar
              variant="square"
              alt="icon"
              src={getMutationIcon(pond.Mutator.MUTATOR_FUEL_LEVEL, themeType)}
              style={{ float: "left" }}
              className={classes.avatarIcon}
            />
          </Grid>
          <Grid style={{ paddingLeft: 5 }}>
            N/A
          </Grid>
        </Grid>
      );
    }
    if (lastFuelCalc) {
      return (
        <Grid container>
          <Grid>
            <Avatar
              variant="square"
              alt="icon"
              src={getMutationIcon(pond.Mutator.MUTATOR_FUEL_LEVEL, themeType)}
              style={{ float: "left" }}
              className={classes.avatarIcon}
            />
          </Grid>
          <Grid style={{ paddingLeft: 5 }}>
            <Typography variant="caption" color="textPrimary">
              <span>
                <span style={{ color: getMutationColour(pond.Mutator.MUTATOR_FUEL_LEVEL) }}>
                  {(lastFuelCalc.value / 10).toFixed(2) +
                    getMutationUnit(pond.Mutator.MUTATOR_FUEL_LEVEL)}
                </span>
              </span>
            </Typography>
          </Grid>
        </Grid>
      );
    }
    return (
      <Grid container direction="row" wrap="nowrap" alignContent="center" alignItems="center">
        <Grid>
          <Avatar
            variant="square"
            alt="icon"
            src={getMutationIcon(pond.Mutator.MUTATOR_FUEL_LEVEL, themeType)}
            style={{ float: "left" }}
            className={classes.avatarIcon}
          />
        </Grid>
        <Grid style={{ paddingLeft: 5 }}>
          No Recent Data
        </Grid>
      </Grid>
    );
  };

  //content of the card if a device is linked to the heater
  const cardBody = (device?: Device) => {
    const productIcon = GetDeviceProductIcon(device ?? Device.create());

    if(device){
    return (
      <React.Fragment>
        <Box height="100%" display="flex" alignItems="center" flexWrap="nowrap" padding={2}>
          <ListItemAvatar className={classes.listAvatar}>
            <Avatar
              variant="square"
              src={productIcon}
              className={classes.avatarImage}
              alt="product"
            />
          </ListItemAvatar>
          <Grid container direction="column">
            <Grid>
              <ListItemText
                primary={heater.name}
                primaryTypographyProps={{
                  className: classes.textOverflow,
                  variant: "subtitle1"
                }}
                className={classes.listText}
              />
            </Grid>
            <Grid>
              <ListItemText
                primary={"Device: " + device.id()}
                primaryTypographyProps={{
                  className: classes.textOverflow,
                  variant: "subtitle2"
                }}
                className={classes.listText}
              />
            </Grid>
            <Grid>
              <ListItemText
                primary={"Last Checked In: " + moment(device.status.lastActive).fromNow()}
                primaryTypographyProps={{
                  className: classes.textOverflow,
                  variant: "subtitle2"
                }}
                className={classes.listText}
              />
            </Grid>
          </Grid>
        </Box>
        {allComponentsRecent ? (
          <CardContent>
            <Grid
              container
              direction="row"
              alignContent="center"
              alignItems="center">
              <Grid size={3}>{componentDisplay(heaterComponent)}</Grid>
              <Grid size={3}>{componentDisplay(heaterTempComponent)}</Grid>
              <Grid size={3}>{componentDisplay(siteTempComponent)}</Grid>
              <Grid size={3}>{fuelMutationDisplay()}</Grid>
            </Grid>
          </CardContent>
        ) : (
          <Box
            display="flex"
            justifyContent="center"
            alignItems="center"
            style={{ backgroundColor: "orange", padding: 10, borderRadius: "0px 0px 10px 10px" }}>
            A Component Is Not Reporting
          </Box>
        )}
      </React.Fragment>
    );
    }else {
      return (
        <React.Fragment>
        <CardContent style={{ padding: 20 }}>
          <Grid
            container
            direction="row"
            alignContent="center"
            alignItems="center">
            <Grid size={4}>
              <EventBlocker>
                <Button
                  variant="contained"
                  onClick={() => {
                    linkDevice(heater, heaterData.devices);
                  }}>
                  <Link />
                </Button>
              </EventBlocker>
            </Grid>
            <Grid size={7}>
              <Typography>{heater.name}</Typography>
            </Grid>
            <Grid size={1}>
              <ObjectHeaterIcon />
            </Grid>
          </Grid>
        </CardContent>
      </React.Fragment>
      )
    }
  };

  return (
    <Card raised onClick={goToHeater} style={{ margin: 5 }}>
      {cardBody(connectedDevice)}
    </Card>
  );
}
