'use strict';

const index = require('../../../../../../../node_modules/.pnpm/@tiptap_extension-image@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_/node_modules/@tiptap/extension-image/dist/index.cjs');
const index$1 = require('../../../../../../../node_modules/.pnpm/@tiptap_react@3.15.3_@floating-ui_dom@1.7.4_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tip_b42b5b2d59902d8a01cd4cc3e2d5dc64/node_modules/@tiptap/react/dist/index.cjs');
const imageViewBlock = require('./components/image-view-block.cjs');
const utils = require('../../utils.cjs');
const index$2 = require('../../../../../../../node_modules/.pnpm/prosemirror-transform@1.10.5/node_modules/prosemirror-transform/dist/index.cjs');

const handleError = (error, props, errorHandler) => {
  const typedError = error instanceof Error ? error : new Error("Unknown error");
  errorHandler?.(typedError, props);
};
const handleDataUrl = (src) => {
  const [header, base64Data] = src.split(",");
  const mimeType = header.split(":")[1].split(";")[0];
  const extension = mimeType.split("/")[1];
  const byteCharacters = atob(base64Data);
  const byteArray = new Uint8Array(byteCharacters.length);
  for (let i = 0; i < byteCharacters.length; i++) {
    byteArray[i] = byteCharacters.charCodeAt(i);
  }
  const blob = new Blob([byteArray], { type: mimeType });
  return { blob, extension };
};
const handleImageUrl = async (src) => {
  const response = await fetch(src);
  if (!response.ok) throw new Error("Failed to fetch image");
  const blob = await response.blob();
  const extension = blob.type.split(/\/|\+/)[1];
  return { blob, extension };
};
const fetchImageBlob = async (src) => {
  return src.startsWith("data:") ? handleDataUrl(src) : handleImageUrl(src);
};
const saveImage = async (blob, name, extension) => {
  const imageURL = URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = imageURL;
  link.download = `${name}.${extension}`;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(imageURL);
};
const downloadImage = async (props, options) => {
  const { src, alt } = props;
  const potentialName = alt || "image";
  try {
    const { blob, extension } = await fetchImageBlob(src);
    await saveImage(blob, potentialName, extension);
    options.onActionSuccess?.({ ...props, action: "download" });
  } catch (error) {
    handleError(error, { ...props, action: "download" }, options.onActionError);
  }
};
const copyImage = async (props, options) => {
  const { src } = props;
  try {
    const res = await fetch(src);
    const blob = await res.blob();
    await navigator.clipboard.write([new ClipboardItem({ [blob.type]: blob })]);
    options.onActionSuccess?.({ ...props, action: "copyImage" });
  } catch (error) {
    handleError(error, { ...props, action: "copyImage" }, options.onActionError);
  }
};
const copyLink = async (props, options) => {
  const { src } = props;
  try {
    await navigator.clipboard.writeText(src);
    options.onActionSuccess?.({ ...props, action: "copyLink" });
  } catch (error) {
    handleError(error, { ...props, action: "copyLink" }, options.onActionError);
  }
};
const Image = index.Image.extend({
  atom: true,
  addOptions() {
    const parentOptions = this.parent?.() || {};
    return {
      ...parentOptions,
      inline: false,
      allowBase64: false,
      HTMLAttributes: {},
      resize: false,
      allowedMimeTypes: [],
      maxFileSize: 0,
      uploadFn: void 0,
      onToggle: void 0,
      downloadImage: void 0,
      copyImage: void 0,
      copyLink: void 0
    };
  },
  addAttributes() {
    return {
      src: {
        default: null
      },
      alt: {
        default: null
      },
      title: {
        default: null
      },
      id: {
        default: null
      },
      width: {
        default: null
      },
      height: {
        default: null
      },
      fileName: {
        default: null
      }
    };
  },
  addCommands() {
    return {
      setImages: (attrs) => ({ commands }) => {
        const [validImages, errors] = utils.filterFiles(attrs, {
          allowedMimeTypes: this.options.allowedMimeTypes,
          maxFileSize: this.options.maxFileSize,
          allowBase64: this.options.allowBase64
        });
        if (errors.length > 0 && this.options.onValidationError) {
          this.options.onValidationError(errors);
        }
        if (validImages.length > 0) {
          return commands.insertContent(
            validImages.map((image) => {
              if (image.src instanceof File) {
                const blobUrl = URL.createObjectURL(image.src);
                const id = utils.randomId();
                return {
                  type: this.type.name,
                  attrs: {
                    id,
                    src: blobUrl,
                    alt: image.alt,
                    title: image.title,
                    fileName: image.src.name
                  }
                };
              } else {
                return {
                  type: this.type.name,
                  attrs: {
                    id: utils.randomId(),
                    src: image.src,
                    alt: image.alt,
                    title: image.title,
                    fileName: null
                  }
                };
              }
            })
          );
        }
        return false;
      },
      downloadImage: (attrs) => () => {
        const downloadFunc = this.options.downloadImage || downloadImage;
        void downloadFunc({ ...attrs, action: "download" }, this.options);
        return true;
      },
      copyImage: (attrs) => () => {
        const copyImageFunc = this.options.copyImage || copyImage;
        void copyImageFunc({ ...attrs, action: "copyImage" }, this.options);
        return true;
      },
      copyLink: (attrs) => () => {
        const copyLinkFunc = this.options.copyLink || copyLink;
        void copyLinkFunc({ ...attrs, action: "copyLink" }, this.options);
        return true;
      },
      toggleImage: () => ({ editor }) => {
        const input = document.createElement("input");
        input.type = "file";
        input.accept = this.options.allowedMimeTypes.join(",");
        input.onchange = () => {
          const files = input.files;
          if (!files) return;
          const [validImages, errors] = utils.filterFiles(Array.from(files), {
            allowedMimeTypes: this.options.allowedMimeTypes,
            maxFileSize: this.options.maxFileSize,
            allowBase64: this.options.allowBase64
          });
          if (errors.length > 0 && this.options.onValidationError) {
            this.options.onValidationError(errors);
            return false;
          }
          if (validImages.length === 0) return false;
          if (this.options.onToggle) {
            this.options.onToggle(
              editor,
              validImages,
              editor.state.selection.from
            );
          }
          return false;
        };
        input.click();
        return true;
      }
    };
  },
  onTransaction({ transaction }) {
    transaction.steps.forEach((step) => {
      if (step instanceof index$2.ReplaceStep && step.slice.size === 0) {
        const deletedPages = transaction.before.content.cut(step.from, step.to);
        deletedPages.forEach((node) => {
          if (node.type.name === "image") {
            const attrs = node.attrs;
            if (attrs.src.startsWith("blob:")) {
              URL.revokeObjectURL(attrs.src);
            }
            this.options.onImageRemoved?.(attrs);
          }
        });
      }
    });
  },
  addNodeView() {
    return index$1.ReactNodeViewRenderer(imageViewBlock.ImageViewBlock, {
      className: "block-node"
    });
  }
});

exports.Image = Image;
