import { Button } from "@mui/material";
import { filesize } from "filesize";
import React from "react";
import { ServerApi } from "../../api/ServerApi";
import { ImageCropperDialog } from "../../dialogs/ImageCropperDialog";
import { useAlert } from "../../hooks/context_providers/AlertDialogProvider";
import { Area } from "react-easy-crop";
import getCroppedImg from "../../utils/crop_image";

export function UploadPhotoButton(p: {
  label: string;
  onPhotoSelected: (b: Blob) => Promise<void>;
}): React.ReactElement {
  const [processing, setProcessing] = React.useState(false);
  const [imageBlob, setImageBlob] = React.useState<Blob>();
  const [imageURL, setImageURL] = React.useState<string>();
  const alert = useAlert();

  const uploadPhoto = async () => {
    try {
      // Create file element
      const fileEl = document.createElement("input");
      fileEl.type = "file";
      fileEl.accept =
        ServerApi.Config.constraints.photo_allowed_types.join(",");
      fileEl.click();

      // Wait for a file to be chosen
      await new Promise((res, _rej) =>
        fileEl.addEventListener("change", () => res(null))
      );

      if ((fileEl.files?.length ?? 0) === 0) return null;
      const file = fileEl.files![0];

      // Check file size
      if (file.size > ServerApi.Config.constraints.photo_max_size) {
        await alert(
          `Le fichier sélectionné est trop lourd ! (taille maximale acceptée : ${filesize(
            ServerApi.Config.constraints.photo_max_size
          )})`
        );
        return;
      }

      const tempURL = URL.createObjectURL(fileEl.files![0]);

      setImageBlob(file);
      setImageURL(tempURL);
    } catch (e) {
      console.error(e);
      alert("Failed to upload custom account image!");
      return null;
    }
  };

  const cancelCrop = () => {
    setImageURL(undefined);
  };

  const submitCrop = async (a: Area | undefined) => {
    setProcessing(true);
    try {
      let blob = imageBlob!;

      if (a) {
        blob = await getCroppedImg(imageURL!, a!);
      }

      await p.onPhotoSelected(blob);

      setImageBlob(undefined);
      setImageURL(undefined);
    } catch (e) {
      console.error(e);
      alert("Echec du traitement de la photo !");
    }

    setProcessing(false);
  };

  return (
    <>
      {/* Upload button */}
      <Button onClick={uploadPhoto}>{p.label}</Button>

      {/* Crop image dialog */}
      {imageURL && (
        <ImageCropperDialog
          processing={processing}
          src={imageURL!}
          onCancel={cancelCrop}
          onSubmit={submitCrop}
        />
      )}
    </>
  );
}
