import { Button, Card, Grid2 as Grid, Slider } from "@mui/material";
import { useMobile } from "hooks";
import { GrainCable } from "models/GrainCable";
import { pond } from "protobuf-ts/pond";
import { useBinAPI, useGlobalState } from "providers";
import React, { useEffect, useState } from "react";

interface Props {
  binKey: string;
  componentDevMap: Map<string, number>;
  cables: GrainCable[];
}

interface CableNodeInfo {
  numNodes: number;
  cableKey: string;
  cableName: string;
  device: number;
  currentTopNode: number;
}

export default function CableTopNodeSummary(props: Props) {
  const { binKey, cables, componentDevMap } = props;
  const [{as}] = useGlobalState()
  const [cableNodes, setCableNodes] = useState<CableNodeInfo[]>([]);
  const isMobile = useMobile();
  const binAPI = useBinAPI();

  useEffect(() => {
    //go through the cables setting the node list and the name map
    let nodeList: CableNodeInfo[] = [];
    cables.forEach(cable => {
      nodeList.push({
        device: componentDevMap.get(cable.key()) ?? 0,
        cableKey: cable.key(),
        currentTopNode: cable.settings.grainFilledTo,
        cableName: cable.name(),
        numNodes: cable.temperatures.length
      });
    });
    setCableNodes(nodeList);
  }, [cables, componentDevMap]);

  //function to build the new topnode array from the cableNodeInfo and send it to the backend to update the cables and their interactions
  const submit = () => {
    let newTopNodes: pond.NewTopNode[] = [];
    cableNodes.forEach(cable => {
      newTopNodes.push(
        pond.NewTopNode.create({
          cableKey: cable.cableKey,
          device: cable.device,
          nodeNumber: cable.currentTopNode
        })
      );
    });
    binAPI
      .updateTopNodes(binKey, newTopNodes, as)
      .then(resp => {
        console.log("Set Top Nodes for cables, components and interactions have been updated");
      })
      .catch(err => {
        console.log("One or more cables or interactions failed to update to the new top nodes");
      });
  };

  const updateCableNode = (index: number, newNode: number) => {
    let nodeList = cableNodes;
    if (nodeList[index]) {
      nodeList[index].currentTopNode = newNode;
    }
    setCableNodes([...nodeList]);
  };

  const verticalSliders = () => {
    return (
      <Grid container direction="row">
        {cableNodes.map((cable, index) => (
          <React.Fragment key={cable.cableKey}>
            <Grid
              size={{ xs: 2 }}
              container
              direction="column"
              style={{ padding: 10 }}
              alignContent="center"
              alignItems="center"
              justifyContent="center">
              <Grid style={{ height: 50 }}>
                {cable.cableName}
              </Grid>
              <Grid style={{ height: 150, margin: 10 }}>
                <Slider
                  orientation="vertical"
                  min={1}
                  max={cable.numNodes}
                  value={cable.currentTopNode}
                  onChange={(_, val) => {
                    updateCableNode(index, val as number);
                  }}
                />
              </Grid>
              <Grid style={{ height: 30 }}>
                {cable.currentTopNode}
              </Grid>
            </Grid>
          </React.Fragment>
        ))}
      </Grid>
    );
  };

  const horizontalSliders = () => {
    return (
      <Grid
        container
        style={{ padding: 5 }}
        alignContent="center"
        alignItems="center"
        justifyContent="center">
        {cableNodes.map((cable, index) => (
          <React.Fragment key={cable.cableKey}>
            <Grid size={{ xs: 3 }}>
              {cable.cableName}
            </Grid>
            <Grid size={{ xs: 8 }} style={{ paddingRight: 15 }}>
              <Slider
                min={1}
                max={cable.numNodes}
                value={cable.currentTopNode}
                onChange={(_, val) => {
                  updateCableNode(index, val as number);
                }}
              />
            </Grid>
            <Grid size={{ xs: 1 }}>
              {cable.currentTopNode}
            </Grid>
          </React.Fragment>
        ))}
      </Grid>
    );
  };

  return (
    <Card style={{ padding: 10 }} elevation={2}>
      {isMobile ? horizontalSliders() : verticalSliders()}
      <Button onClick={submit} variant="contained" color="primary">
        Update Cable Top Nodes
      </Button>
    </Card>
  );
}
