import {
  Box,
  Button,
  CircularProgress,
  darken,
  Grid2 as Grid,
  IconButton,
  Theme,
  Typography
} from "@mui/material";
import { useFileControllerAPI, useGlobalState } from "providers";
import { useState } from "react";
import ErrorIcon from "@mui/icons-material/Error";
import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutline";
import { getThemeType } from "theme";
import { toAttach } from "providers/pond/fileControllerAPI";
import DeleteIcon from "products/AgIcons/Delete";
import { pond } from "protobuf-ts/pond";
import { makeStyles } from "@mui/styles";

interface Props {
  toAttach?: toAttach;
  uploadStart: () => void;
  uploadEnd: (fileID?: string, fileName?: string) => void;
  uniqueID?: string;
  keys?: string[];
  types?: string[];
}

const useStyles = makeStyles((theme: Theme) => {
  return ({
    fileSelect: {
      cursor: "pointer",
      border: "1px solid white",
      padding: 7,
      borderRadius: 5,
      backgroundColor: darken(
        theme.palette.background.paper,
        getThemeType() === "light" ? 0.05 : 0.25
      ),
      "&:hover": {
        backgroundColor: theme.palette.background.paper
      }
    },
    fileDisabled: {
      border: "1px solid gray",
      color: "gray",
      padding: 7,
      borderRadius: 5,
      backgroundColor: theme.palette.background.paper
    }
  });
});

export default function FileSelector(props: Props) {
  const { uploadEnd, uploadStart, uniqueID, toAttach, keys, types } = props;
  const [{ userTeamPermissions }] = useGlobalState();
  const [fileList, setFileList] = useState<FileList | undefined>();
  const classes = useStyles();
  const fileAPI = useFileControllerAPI();
  const [uploadFailed, setUploadFailed] = useState(false);
  const [fileID, setFileID] = useState("");
  const [uploading, setUploading] = useState(false);
  const [fileName, setFileName] = useState("");
  const [errorMsg, setErrorMsg] = useState("File failed to upload");
  const [fileInvalid, setFileInvalid] = useState(false);
  const maxFileSizeMB = 10;
  const bytesConversionFactor = 1048576;

  const uploadFile = () => {
    if (fileList) {
      let image = fileID;
      uploadStart();
      setUploading(true);
      fileAPI
        .uploadFiles(fileList, toAttach, keys, types)
        .then(resp => {
          image = resp.data.uuid;
          setUploadFailed(false);
        })
        .catch(err => {
          //file failed to upload
          if (err.response) {
            setErrorMsg(err.response.data.error);
          }
          setUploadFailed(true);
        })
        .finally(() => {
          setFileID(image);
          uploadEnd(image, fileName);
          setUploading(false);
        });
    }
  };

  const deleteFile = () => {
    fileAPI
      .deleteFile(fileID)
      .then(resp => {
        console.log("no errors");
      })
      .catch(err => {
        console.log("error found");
      });
  };

  const checkFile = (file: File) => {
    let invalid = false;
    let largeFile = file.size / bytesConversionFactor > maxFileSizeMB;
    if (largeFile || !file.type.includes("image/")) {
      invalid = true;
      let errMsg = "File type not allowed";
      if (largeFile) errMsg = "File too large";
      setErrorMsg(errMsg);
    }
    setFileInvalid(invalid);
  };

  const uploadStatus = () => {
    if (uploading) {
      return <CircularProgress />;
    }
    if (uploadFailed) {
      return <ErrorIcon style={{ height: 40, width: 40, color: "red" }} />;
    }
    if (fileID !== "") {
      return <CheckCircleOutlineIcon style={{ height: 40, width: 40, color: "green" }} />;
    }
    return;
  };

  return (
    <Box width={"100%"}>
      <Grid
        container
        direction="row"
        alignContent="center"
        alignItems="center"
        justifyContent="space-between">
        <Grid >
          <input
            disabled={
              uploading ||
              (!uploadFailed && fileID !== "") ||
              !userTeamPermissions.includes(pond.Permission.PERMISSION_FILE_MANAGEMENT)
            }
            multiple={false}
            name={uniqueID || "fileInput"}
            id={uniqueID || "fileInput"}
            hidden
            type="file"
            onChange={event => {
              if (event.target.files) {
                setFileList(event.target.files);
                let file = event.target.files[0];
                if (file) {
                  setFileName(file.name);
                  checkFile(file);
                }
              }
            }}
          />
          <label
            htmlFor={uniqueID || "fileInput"}
            className={
              userTeamPermissions.includes(pond.Permission.PERMISSION_FILE_MANAGEMENT)
                ? classes.fileSelect
                : classes.fileDisabled
            }>
            {fileName === "" ? "Choose a file..." : fileName}
          </label>
        </Grid>
        <Grid >
          <Grid container spacing={2} alignContent="center" alignItems="center">
            <Grid >{uploadStatus()}</Grid>
            {!uploadFailed && fileID !== "" && (
              <Grid>
                <IconButton
                  onClick={() => {
                    deleteFile();
                  }}>
                  <DeleteIcon />
                </IconButton>
              </Grid>
            )}
            <Grid >
              {fileList && (
                <Button
                  onClick={uploadFile}
                  variant="contained"
                  disabled={uploading || (!uploadFailed && fileID !== "") || fileInvalid}>
                  Upload
                </Button>
              )}
            </Grid>
          </Grid>
        </Grid>
      </Grid>
      {(uploadFailed || fileInvalid) && <Typography color="error">{errorMsg}</Typography>}
    </Box>
  );
}
