<template>
  <figure :class="ui.root({ class: [props.ui?.root, props.class] })">
    <div
      v-if="lqip || color"
      :class="ui.lqip({ class: props.ui?.lqip })"
      :style="{
  backgroundColor: color,
  backgroundImage: lqip ? `url(${lqip})` : void 0
}"
    />
    <picture :class="ui.picture({ class: props.ui?.picture })" :style="{ aspectRatio }">
      <template v-if="sources.length">
        <source
          v-for="(source, key) in sources"
          :key="key"
          :srcset="source.srcset"
          :type="source.type"
        >
      </template>

      <img
        ref="imageRef"
        v-bind="imageAttrs"
        :src="image.img"
        :srcset="image?.srcset"
        :alt="alt"
        :loading="loading"
        :class="ui.img({ class: props.ui?.img })"
      >
    </picture>
  </figure>
</template>

<script>
import theme from "#build/cms/uplora-image";
import { useAppConfig, useCmsConfig, useHead, useNuxtApp } from "#imports";
import { computed, onMounted, useTemplateRef } from "vue";
import { tv } from "../tv";
import { buildUploraImage } from "../utils";
</script>

<script setup>
const props = defineProps({
  image: { type: [String, Object], required: true },
  alt: { type: String, required: false },
  formats: { type: Array, required: false },
  sizes: { type: Array, required: false },
  lqip: { type: String, required: false },
  color: { type: String, required: false },
  aspect: { type: String, required: false, default: "horizontal" },
  width: { type: [Number, String], required: false },
  height: { type: [Number, String], required: false },
  loading: { type: String, required: false, default: "lazy" },
  preload: { type: [Boolean, Object], required: false },
  nonce: { type: String, required: false },
  imgAttrs: { type: Object, required: false },
  class: { type: null, required: false },
  ui: { type: null, required: false }
});
const emit = defineEmits(["load", "error"]);
const appConfig = useAppConfig();
const cmsConfig = useCmsConfig();
const nuxtApp = useNuxtApp();
const initialLoad = nuxtApp.isHydrating;
const image = computed(() => typeof props.image === "string" ? buildUploraImage({
  id: props.image,
  formats: props.formats ?? cmsConfig?.components?.uploraImage?.formats,
  sizes: props.sizes
}) : props.image);
const sources = computed(() => {
  if (image.value.sources.length > 1) {
    return image.value.sources.slice(1);
  }
  return [];
});
if (import.meta.server && props.preload) {
  useHead({ link: () => {
    if (!image.value.img) {
      return [];
    }
    const link = {
      rel: "preload",
      as: "image",
      imagesrcset: image.value.srcset,
      nonce: props.nonce,
      ...typeof props.preload !== "boolean" && props.preload?.fetchPriority ? { fetchpriority: props.preload.fetchPriority } : {}
    };
    return [link];
  } });
}
const imageRef = useTemplateRef("imageRef");
const imageAttrs = computed(() => ({
  ...props.imgAttrs || {},
  ...import.meta.server ? { onerror: "this.setAttribute('data-error', 1)" } : {}
}));
const aspectRatio = computed(() => {
  if (props.aspect === "dynamic" && props.width && props.height) {
    return Number.parseInt(props.width) / Number(props.height);
  }
  return void 0;
});
onMounted(() => {
  if (!imageRef.value) {
    return;
  }
  if (imageRef.value.complete && initialLoad) {
    if (imageRef.value.getAttribute("data-error")) {
      emit("error", new Event("error"));
    } else {
      emit("load", new Event("load"));
    }
  }
  imageRef.value.onload = (event) => {
    emit("load", event);
  };
  imageRef.value.onerror = (event) => {
    emit("error", event);
  };
});
const ui = computed(() => tv({ extend: tv(theme), ...appConfig.cms?.uploraImage || {} })({
  aspect: props.aspect
}));
</script>
