import { 
  Card, 
  darken, 
  Theme, 
  Typography 
} from "@mui/material";
import { Component, Interaction } from "models";
import { Ambient } from "models/Ambient";
import { Controller } from "models/Controller";
import { Plenum } from "models/Plenum";
import { componentIDToString } from "pbHelpers/Component";
import { pond } from "protobuf-ts/pond";
import { useEffect, useState } from "react";
import BinConditioningInteraction from "./BinConditioningInteraction";
import { makeStyles } from "@mui/styles";

const useStyles = makeStyles((theme: Theme) => {
  return ({
    card: {
      padding: 10,
      paddingLeft: 15,
      paddingRight: 15
    },
    displayBG: {
      marginTop: 10,
      background: darken(theme.palette.background.default, 0.05),
      borderRadius: 5,
      padding: 10
    }
  });
});

interface Props {
  interactions: Interaction[];
  interactionDevices: Map<string, number>;
  mode: pond.BinMode.BIN_MODE_DRYING | pond.BinMode.BIN_MODE_HYDRATING;
  plenums?: Plenum[];
  ambients?: Ambient[];
  heaters?: Controller[];
  fans?: Controller[];
  grain?: pond.Grain;
}

export default function BinConditioningCard(props: Props) {
  const classes = useStyles();
  const { interactions, interactionDevices, plenums, ambients, heaters, fans, grain, mode } = props;
  const [sourceMap, setSourceMap] = useState<Map<string, Component>>(new Map());
  const [sinkMap, setSinkMap] = useState<Map<string, Component>>(new Map());

  useEffect(() => {
    let sourceMap: Map<string, Component> = new Map();
    let sinkMap: Map<string, Component> = new Map();

    plenums?.forEach(plenum => {
      sourceMap.set(plenum.locationString(), plenum.asComponent());
    });

    ambients?.forEach(ambient => {
      sourceMap.set(ambient.locationString(), ambient.asComponent());
    });

    heaters?.forEach(heater => {
      sinkMap.set(heater.locationString(), heater.asComponent());
    });

    fans?.forEach(fan => {
      sinkMap.set(fan.locationString(), fan.asComponent());
    });

    setSourceMap(sourceMap);
    setSinkMap(sinkMap);
  }, [plenums, ambients, heaters, fans]);

  const conditionsDisplay = () => {
    let conditioningInteractions: JSX.Element[] = [];
    interactions.forEach(interaction => {
      let source = sourceMap.get(componentIDToString(interaction.settings.source));
      let sink = sinkMap.get(componentIDToString(interaction.settings.sink));
      let deviceId = interactionDevices.get(interaction.key());
      //if they do exist add to the array of elements to return
      if (deviceId && source && sink) {
        conditioningInteractions.push(
          <BinConditioningInteraction
            key={interaction.key()}
            deviceId={deviceId}
            interaction={interaction}
            sink={sink}
            source={source}
            grain={grain}
          />
        );
      }
    });
    return conditioningInteractions;
  };

  return (
    <Card raised className={classes.card}>
      <Typography style={{ fontWeight: 650 }}>
        {mode === pond.BinMode.BIN_MODE_DRYING ? "Drying" : "Hydrating"} Conditions
      </Typography>
      {conditionsDisplay()}
    </Card>
  );
}
