import {
  Box,
  Card,
  Grid2 as Grid,
  Slider,
  Typography,
  IconButton,
  Theme,
  useTheme,
  darken
} from "@mui/material";
import GrainDescriber from "grain/GrainDescriber";
import GrainTransaction from "grain/GrainTransaction";
import { useMobile } from "hooks";
import useViewport from "hooks/useViewport";
import { round } from "lodash";
import { GrainBag } from "models/GrainBag";
import moment from "moment";
import { pond } from "protobuf-ts/pond";
import { useEffect, useState } from "react";
import { getThemeType } from "theme";
import { getGrainUnit } from "utils";
import GrainBagSVG from "./grainBagSVG";
import { makeStyles } from "@mui/styles";

interface Props {
  grainBag: GrainBag;
}

// eslint-disable-next-line @typescript-eslint/no-unused-vars
enum zIndexPriority {
  low = 1,
  medium = 2,
  high = 3
}

const useStyles = makeStyles((theme: Theme) => {
  return ({
    grainOVerlay: {
      position: "absolute",
      height: "10%",
      width: "100%",
      textAlign: "center",
      textShadow: "4px 4px 10px black"
    },
    cardContent: {
      padding: theme.spacing(2)
    },
    bgItem: {
      background: darken(theme.palette.background.paper, getThemeType() === "light" ? 0.05 : 0.25),
      zIndex: zIndexPriority.low,
      borderRadius: theme.shape.borderRadius,
      position: "relative",
      width: "auto",
      marginRight: theme.spacing(1)
    }
  });
});

export default function GrainBagVisualizer(props: Props) {
  const { grainBag } = props;
  const [fillLevel, setFillLevel] = useState(0);
  const isMobile = useMobile();
  const viewport = useViewport();
  const [sliderColour, setSliderCoulour] = useState("gold");
  const [pendingGrainAmount, setPendingGrainAmount] = useState<number | null>();
  const classes = useStyles();
  const [grainDiff, setGrainDiff] = useState<number | undefined>();
  const theme = useTheme();
  const [openTransaction, setOpenTransaction] = useState(false);

  useEffect(() => {
    setFillLevel((grainBag.bushels() / grainBag.capacity()) * 100);
  }, [grainBag]);

  const getSVGHeight = () => {
    if (isMobile) {
      return viewport.width * 0.8;
    }
    return viewport.height * 0.4;
  };

  const grainOverlay = () => {
    let displayPending = pendingGrainAmount;
    let displayDiff = grainDiff;
    if (getGrainUnit() === pond.GrainUnit.GRAIN_UNIT_WEIGHT && grainBag.bushelsPerTonne() > 1) {
      if (displayPending && displayDiff) {
        displayPending = Math.round((displayPending / grainBag.bushelsPerTonne()) * 100) / 100;
        displayDiff = Math.round((displayDiff / grainBag.bushelsPerTonne()) * 100) / 100;
      }
    }
    return (
      <Box>
        {grainDiff !== undefined && grainDiff > 0 && (
          <div
            className={classes.grainOVerlay}
            style={{
              top: "38%",
              color: "#5CE422"
            }}>
            <Typography variant={"h5"} style={{ fontWeight: 750 }}>
              +{displayDiff}
            </Typography>
          </div>
        )}
        <div
          className={classes.grainOVerlay}
          style={{
            top: "45%"
          }}>
          <Typography variant={"h4"} style={{ fontWeight: 750 }}>
            {displayPending}
          </Typography>
        </div>
        {grainDiff !== undefined && grainDiff < 0 && (
          <div
            className={classes.grainOVerlay}
            style={{
              top: "55%",
              color: "#E42222"
            }}>
            <Typography variant={"h5"} style={{ fontWeight: 750 }}>
              {displayDiff}
            </Typography>
          </div>
        )}
      </Box>
    );
  };

  const timeDisplay = () => {
    let now = moment();
    let duration = moment.duration(moment(grainBag.settings.fillDate).diff(now));
    let days = duration.asDays();
    days = Math.abs(days);
    duration.subtract(moment.duration(days, "days"));
    // let hours = duration.hours();
    // hours = Math.abs(hours);

    return Math.floor(days) + " days in bag";
  };

  const grainAmountDisplay = () => {
    if (getGrainUnit() === pond.GrainUnit.GRAIN_UNIT_WEIGHT && grainBag.bushelsPerTonne() > 1) {
      return (
        <div style={{ display: "flex", flexDirection: "row" }}>
          <Typography variant="body2" style={{ fontWeight: "bold", marginRight: "4px" }}>
            {(grainBag.bushels() / grainBag.bushelsPerTonne()).toFixed(2) + " mT"}
          </Typography>
          <Typography variant="body2">({grainBag.fillPercent()}%)</Typography>
        </div>
      );
    } else {
      return (
        <div style={{ display: "flex", flexDirection: "row" }}>
          <Typography variant="body2" style={{ fontWeight: "bold", marginRight: "4px" }}>
            {grainBag.bushels() <= 0 ? "Empty" : grainBag.bushels().toLocaleString()}
          </Typography>
          <Typography variant="body2">
            {grainBag.bushels() <= 0 ? "" : " / " + grainBag.capacity().toLocaleString() + " bu"}
          </Typography>
        </div>
      );
    }
  };

  const overview = () => {
    return (
      <Box width={1} position="absolute" top={0}>
        <Typography variant="subtitle2" color="textPrimary" style={{ fontWeight: 800 }}>
          {grainBag.storage() === pond.BinStorage.BIN_STORAGE_SUPPORTED_GRAIN
            ? GrainDescriber(grainBag.grain()).name
            : grainBag.customType()}
          {grainBag.subtype() !== "" ? " - " + grainBag.subtype() : ""}
        </Typography>
        <Box className={classes.bgItem} padding={1}>
          {grainAmountDisplay()}
        </Box>
        <Box padding="0" width={1} position="absolute" top={70}>
          <Typography variant="subtitle2" color="textPrimary" style={{ fontWeight: 600 }}>
            Fill Date
          </Typography>
          <Box className={classes.bgItem} display="flex" flexDirection={"column"} padding={1}>
            <Typography variant="body2" style={{ fontWeight: "bold" }}>
              {grainBag.settings.fillDate}
            </Typography>
            <Typography variant="body2" style={{ fontWeight: "bold" }}>
              {timeDisplay()}
            </Typography>
          </Box>
        </Box>
        <Box padding="0" width={1} position="absolute" top={160}>
          <Typography variant="subtitle2" color="textPrimary" style={{ fontWeight: 600 }}>
            Initial Moisture
          </Typography>
          <Box className={classes.bgItem} display="flex" flexDirection={"column"} padding={1}>
            <Typography variant="body2" style={{ fontWeight: "bold" }}>
              {grainBag.settings.initialMoisture}%
            </Typography>
          </Box>
        </Box>
      </Box>
    );
  };

  const visual = () => {
    return (
      <Box display="flex" width={1} justifyContent="flex-end">
        <Box
          position="relative"
          height={1}
          width={1}
          //bgcolor={theme.palette.background.paper}
          display="flex"
          justifyContent="center"
          alignItems="center"
          alignContent="flex-end">
          <Box zIndex={zIndexPriority.high}>
            {grainOverlay()}
            <GrainBagSVG fillPercent={fillLevel} height={getSVGHeight()} />
          </Box>
        </Box>
      </Box>
    );
  };

  const controls = () => {
    return (
      <Box
        height={1}
        width={1}
        display="flex"
        flexDirection="column"
        justifyContent="flex-end"
        alignContent="flex-end">
        <IconButton
          onClick={() => {
            setOpenTransaction(true);
          }}
          style={{
            backgroundColor: "gold",
            color: "black",
            height: 40,
            width: 40,
            marginBottom: 10
          }}>
          +/-
        </IconButton>
        <Box
          height={0.7}
          width={1}
          display="flex"
          justifyContent="center"
          alignContent="flex-end"
          zIndex={zIndexPriority.high}>
          <Slider
            orientation="vertical"
            value={fillLevel}
            style={{height: "100%", color: sliderColour }}
            min={0}
            max={100}
            valueLabelDisplay="auto"
            valueLabelFormat={value => value.toFixed() + "%"}
            onChange={(_, value) => {
              setFillLevel(value as number);
              const capacity = grainBag.capacity();
              const current = grainBag.bushels();
              let grainAmount = ((value as number) / 100) * capacity;
              if (grainAmount < current) {
                setSliderCoulour("#E42222");
              } else if (grainAmount > current) {
                setSliderCoulour("#5CE422");
              } else {
                setSliderCoulour("gold");
              }
              setGrainDiff(round(grainAmount - current, 0));
              setPendingGrainAmount(round(grainAmount, 0));
            }}
            onChangeCommitted={() => {
              setOpenTransaction(true);
            }}
            aria-labelledby="grain-amount"
          />
        </Box>
        <Box height={0.2} width={1} position="relative">
          <Box width={1} position="absolute" bottom="0" textAlign="center" />{" "}
          {/* this box is used to push the slider up */}
        </Box>
      </Box>
    );
  };

  return (
    <Card raised className={classes.cardContent}>
      <Grid container justifyContent="flex-start" alignItems="stretch" width={"100%"}>
        <Grid style={{ position: "relative" }} size={6}>
          {overview()}
        </Grid>
        <Grid style={{ position: "relative" }} size={5}>
          {visual()}
        </Grid>
        <Grid size={1}>{controls()}</Grid>
      </Grid>
      {/* dialog for grain inventory transactions */}
      <GrainTransaction
        open={openTransaction}
        close={() => {
          setOpenTransaction(false);
        }}
        mainObject={grainBag}
        grainAdjustment={grainDiff}
        callback={() => {
          setFillLevel((grainBag.bushels() / grainBag.capacity()) * 100);
          setGrainDiff(undefined);
          setPendingGrainAmount(null);
          setSliderCoulour("gold");
        }}
      />
    </Card>
  );
}
