import React from "react";
import { connect } from "react-redux";
import { FixedSizeList } from "react-window";
import SplitPane from "react-split-pane";
import { makeStyles, withStyles } from "@material-ui/core/styles";
import ListItem from "@material-ui/core/ListItem";
import ListItemText from "@material-ui/core/ListItemText";
import Paper from "@material-ui/core/Paper";
import Typography from "@material-ui/core/Typography";
import Box from "@material-ui/core/Box";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import MuiAccordion from "@material-ui/core/Accordion";
import MuiAccordionSummary from "@material-ui/core/AccordionSummary";
import MuiAccordionDetails from "@material-ui/core/AccordionDetails";
import { socket } from "./connect";
import useResizeAware from "react-resize-aware";

import { getSelected } from "./redux/store";
import { selectedGraphPaths, setSelectedPath } from "./redux/graphPaths";

import OverflowTooltip from "./OverflowTooltip";

const rowHeight = 25;

const Accordion = withStyles({
  root: {
    border: "1px solid rgba(0, 0, 0, .125)",
    boxShadow: "none",
    "&:not(:last-child)": {
      borderBottom: 0,
    },
    "&:before": {
      display: "none",
    },
    "&$expanded": {
      margin: "auto",
    },
  },
  expanded: {},
})(MuiAccordion);

const AccordionSummary = withStyles({
  root: {
    backgroundColor: "rgba(0, 0, 0, .03)",
    borderBottom: "1px solid rgba(0, 0, 0, .125)",
    marginBottom: -1,
    minHeight: 56,
    "&$expanded": {
      minHeight: 56,
    },
  },
  content: {
    "&$expanded": {
      margin: "12px 0",
    },
  },
  expanded: {},
})(MuiAccordionSummary);

const AccordionDetails = withStyles((theme) => ({
  root: {
    padding: theme.spacing(2),
  },
}))(MuiAccordionDetails);

const GraphPaths = ({ selectedNodes, graphPaths, setSelectedPath, width }) => {
  const [fromNode, setFromNode] = React.useState("");
  const [toNode, setToNode] = React.useState("");
  const [fromNodeId, setFromNodeId] = React.useState(0);
  const [toNodeId, setToNodeId] = React.useState(0);
  const [fromNodeExpanded, setFromNodeExpanded] = React.useState(false);
  const [toNodeExpanded, setToNodeExpanded] = React.useState(false);
  const [paneSize, setPaneSize] = React.useState("50%");

  const [fromResizeListener, fromSizes] = useResizeAware();
  const [toResizeListener, toSizes] = useResizeAware();

  const useStyles = makeStyles((theme) => ({
    root: {
      width: "100%",
      maxWidth: width,
      backgroundColor: theme.palette.background.paper,
    },
    nested: {
      paddingLeft: theme.spacing(4),
    },
    listItem: {
      width: width,
    },
  }));
  const classes = useStyles();

  function toNodeRow({ index, style, data }) {
    return (
      <ListItem
        button
        style={style}
        key={index}
        onClick={() => {
          setToNode(data[index].name);
          setToNodeId(index);
          setToNodeExpanded(false);
          setPaneSize("50%");
          if (fromNode != "" && data[fromNodeId]) {
            const nodes = {
              fromNode: data[fromNodeId].node,
              toNode: data[index].node,
            };
            socket.emit("receive_graph_paths", nodes);
          }
        }}
      >
        <ListItemText primary={data[index].name} />
      </ListItem>
    );
  }

  function fromNodeRow({ index, style, data }) {
    return (
      <ListItem
        button
        style={style}
        key={index}
        onClick={() => {
          setFromNode(data[index].name);
          setFromNodeId(index);
          setFromNodeExpanded(false);
          setPaneSize("50%");

          if (toNode != "" && data[toNodeId]) {
            const nodes = {
              fromNode: data[index].node,
              toNode: data[toNodeId].node,
            };
            socket.emit("receive_graph_paths", nodes);
          }
        }}
      >
        <ListItemText primary={data[index].name} />
      </ListItem>
    );
  }

  function pathRow({ index, style, data }) {
    return (
      <ListItem
        button
        style={style}
        key={index}
        onClick={() => {
          setSelectedPath(index);
        }}
      >
        <ListItemText
          primary={
            "Path #" +
            (index + 1).toString() +
            " - Hops: " +
            (data[index].length - 1).toString()
          }
        />
      </ListItem>
    );
  }

  function listHeight(numItems, minHeight, maxHeight) {
    const size = numItems * rowHeight;
    if (size > maxHeight) {
      return maxHeight;
    }
    if (size < minHeight) {
      return minHeight;
    }
    return size;
  }

  const handleToChange = (panel) => (event, newExpanded) => {
    setPaneSize(newExpanded ? "0%" : "50%");
    setToNodeExpanded(newExpanded ? panel : false);
  };

  const handleFromChange = (panel) => (event, newExpanded) => {
    setPaneSize(newExpanded ? "100%" : "50%");
    setFromNodeExpanded(newExpanded ? panel : false);
  };

  return (
    <Paper elevation={3} style={{ backgroundColor: "rgba(0, 0, 0, .03)" }}>
      <SplitPane
        split="vertical"
        minSize={"50%"}
        size={paneSize}
        style={{ position: "relative" }}
        defaultSize={"50%"}
        pane1Style={{ height: "100%" }}
        pane2Style={{ height: "100%", width: "100%" }}
      >
        <Accordion
          expanded={fromNodeExpanded}
          onChange={handleFromChange(!fromNodeExpanded)}
        >
          <AccordionSummary
            expandIcon={<ExpandMoreIcon />}
            aria-controls="panel1a-content"
            id="panel1a-header"
          >
            <Box
              style={{
                display: "flex",
                flexDirection: "column",
              }}
            >
              <Typography className={classes.heading}>From Node:</Typography>
              <Typography
                className={classes.heading}
                style={{ width: fromSizes.width - 50 }}
                noWrap={true}
                display={"block"}
              >
                {fromResizeListener}
                {fromNode}
              </Typography>
            </Box>
          </AccordionSummary>
          <AccordionDetails>
            <FixedSizeList
              height={listHeight(selectedNodes.length, 100, 200)}
              width={width}
              itemSize={rowHeight}
              itemCount={selectedNodes.length}
              itemData={selectedNodes}
            >
              {fromNodeRow}
            </FixedSizeList>
          </AccordionDetails>
        </Accordion>

        <Accordion
          expanded={toNodeExpanded}
          onChange={handleToChange(!toNodeExpanded)}
        >
          <AccordionSummary
            expandIcon={<ExpandMoreIcon />}
            aria-controls="panel1a-content"
            id="panel1a-header"
          >
            <Box style={{ display: "flex", flexDirection: "column" }}>
              <Typography className={classes.heading}>To Node:</Typography>
              <Typography
                className={classes.heading}
                style={{ width: toSizes.width - 50 }}
                noWrap={true}
                display={"block"}
              >
                {toResizeListener}
                {toNode}
              </Typography>
            </Box>
          </AccordionSummary>
          <AccordionDetails>
            <FixedSizeList
              height={listHeight(selectedNodes.length, 100, 200)}
              width={width}
              itemSize={rowHeight}
              itemCount={selectedNodes.length}
              itemData={selectedNodes}
            >
              {toNodeRow}
            </FixedSizeList>
          </AccordionDetails>
        </Accordion>
      </SplitPane>
      <Paper elevation={2} style={{ backgroundColor: "rgba(0, 0, 0, .03)" }}>
        <Typography className={classes.heading} style={{ margin: "10px" }}>
          Num Paths: {graphPaths.paths.length}{" "}
        </Typography>
      </Paper>
      <FixedSizeList
        height={listHeight(graphPaths.paths.length, 100, 200)}
        width={width}
        itemSize={rowHeight}
        itemCount={graphPaths.paths.length}
        itemData={graphPaths.paths}
        style={{ margin: "10px" }}
      >
        {pathRow}
      </FixedSizeList>
    </Paper>
  );
};

export default connect(getSelected, { selectedGraphPaths, setSelectedPath })(
  GraphPaths
);
