import CloudUploadIcon from "@mui/icons-material/CloudUpload";
import {
  Button,
  Dialog,
  DialogActions,
  DialogContent,
  DialogContentText,
  DialogTitle,
  FormControl,
  InputLabel,
  MenuItem,
  Select,
  styled,
} from "@mui/material";
import React from "react";
import { OTAAPI } from "../api/OTAApi";
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
import { useLoadingMessage } from "../hooks/context_providers/LoadingMessageProvider";
import { useSnackbar } from "../hooks/context_providers/SnackbarProvider";
import { checkVersion } from "../utils/StringsUtils";
import { TextInput } from "../widgets/forms/TextInput";

const VisuallyHiddenInput = styled("input")({
  clip: "rect(0 0 0 0)",
  clipPath: "inset(50%)",
  height: 1,
  overflow: "hidden",
  position: "absolute",
  bottom: 0,
  left: 0,
  whiteSpace: "nowrap",
  width: 1,
});

export function UploadUpdateDialog(p: {
  platforms: string[];
  onClose: () => void;
  onCreated: () => void;
}): React.ReactElement {
  const alert = useAlert();
  const snackbar = useSnackbar();
  const loadingMessage = useLoadingMessage();

  const [platform, setPlatform] = React.useState<string | undefined>();
  const [version, setVersion] = React.useState<string | undefined>();
  const [file, setFile] = React.useState<File | undefined>();

  const canSubmit = platform && version && checkVersion(version) && file;

  const upload = async () => {
    try {
      loadingMessage.show("Uploading firmware...");
      await OTAAPI.UploadFirmware(platform!, version!, file!);

      snackbar("Successfully uploaded new firmware!");

      p.onCreated();
    } catch (e) {
      console.error(e);
      alert(`Failed to upload firmware: ${e}`);
    } finally {
      loadingMessage.hide();
    }
  };

  return (
    <Dialog open={true} onClose={p.onClose}>
      <DialogTitle>Submit a new update</DialogTitle>
      <DialogContent>
        <DialogContentText>
          You can upload a new firmware using this form.
        </DialogContentText>
        <br />
        <FormControl fullWidth>
          <InputLabel>Platform</InputLabel>
          <Select
            label="Platform"
            value={platform}
            onChange={(e) => setPlatform(e.target.value)}
            variant="standard"
          >
            {p.platforms.map((p) => (
              <MenuItem key={p} value={p}>
                {p}
              </MenuItem>
            ))}
          </Select>
        </FormControl>
        <br />
        <br />
        <TextInput
          editable
          label="Version"
          helperText="The version shall follow semantics requirements"
          value={version}
          onValueChange={setVersion}
          checkValue={checkVersion}
        />

        <br />

        <Button
          fullWidth
          component="label"
          role={undefined}
          variant={file ? "contained" : "outlined"}
          tabIndex={-1}
          startIcon={<CloudUploadIcon />}
        >
          Upload file
          <VisuallyHiddenInput
            type="file"
            onChange={(event) =>
              setFile(
                (event.target.files?.length ?? 0) > 0
                  ? event.target.files![0]
                  : undefined
              )
            }
            multiple
          />
        </Button>
      </DialogContent>
      <DialogActions>
        <Button onClick={p.onClose}>Cancel</Button>
        <Button type="submit" disabled={!canSubmit} onClick={upload}>
          Upload
        </Button>
      </DialogActions>
    </Dialog>
  );
}
