import { 
  Box, 
  Grid, 
  Typography,
  Theme 
} from "@mui/material";
import { makeStyles } from "@mui/styles";
import { Component } from "models";
import moment from "moment";
import { getMeasurementSummary, Summary } from "pbHelpers/ComponentType";
import { pond } from "protobuf-ts/pond";
import { quack } from "protobuf-ts/quack";
import React, { useEffect, useState } from "react";
import { or } from "utils/types";

interface Props {
  component: Component;
  reading?: pond.Measurement | null;
  tableCell?: boolean;
  centered?: boolean;
  dense?: boolean;
  omitTime?: boolean;
}

const useStyles = makeStyles((theme: Theme) => {
  return ({
    "@keyframes ripple": {
      from: {
        transform: "scale(.8)",
        opacity: 1
      },
      to: {
        transform: "scale(1.4)",
        opacity: 0
      }
    },
    on: {
      boxShadow: `0 0 0 2px ${theme.palette.background.paper}`,
      animationName: "$ripple",
      animationDuration: "1.2s",
      animationTimingFunction: "ease-in-out",
      animationIterationCount: "infinite"
    },
    off: {
      backgroundColor: "transparent"
    }
  })
});

//TODO: deprecated as unit measurements use a new measurement summary file
export default function MeasurementSummary(props: Props) {
  const { component, reading, tableCell, centered, dense } = props;
  const [summaries, setSummaries] = useState<Summary[]>([]);
  const [timestamp, setTimestamp] = useState("");
  const classes = useStyles();

  const grainCableFilters = () => {
    const { component } = props;
    return {
      grainType: component.settings.grainType,
      grainFilledTo: component.settings.grainFilledTo
    };
  };

  useEffect(() => {
    async function getSummary() {
      if (
        reading &&
        reading.measurement &&
        reading.measurement.id &&
        reading.measurement.id.type !== null &&
        reading.measurement.id.type !== undefined
      ) {
        let id = quack.ComponentID.fromObject(reading.measurement.id);
        let filters = { isTableCellMode: tableCell };
        if (id.type === quack.ComponentType.COMPONENT_TYPE_GRAIN_CABLE) {
          filters = { ...filters, ...grainCableFilters() };
        }
        await getMeasurementSummary(
          id.type,
          or(component.settings.subtype, 0),
          quack.Measurement.create(reading.measurement ? reading.measurement : undefined),
          filters
        ).then(summaries => {
          setSummaries(summaries);
        });
        setTimestamp(reading.timestamp);
      }
    }

    getSummary();
  }, [component, reading]); // eslint-disable-line react-hooks/exhaustive-deps

  const noSummary = () => {
    return (
      <Typography variant="body2" color="textPrimary">
        No Data
      </Typography>
    );
  };

  const getSummaryComponent = (summaries: Summary[]): any => {
    if (summaries.length < 1) {
      return noSummary();
    }

    return (
      <Grid container>
        <Grid item xs={12}>
          <Typography variant="body2" color="textPrimary">
            {summaries.map((summary: Summary, index: number) => {
              let sumVal = summary.value;
              if (component.settings.type === quack.ComponentType.COMPONENT_TYPE_EDGE_TRIGGERED) {
                if (
                  component.settings.subtype ===
                    quack.EdgeTriggeredSubtype.EDGE_TRIGGERED_SUBTYPE_WIND_SPEED &&
                  !isNaN(Number(sumVal))
                ) {
                  //make sure sumVal is a number
                  sumVal = Number(sumVal);

                  //get the period of time that all the measurements are in and convert it to seconds
                  let measurementInterval = Number(component.settings.measurementPeriodMs) / 1000;
                  //formula to determine the km/h
                  sumVal = (sumVal / measurementInterval) * 2.4;
                  //round to 2 decimal places and add the units
                  sumVal = Math.round(sumVal * 100) / 100 + "km/h";
                }
              }
              return (
                <span key={index}>
                  {summary.label + ": "} <span style={{ color: summary.colour }}>{sumVal}</span>{" "}
                  <br />
                </span>
              );
            })}
          </Typography>
        </Grid>
        {!props.omitTime && (
          <Grid item xs={12}>
            <Typography color="textSecondary" variant="caption">
              {moment(timestamp).fromNow()}
            </Typography>
          </Grid>
        )}
      </Grid>
    );
  };

  const getTableCellSummaryComponent = (summaries: Summary[]): any => {
    if (summaries.length < 1) {
      return <span>Unknown</span>;
    }
    const blacklist: Array<any> = [];
    const filteredSummaries = summaries.filter((item: any) => !blacklist.includes(item.label));
    return (
      <Grid container direction="row" justifyContent={centered ? "center" : "flex-start"} spacing={1}>
        {filteredSummaries.map((summary: Summary, i: number) => {
          let sumVal = summary.value;
          if (component.settings.type === quack.ComponentType.COMPONENT_TYPE_EDGE_TRIGGERED) {
            if (
              component.settings.subtype ===
                quack.EdgeTriggeredSubtype.EDGE_TRIGGERED_SUBTYPE_WIND_SPEED &&
              !isNaN(Number(sumVal))
            ) {
              //make sure sumVal is a number
              sumVal = Number(sumVal);
              //get the period of time that all the measurements are in and convert it to seconds
              let measurementInterval = Number(component.settings.measurementPeriodMs) / 1000;
              //formula to determine the km/h
              sumVal = (sumVal / measurementInterval) * 2.4;
              //round to 2 decimal places and add the units
              sumVal = Math.round(sumVal * 100) / 100 + "km/h";
            }
          }
          return (
            <Grid item key={summary.label}>
              {summary.label + ": "}
              <span style={{ color: summary.colour }}>{sumVal}</span>
              {i + 1 !== filteredSummaries.length && ","}
            </Grid>
          );
        })}
      </Grid>
    );
  };

  const getDenseSummary = (summaries: Summary[]): any => {
    if (summaries.length < 1) {
      return null;
    }

    const blacklist: Array<any> = ["Temperature (Air)", "Moisture (Air)"];
    const filteredSummaries = summaries.filter(
      (item: any) =>
        !blacklist.includes(item.label) && (item.label !== "Grain Type" || item.value !== "None")
    );

    let overlays: any = [];

    return (
      <Box width={"100%"} component="div">
        {filteredSummaries.map((summary: Summary, i: number) => {
          let sumVal = summary.value;
          if (component.settings.type === quack.ComponentType.COMPONENT_TYPE_EDGE_TRIGGERED) {
            if (
              component.settings.subtype ===
                quack.EdgeTriggeredSubtype.EDGE_TRIGGERED_SUBTYPE_WIND_SPEED &&
              !isNaN(Number(sumVal))
            ) {
              //make sure sumVal is a number
              sumVal = Number(sumVal);
              //get the period of time that all the measurements are in and convert it to seconds
              let measurementInterval = Number(component.settings.measurementPeriodMs) / 1000;
              //formula to determine the km/h
              sumVal = (sumVal / measurementInterval) * 2.4;
              //round to 2 decimal places and add the units
              sumVal = Math.round(sumVal * 100) / 100 + "km/h";
            }
          }
          if (component.settings.hasOverlays) {
            let overlay: pond.ComponentOverlays = pond.ComponentOverlays.create();
            let found = false;
            component.settings.overlays.forEach(ov => {
              if (ov.measurementType === summary.type) {
                //check if the sum value is within the overlay min-max
                let numVal = parseFloat(sumVal);
                if (numVal >= ov.min && numVal <= ov.max) {
                  overlay = ov;
                  found = true;
                }
              }
            });
            if (found) {
              overlays.push(
                <React.Fragment key={"overlay" + i}>
                  <Grid item>
                    <Box
                      width="20px"
                      height="20px"
                      borderRadius="50%"
                      className={classes.on}
                      style={{ background: overlay.colour }}
                    />
                  </Grid>
                  <Grid item>
                    <Typography
                      variant="caption"
                      component="span"
                      style={{ marginLeft: 5, marginRight: 5 }}>
                      {overlay.message}
                    </Typography>
                  </Grid>
                </React.Fragment>
              );
            }
          }
          return (
            <Typography key={summary.label} variant="caption" component="span">
              <span style={{ color: summary.colour }}>{sumVal}</span>
              {i + 1 !== filteredSummaries.length && ", "}
            </Typography>
          );
        })}
        {!props.omitTime && (
          <Box component="span">
            {" - "}
            <Typography color="textSecondary" variant="caption">
              {moment(timestamp).fromNow()}
            </Typography>
          </Box>
        )}
        <Grid container direction="row">
          {overlays}
        </Grid>
      </Box>
    );
  };

  if (summaries.length <= 0) return noSummary();
  if (dense) return getDenseSummary(summaries);
  if (tableCell) return getTableCellSummaryComponent(summaries);
  return getSummaryComponent(summaries);
}
