import { useCallback, useState } from "react";
import { observer } from "mobx-react-lite";
import { useDropzone } from "react-dropzone";
// hooks
import { useApplication } from "hooks/store";
// constants
import { MAX_FILE_SIZE } from "constants/common";
// helpers
import { generateFileName } from "helpers/attachment.helper";
// types
import { TAttachmentOperations } from "./root";

type TAttachmentOperationsModal = Exclude<TAttachmentOperations, "remove">;

type Props = {
  workspaceSlug: string;
  disabled?: boolean;
  handleAttachmentOperations: TAttachmentOperationsModal;
};

export const IssueAttachmentUpload: React.FC<Props> = observer((props) => {
  const { workspaceSlug, disabled = false, handleAttachmentOperations } = props;
  // store hooks
  const {
    config: { envConfig },
  } = useApplication();
  // states
  const [isLoading, setIsLoading] = useState(false);

  const onDrop = useCallback((acceptedFiles: File[]) => {
    const currentFile: File = acceptedFiles[0];
    if (!currentFile || !workspaceSlug) return;

    const uploadedFile: File = new File([currentFile], generateFileName(currentFile.name), { type: currentFile.type });
    const formData = new FormData();
    formData.append("asset", uploadedFile);
    formData.append(
      "attributes",
      JSON.stringify({
        name: uploadedFile.name,
        size: uploadedFile.size,
      })
    );
    setIsLoading(true);
    handleAttachmentOperations.create(formData).finally(() => setIsLoading(false));
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const { getRootProps, getInputProps, isDragActive, isDragReject, fileRejections } = useDropzone({
    onDrop,
    maxSize: envConfig?.file_size_limit ?? MAX_FILE_SIZE,
    multiple: false,
    disabled: isLoading || disabled,
  });

  const maxFileSize = envConfig?.file_size_limit ?? MAX_FILE_SIZE;

  const fileError =
    fileRejections.length > 0 ? `Invalid file type or size (max ${maxFileSize / 1024 / 1024} MB)` : null;

  return (
    <div
      {...getRootProps()}
      className={`flex h-[60px] items-center justify-center rounded-md border-2 border-dashed bg-custom-primary/5 px-4 text-xs text-custom-primary ${
        isDragActive ? "border-custom-primary bg-custom-primary/10" : "border-custom-border-200"
      } ${isDragReject ? "bg-red-100" : ""} ${disabled ? "cursor-not-allowed" : "cursor-pointer"}`}
    >
      <input {...getInputProps()} />
      <span className="flex items-center gap-2">
        {isDragActive ? (
          <p>Drop here...</p>
        ) : fileError ? (
          <p className="text-center text-red-500">{fileError}</p>
        ) : isLoading ? (
          <p className="text-center">Uploading...</p>
        ) : (
          <p className="text-center">Click or drag a file here</p>
        )}
      </span>
    </div>
  );
});