import {
  Divider,
  Grid2 as Grid,
  IconButton,
  Theme,
  Typography,
  useTheme
} from "@mui/material";
import React, { useState } from "react";
import UndoIcon from "assets/editor/undo.png";
import RedoIcon from "assets/editor/redo.png";
import MoveIcon from "assets/editor/move.png";
import CursorIcon from "assets/editor/cursor.png";
import DeleteIcon from "assets/editor/delete.png";
import { ImgIcon } from "common/ImgIcon";
import { pond } from "protobuf-ts/pond";
import { useGlobalState, useMineAPI, useSnackbar } from "providers";
import { Save, CloudDownload } from "@mui/icons-material";
import { Placeable } from "./drawable/Placeable";
import { Component } from "models";
import EditorActions from "./EditorActions";
import LoadMine from "./LoadMine";
import { Sensor } from "./drawable/Sensor";
import { makeStyles } from "@mui/styles";

const useStyles = makeStyles((theme: Theme) => {
  return ({
    header: {
      width: "100%",
      height: theme.spacing(7),
      background: "rgba(25, 25, 25, 1)",
      margin: 0,
      padding: 0,
      display: "flex",
      alignItems: "center",
      borderBottom: "1px solid rgb(75, 75, 75)"
    },
    middleButtons: {
      display: "flex",
      alignItems: "center",
      margin: "auto"
    },
    leftButtons: {
      display: "flex",
      alignItems: "left",
      marginLeft: theme.spacing(1),
      marginTop: "auto",
      marginBottom: "auto"
    },
    rightButtons: {
      display: "flex",
      alignItems: "right",
      justifyItems: "flex-en",
      marginRight: theme.spacing(1),
      marginLeft: "auto"
    },
    divider: {
      height: "42px",
      width: "2px",
      margin: theme.spacing(1)
    }
  });
});

enum Mode {
  NORMAL,
  MOVE,
  ADD,
  DELETE
}

interface Props {
  setMode: any;
  undoRef: any;
  redoRef: any;
  saveRef: any;
  blocks: Placeable[];
  devices: pond.Device[];
  components: Component[];
  setBlocks: React.Dispatch<React.SetStateAction<Placeable[]>>;
  setDevices: React.Dispatch<React.SetStateAction<pond.Device[]>>;
  mine: pond.MineSettings;
  setMine: React.Dispatch<React.SetStateAction<pond.MineSettings>>;
  permissions: pond.Permission[];
  setPermissions: React.Dispatch<React.SetStateAction<pond.Permission[]>>;
  componentPreferences: Map<string, pond.MineComponentPreferences>;
  sensors: Sensor[];
}

export default function EditorHeader(props: Props) {
  const classes = useStyles();
  const {
    setMode,
    undoRef,
    redoRef,
    blocks,
    setBlocks,
    setDevices,
    mine,
    setMine,
    permissions,
    setPermissions,
    componentPreferences
  } = props;

  const mineAPI = useMineAPI();
  const snackbar = useSnackbar();
  const theme = useTheme();
  const [loadDialog, setLoadDialog] = useState(false);
  const [{as}] = useGlobalState();

  const save = () => {
    let settings = pond.MineSettings.create();
    blocks.forEach(block => {
      let shaft = pond.Placeable.create();
      shaft.angle = block.angle;
      shaft.direction = block.direction;
      shaft.radius = block.radius();
      shaft.type = block.type.valueOf();
      shaft.subtype = block.subtype;
      shaft.width = 64;
      shaft.x = block.x;
      shaft.y = block.y;
      shaft.magnitude = block.magnitude();
      settings.placeables.push(shaft);
    });

    settings.name = mine.name;

    if (mine.key) {
      settings.key = mine.key;
      let prefs = componentPreferences;
      mineAPI
        .updateMine(settings, prefs)
        .then(resp => {
          if (resp.status === 200) {
            snackbar.success("Changes successfully saved!");
          }
        })
        .catch(err => {
          snackbar.error("Error saving changes");
        });
    } else {
      mineAPI
        .addMine(settings, as)
        .then(resp => {
          if (resp.status === 200) {
            snackbar.success("New mine successfully saved!");
            settings.key = resp.data.key;
            setMine(settings);
            setPermissions([
              pond.Permission.PERMISSION_READ,
              pond.Permission.PERMISSION_SHARE,
              pond.Permission.PERMISSION_USERS,
              pond.Permission.PERMISSION_WRITE
            ]);
          }
        })
        .catch(err => {
          snackbar.error("Error saving new mine");
        });
    }
  };

  return (
    <Grid container className={classes.header}>
      <Grid className={classes.leftButtons}>
        <Typography className={classes.leftButtons} variant="h6">
          {mine.name ? mine.name : "No Name"}
        </Typography>
        <IconButton onClick={save} style={{ marginLeft: theme.spacing(2) }}>
          <Save />
        </IconButton>
        <IconButton onClick={() => setLoadDialog(true)}>
          <CloudDownload />
        </IconButton>
      </Grid>
      <Grid className={classes.middleButtons}>
        <div className={classes.middleButtons}>
          <IconButton onClick={undoRef.current ? (undoRef.current as any) : undefined}>
            <ImgIcon src={UndoIcon} />
          </IconButton>
          <IconButton onClick={redoRef.current ? (redoRef.current as any) : undefined}>
            <ImgIcon src={RedoIcon} />
          </IconButton>

          <Divider className={classes.divider} />

          <IconButton onClick={() => setMode(Mode.NORMAL)}>
            <ImgIcon src={CursorIcon} />
          </IconButton>
          <IconButton onClick={() => setMode(Mode.MOVE)}>
            <ImgIcon src={MoveIcon} />
          </IconButton>
          <IconButton onClick={() => setMode(Mode.DELETE)}>
            <ImgIcon src={DeleteIcon} />
          </IconButton>
        </div>
      </Grid>
      <Grid className={classes.rightButtons}>
        <div className={classes.rightButtons}>
          <EditorActions
            mine={mine}
            setMine={setMine}
            refreshCallback={() => {}}
            permissions={permissions}
          />
        </div>
      </Grid>
      <LoadMine
        setBlocks={setBlocks}
        setDevices={setDevices}
        setMine={setMine}
        setPermissions={setPermissions}
        open={loadDialog}
        setOpen={setLoadDialog}
      />
    </Grid>
  );
}
