import { defineComponent, ref, computed, watchEffect, onMounted, createBlock, openBlock, unref, normalizeStyle, normalizeClass, withCtx, createElementBlock, createCommentVNode, Fragment, renderSlot, createVNode, createElementVNode } from "vue";
import { defaultPrestColorPool } from "../_utils/global.mjs";
import HtmlTag from "../_components/html-tag.mjs";
import { OLayer } from "../layer/index.mjs";
import { IconImageError, IconVideoPlay } from "../_utils/icons.mjs";
import { isObject } from "../_utils/is.mjs";
import { useIntersectionObserver } from "../hooks/use-intersection-observer.mjs";
import { useScreen } from "../hooks/use-screen.mjs";
import { figureProps } from "./types.mjs";
import { requestImage } from "../_utils/helper.mjs";
const _hoisted_1 = {
  key: 0,
  class: "o-figure-error-wrap"
};
const _hoisted_2 = ["src", "alt", "loading"];
const _hoisted_3 = ["src", "alt", "loading"];
const _hoisted_4 = {
  key: 1,
  class: "o-figure-main"
};
const _hoisted_5 = {
  key: 0,
  class: "o-figure-mask"
};
const _hoisted_6 = { class: "o-figure-play-icon" };
const _hoisted_7 = {
  key: 1,
  class: "o-figure-content"
};
const _hoisted_8 = { class: "o-figure-title" };
const _hoisted_9 = { class: "o-figure-preview-img" };
const _hoisted_10 = ["src"];
const _sfc_main = /* @__PURE__ */ defineComponent({
  __name: "OFigure",
  props: figureProps,
  emits: ["error", "load", "preview"],
  setup(__props, { expose: __expose, emit: __emit }) {
    const props = __props;
    const emits = __emit;
    const imgRef = ref(null);
    const { isPhonePad } = useScreen();
    const isLoading = ref(true);
    const isError = ref(false);
    const prestColor = props.colorful ? defaultPrestColorPool.value.pick() : "";
    const imgSrc = ref(void 0);
    const bgUrl = computed(() => props.background && imgSrc.value ? `url(${imgSrc.value})` : void 0);
    const useObserver = props.lazy && props.background || isObject(props.lazy);
    const onImgLoaded = () => {
      isLoading.value = false;
      isError.value = false;
      emits("load");
    };
    const onImgError = () => {
      isLoading.value = false;
      isError.value = true;
      emits("error");
    };
    watchEffect(() => {
      if (!props.src) {
        return;
      }
      if (props.lazy === false) {
        imgSrc.value = props.src;
      } else {
        if (!useObserver) {
          imgSrc.value = props.src;
        }
      }
      if (props.background && imgSrc.value) {
        requestImage(imgSrc.value).then(onImgLoaded).catch(onImgError);
      }
    });
    let io = null;
    const rootEl = ref(null);
    onMounted(() => {
      if (imgRef.value && imgRef.value.complete && imgSrc.value) {
        onImgLoaded();
      }
      if (useObserver) {
        io = useIntersectionObserver(isObject(props.lazy) ? props.lazy : {});
        if (rootEl.value) {
          io == null ? void 0 : io.observe(rootEl.value.$el, (entry) => {
            if (entry.isIntersecting) {
              imgSrc.value = props.src;
            }
          });
        }
      }
    });
    const paddingTop = computed(() => {
      if (props.ratio) {
        return `${(1 / props.ratio * 100).toFixed(2)}%`;
      }
      return "";
    });
    const previewVisible = ref(false);
    const canPreview = computed(() => props.preview || props.lazyPreiew);
    const previewCloseTypes = computed(() => {
      if (!props.previewClose) {
        return isPhonePad.value ? ["image", "mask", "button"] : ["mask", "button"];
      } else if (Array.isArray(props.previewClose)) {
        return props.previewClose;
      }
      return [props.previewClose];
    });
    const isMaskClose = computed(() => previewCloseTypes.value.includes("mask"));
    const isButtonClose = computed(() => previewCloseTypes.value.includes("button"));
    const isBodyClose = computed(() => previewCloseTypes.value.includes("body"));
    const preview = (visible = true) => {
      if (canPreview.value) {
        previewVisible.value = visible;
      }
    };
    const onPreviewChange = (visible) => {
      emits("preview", visible);
    };
    const onPreviewImgClick = () => {
      if (isBodyClose.value) {
        previewVisible.value = false;
      }
    };
    const onFigureClick = () => {
      if (props.preview) {
        preview();
      }
    };
    __expose({
      preview
    });
    return (_ctx, _cache) => {
      return openBlock(), createBlock(unref(HtmlTag), {
        tag: !!props.href ? "a" : "div",
        class: normalizeClass(["o-figure", {
          "is-loading": isLoading.value,
          "is-error": isError.value,
          "is-colorful": props.colorful,
          "o-figure-hoverable": props.hoverable || !!props.href || props.preview || props.videoPoster,
          "o-figure-previewable": props.preview,
          "o-figure-video-poster": props.videoPoster
        }]),
        href: props.href,
        style: normalizeStyle({
          "--figure-prest-color": unref(prestColor),
          "--figure-padding-top": paddingTop.value,
          "--figure-fit": props.fit
        }),
        onClick: onFigureClick,
        ref_key: "rootEl",
        ref: rootEl
      }, {
        default: withCtx(() => [
          imgSrc.value ? (openBlock(), createElementBlock(
            Fragment,
            { key: 0 },
            [
              paddingTop.value || isError.value ? (openBlock(), createElementBlock(
                "div",
                {
                  key: 0,
                  class: normalizeClass(["o-figure-wrap", {
                    "o-figure-bg": props.background
                  }]),
                  style: normalizeStyle({
                    backgroundImage: bgUrl.value
                  })
                },
                [
                  isError.value ? (openBlock(), createElementBlock("div", _hoisted_1, [
                    renderSlot(_ctx.$slots, "error", {}, () => [
                      createVNode(unref(IconImageError))
                    ])
                  ])) : !props.background ? (openBlock(), createElementBlock("img", {
                    key: 1,
                    ref_key: "imgRef",
                    ref: imgRef,
                    src: imgSrc.value,
                    alt: props.alt,
                    class: "o-figure-img-ratio",
                    loading: props.lazy === true ? "lazy" : "eager",
                    onLoad: onImgLoaded,
                    onError: onImgError
                  }, null, 40, _hoisted_2)) : createCommentVNode("v-if", true)
                ],
                6
                /* CLASS, STYLE */
              )) : !isError.value ? (openBlock(), createElementBlock("img", {
                key: 1,
                ref_key: "imgRef",
                ref: imgRef,
                src: imgSrc.value,
                alt: props.alt,
                class: "o-figure-img",
                loading: props.lazy === true ? "lazy" : "eager",
                onLoad: onImgLoaded,
                onError: onImgError
              }, null, 40, _hoisted_3)) : createCommentVNode("v-if", true)
            ],
            64
            /* STABLE_FRAGMENT */
          )) : createCommentVNode("v-if", true),
          props.videoPoster || _ctx.$slots.content || _ctx.$slots.title || _ctx.$slots.default ? (openBlock(), createElementBlock("div", _hoisted_4, [
            renderSlot(_ctx.$slots, "default"),
            props.videoPoster ? (openBlock(), createElementBlock("div", _hoisted_5, [
              renderSlot(_ctx.$slots, "play-icon", {}, () => [
                createElementVNode("div", _hoisted_6, [
                  createVNode(unref(IconVideoPlay))
                ])
              ])
            ])) : createCommentVNode("v-if", true),
            _ctx.$slots.content || _ctx.$slots.title ? (openBlock(), createElementBlock("div", _hoisted_7, [
              renderSlot(_ctx.$slots, "content", {}, () => [
                createElementVNode("div", _hoisted_8, [
                  renderSlot(_ctx.$slots, "title")
                ])
              ])
            ])) : createCommentVNode("v-if", true)
          ])) : createCommentVNode("v-if", true),
          canPreview.value ? (openBlock(), createBlock(unref(OLayer), {
            key: 2,
            visible: previewVisible.value,
            "onUpdate:visible": _cache[0] || (_cache[0] = ($event) => previewVisible.value = $event),
            class: "o-figure-preview-layer",
            onChange: onPreviewChange,
            "mask-close": isMaskClose.value,
            "button-close": isButtonClose.value
          }, {
            default: withCtx(() => [
              createElementVNode("div", {
                class: "o-figure-preview-wrapper",
                onClick: onPreviewImgClick
              }, [
                renderSlot(_ctx.$slots, "preview", { image: imgSrc.value }, () => [
                  createElementVNode("div", _hoisted_9, [
                    createElementVNode("img", { src: imgSrc.value }, null, 8, _hoisted_10)
                  ]),
                  renderSlot(_ctx.$slots, "preview-extra")
                ])
              ])
            ]),
            _: 3
            /* FORWARDED */
          }, 8, ["visible", "mask-close", "button-close"])) : createCommentVNode("v-if", true)
        ]),
        _: 3
        /* FORWARDED */
      }, 8, ["tag", "href", "class", "style"]);
    };
  }
});
export {
  _sfc_main as default
};
