import {
  Button,
  Card,
  CircularProgress,
  DialogActions,
  DialogContent,
  DialogTitle,
  Divider,
  IconButton,
  MenuItem,
  Select,
  Theme,
  Typography
} from "@mui/material";
import { pond } from "protobuf-ts/pond";
import { useGlobalState, useMineAPI, useSnackbar } from "providers";
import React, { useEffect, useState } from "react";
import { or } from "utils";
import { loadPlaceable, Placeable } from "./drawable/Placeable";
import LeftIcon from "@mui/icons-material/KeyboardArrowLeft";
import RightIcon from "@mui/icons-material/KeyboardArrowRight";
import ResponsiveDialog from "common/ResponsiveDialog";
import { useMobile } from "hooks";
import { makeStyles } from "@mui/styles";

interface Props {
  setMine: (value: React.SetStateAction<pond.MineSettings>) => void;
  setBlocks: (value: React.SetStateAction<Placeable[]>) => void;
  setDevices: (value: React.SetStateAction<pond.Device[]>) => void;
  setPermissions: (value: React.SetStateAction<pond.Permission[]>) => void;
  open: boolean;
  setOpen: React.Dispatch<React.SetStateAction<boolean>>;
}

const useStyles = makeStyles((theme: Theme) => {
  return ({
    dialog: {
      //width: theme.spacing(32)
    },
    mineCard: {
      margin: theme.spacing(1),
      padding: theme.spacing(1),
      background: theme.palette.background.default,
      "&:hover": {
        cursor: "pointer"
      }
    },
    highlight: {
      backgroundColor: "rgba(255, 255, 255, 0)",
      zIndex: 10,
      "&:hover": {
        backgroundColor: "rgba(255, 255, 255, 0.1)"
      }
    },
    bottomButtons: {
      marginLeft: "auto",
      justifyContent: "center",
      alignContent: "center"
    },
    bottom: {
      display: "flex",
      alignItems: "center",
      width: "100%",
      paddingRight: theme.spacing(1),
      paddingLeft: theme.spacing(1),
      marginTop: theme.spacing(1)
    }
  });
});

export default function LoadMine(props: Props) {
  const { setMine, setBlocks, setDevices, setPermissions, open, setOpen } = props;

  const mineAPI = useMineAPI();
  const snackbar = useSnackbar();
  const [mines, setMines] = useState<pond.MineSimple[]>([]);
  const [loading, setLoading] = useState(true);
  const [limit, setLimit] = useState(5);
  const [total, setTotal] = useState(0);
  const [offset, setOffset] = useState(0);
  const classes = useStyles();
  const isMobile = useMobile();
  const [{as}] = useGlobalState();

  const load = (key: string) => {
    setLoading(true);
    mineAPI
      .getMine(key, as)
      .then(resp => {
        let newBlocks: Placeable[] = [];
        if (resp.data.mine?.settings?.placeables)
          resp.data.mine?.settings?.placeables.forEach(p => {
            let placeable = loadPlaceable(p);
            newBlocks.push(placeable as Placeable);
          });
        setMine(
          pond.MineSettings.fromObject(or(resp.data.mine?.settings, pond.MineSettings.create()))
        );
        setBlocks(newBlocks);
        setDevices(or(resp.data.devices, []));
        setMine(or(resp.data.mine?.settings, undefined));
        let d = pond.GetMineResponse.fromObject(resp.data);
        setPermissions(d.permissions);
        if (resp.status === 200) {
          snackbar.success("Mine successfully loaded");
        }
      })
      .catch(err => {
        snackbar.error("Error loading mine");
      })
      .finally(() => {
        setOpen(false);
        setLoading(false);
      });
  };

  // Load list of mines when the tab is opened
  useEffect(() => {
    if (open) {
      setLoading(true);
      mineAPI.listMinesSimple(limit, offset, undefined, undefined, undefined, false, as).then(resp => {
        setMines(resp.data.mines);
        setLoading(false);
        setTotal(resp.data.total);
      });
    }
  }, [mineAPI, open, limit, offset, as]);

  const back = () => {
    if (offset - limit < 0) {
      setOffset(0);
    } else {
      setOffset(offset - limit);
    }
  };

  const forward = () => {
    if (offset + limit > total) {
      setOffset(total - limit);
    } else {
      setOffset(offset + limit);
    }
  };

  const paginator = () => {
    return (
      <div className={classes.bottom}>
        <Typography>
          {offset + 1} - {offset + limit > total ? total : offset + limit} of {total}
        </Typography>
        <div className={classes.bottomButtons}>
          <IconButton onClick={back} size="small">
            <LeftIcon />
          </IconButton>
          <Select value={limit} onChange={event => setLimit(event.target.value as number)}>
            <MenuItem value={5}>5</MenuItem>
            <MenuItem value={10}>10</MenuItem>
            <MenuItem value={15}>15</MenuItem>
          </Select>
          <IconButton onClick={forward} size="small">
            <RightIcon />
          </IconButton>
        </div>
      </div>
    );
  };

  return (
    <React.Fragment>
      <ResponsiveDialog
        open={open}
        onClose={() => setOpen(false)}
        className={classes.dialog}
        maxWidth="xs"
        fullWidth
        fullScreen={isMobile}>
        <DialogTitle>Load a Mine</DialogTitle>
        <DialogContent>
          {loading ? (
            <CircularProgress style={{ margin: "auto" }} />
          ) : mines.length < 1 ? (
            <Typography>No mines</Typography>
          ) : (
            <React.Fragment>
              {mines.map((mine, index) => {
                return (
                  <div key={index} className={classes.highlight}>
                    <Card className={classes.mineCard} onClick={() => load(mine.key)}>
                      <Typography>{mine.name === undefined ? "No Name" : mine.name}</Typography>
                    </Card>
                  </div>
                );
              })}
            </React.Fragment>
          )}
          {/* Set offsets */}
          <Divider />
          {paginator()}
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setOpen(false)}>Cancel</Button>
        </DialogActions>
      </ResponsiveDialog>
    </React.Fragment>
  );
}
