'use strict';

const jsxRuntime = require('react/jsx-runtime');
const React = require('react');
const index = 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 useDragResize = require('../hooks/use-drag-resize.cjs');
const resizeHandle = require('./resize-handle.cjs');
const utils = require('../../../../../lib/utils.cjs');
const index$1 = require('../../../../../../../../node_modules/.pnpm/react-medium-image-zoom@5.4.0_react-dom@19.2.0_react@19.2.0__react@19.2.0/node_modules/react-medium-image-zoom/dist/index.cjs');
const imageActions = require('./image-actions.cjs');
const useImageActions = require('../hooks/use-image-actions.cjs');
const utils$1 = require('../../../utils.cjs');
const reactIcons_esm = require('../../../../../../../../node_modules/.pnpm/@radix-ui_react-icons@1.3.2_react@19.2.0/node_modules/@radix-ui/react-icons/dist/react-icons.esm.cjs');
const imageOverlay = require('./image-overlay.cjs');
const spinner = require('../../../components/spinner.cjs');

function _interopNamespaceCompat(e) {
  if (e && typeof e === 'object' && 'default' in e) return e;
  const n = Object.create(null);
  if (e) {
    for (const k in e) {
      n[k] = e[k];
    }
  }
  n.default = e;
  return n;
}

const React__namespace = /*#__PURE__*/_interopNamespaceCompat(React);

const MAX_HEIGHT = 600;
const MIN_HEIGHT = 120;
const MIN_WIDTH = 120;
const normalizeUploadResponse = (res) => ({
  src: typeof res === "string" ? res : res.src,
  id: typeof res === "string" ? utils$1.randomId() : res.id
});
const ImageViewBlock = ({
  editor,
  node,
  selected,
  updateAttributes
}) => {
  const {
    src: initialSrc,
    width: initialWidth,
    height: initialHeight,
    fileName
  } = node.attrs;
  const uploadAttemptedRef = React__namespace.useRef(false);
  const initSrc = React__namespace.useMemo(() => {
    if (typeof initialSrc === "string") {
      return initialSrc;
    }
    return initialSrc.src;
  }, [initialSrc]);
  const [imageState, setImageState] = React__namespace.useState({
    src: initSrc,
    isServerUploading: false,
    imageLoaded: false,
    isZoomed: false,
    error: false,
    naturalSize: { width: initialWidth, height: initialHeight }
  });
  const containerRef = React__namespace.useRef(null);
  const [activeResizeHandle, setActiveResizeHandle] = React__namespace.useState(null);
  const onDimensionsChange = React__namespace.useCallback(
    ({ width, height }) => {
      updateAttributes({ width, height });
    },
    [updateAttributes]
  );
  const aspectRatio = React__namespace.useMemo(() => {
    const { width, height } = imageState.naturalSize;
    if (!height || height <= 0 || !width || width <= 0) {
      return 1;
    }
    return width / height;
  }, [imageState.naturalSize]);
  const maxWidth = MAX_HEIGHT * aspectRatio;
  const containerMaxWidth = containerRef.current ? parseFloat(
    getComputedStyle(containerRef.current).getPropertyValue(
      "--editor-width"
    )
  ) : Infinity;
  const { isLink, onView, onDownload, onCopy, onCopyLink, onRemoveImg } = useImageActions.useImageActions({
    editor,
    node,
    src: imageState.src,
    onViewClick: (isZoomed) => setImageState((prev) => ({ ...prev, isZoomed }))
  });
  const {
    currentWidth,
    currentHeight,
    updateDimensions,
    initiateResize,
    isResizing
  } = useDragResize.useDragResize({
    initialWidth: initialWidth ?? imageState.naturalSize.width,
    initialHeight: initialHeight ?? imageState.naturalSize.height,
    contentWidth: imageState.naturalSize.width,
    contentHeight: imageState.naturalSize.height,
    gridInterval: 0.1,
    onDimensionsChange,
    minWidth: MIN_WIDTH,
    minHeight: MIN_HEIGHT,
    maxWidth: containerMaxWidth > 0 ? containerMaxWidth : maxWidth
  });
  const shouldMerge = React__namespace.useMemo(() => currentWidth <= 180, [currentWidth]);
  const handleImageLoad = React__namespace.useCallback(
    (ev) => {
      const img = ev.target;
      const newNaturalSize = {
        width: img.naturalWidth,
        height: img.naturalHeight
      };
      setImageState((prev) => ({
        ...prev,
        naturalSize: newNaturalSize,
        imageLoaded: true
      }));
      updateAttributes({
        width: img.width || newNaturalSize.width,
        height: img.height || newNaturalSize.height,
        alt: img.alt,
        title: img.title
      });
      if (!initialWidth) {
        updateDimensions((state) => ({ ...state, width: newNaturalSize.width }));
      }
    },
    [initialWidth, updateAttributes, updateDimensions]
  );
  const handleImageError = React__namespace.useCallback(() => {
    setImageState((prev) => ({ ...prev, error: true, imageLoaded: true }));
  }, []);
  const handleResizeStart = React__namespace.useCallback(
    (direction) => (event) => {
      setActiveResizeHandle(direction);
      initiateResize(direction)(event);
    },
    [initiateResize]
  );
  const handleResizeEnd = React__namespace.useCallback(() => {
    setActiveResizeHandle(null);
  }, []);
  React__namespace.useEffect(() => {
    if (!isResizing) {
      handleResizeEnd();
    }
  }, [isResizing, handleResizeEnd]);
  React__namespace.useEffect(() => {
    const handleImage = async () => {
      if (!initSrc.startsWith("blob:") || uploadAttemptedRef.current) {
        return;
      }
      uploadAttemptedRef.current = true;
      const imageExtension = editor.options.extensions.find(
        (ext) => ext.name === "image"
      );
      const { uploadFn } = imageExtension?.options ?? {};
      if (!uploadFn) {
        try {
          const base64 = await utils$1.blobUrlToBase64(initSrc);
          setImageState((prev) => ({ ...prev, src: base64 }));
          updateAttributes({ src: base64 });
        } catch {
          setImageState((prev) => ({ ...prev, error: true }));
        }
        return;
      }
      try {
        setImageState((prev) => ({ ...prev, isServerUploading: true }));
        const response = await fetch(initSrc);
        const blob = await response.blob();
        const file = new File([blob], fileName, { type: blob.type });
        const url = await uploadFn(file, editor);
        const normalizedData = normalizeUploadResponse(url);
        setImageState((prev) => ({
          ...prev,
          ...normalizedData,
          isServerUploading: false
        }));
        updateAttributes(normalizedData);
      } catch {
        setImageState((prev) => ({
          ...prev,
          error: true,
          isServerUploading: false
        }));
      }
    };
    handleImage();
  }, [editor, fileName, initSrc, updateAttributes]);
  return /* @__PURE__ */ jsxRuntime.jsx(
    index.NodeViewWrapper,
    {
      ref: containerRef,
      "data-drag-handle": true,
      className: "relative text-center leading-none",
      children: /* @__PURE__ */ jsxRuntime.jsx(
        "div",
        {
          className: "group/node-image relative mx-auto rounded-md object-contain",
          style: {
            maxWidth: `min(${maxWidth}px, 100%)`,
            width: currentWidth,
            maxHeight: MAX_HEIGHT,
            aspectRatio: `${aspectRatio}`
          },
          children: /* @__PURE__ */ jsxRuntime.jsxs(
            "div",
            {
              className: utils.cn(
                "relative flex h-full cursor-default flex-col items-center gap-2 rounded",
                {
                  "outline-primary outline-2 outline-offset-1": selected || isResizing
                }
              ),
              children: [
                /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full contain-paint", children: [
                  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-full", children: [
                    imageState.isServerUploading && !imageState.error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(spinner.Spinner, { className: "size-7" }) }),
                    imageState.error && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute inset-0 flex flex-col items-center justify-center", children: [
                      /* @__PURE__ */ jsxRuntime.jsx(reactIcons_esm.InfoCircledIcon, { className: "text-destructive size-8" }),
                      /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mt-2 text-sm", children: "Failed to load image" })
                    ] }),
                    /* @__PURE__ */ jsxRuntime.jsx(
                      index$1.Controlled,
                      {
                        isZoomed: imageState.isZoomed,
                        onZoomChange: () => setImageState((prev) => ({ ...prev, isZoomed: false })),
                        children: /* @__PURE__ */ jsxRuntime.jsx(
                          "img",
                          {
                            className: utils.cn(
                              "h-auto rounded object-contain transition-shadow",
                              {
                                "opacity-0": !imageState.imageLoaded || imageState.error
                              }
                            ),
                            style: {
                              maxWidth: `min(100%, ${maxWidth}px)`,
                              minWidth: `${MIN_WIDTH}px`,
                              maxHeight: MAX_HEIGHT
                            },
                            width: currentWidth,
                            height: currentHeight,
                            src: imageState.src,
                            onError: handleImageError,
                            onLoad: handleImageLoad,
                            alt: node.attrs.alt || "",
                            title: node.attrs.title || "",
                            id: node.attrs.id
                          }
                        )
                      }
                    )
                  ] }),
                  imageState.isServerUploading && /* @__PURE__ */ jsxRuntime.jsx(imageOverlay.ImageOverlay, {}),
                  editor.isEditable && imageState.imageLoaded && !imageState.error && !imageState.isServerUploading && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
                    /* @__PURE__ */ jsxRuntime.jsx(
                      resizeHandle.ResizeHandle,
                      {
                        onPointerDown: handleResizeStart("left"),
                        className: utils.cn("left-1", {
                          hidden: isResizing && activeResizeHandle === "right"
                        }),
                        isResizing: isResizing && activeResizeHandle === "left"
                      }
                    ),
                    /* @__PURE__ */ jsxRuntime.jsx(
                      resizeHandle.ResizeHandle,
                      {
                        onPointerDown: handleResizeStart("right"),
                        className: utils.cn("right-1", {
                          hidden: isResizing && activeResizeHandle === "left"
                        }),
                        isResizing: isResizing && activeResizeHandle === "right"
                      }
                    )
                  ] })
                ] }),
                imageState.error && /* @__PURE__ */ jsxRuntime.jsx(imageActions.ActionWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(
                  imageActions.ActionButton,
                  {
                    icon: /* @__PURE__ */ jsxRuntime.jsx(reactIcons_esm.TrashIcon, {}),
                    tooltip: "Remove image",
                    onClick: onRemoveImg
                  }
                ) }),
                !isResizing && !imageState.error && !imageState.isServerUploading && /* @__PURE__ */ jsxRuntime.jsx(
                  imageActions.ImageActions,
                  {
                    shouldMerge,
                    isLink,
                    onView,
                    onDownload,
                    onCopy,
                    onCopyLink
                  }
                )
              ]
            }
          )
        }
      )
    }
  );
};

exports.ImageViewBlock = ImageViewBlock;
