<script>
import theme from "#build/b24ui/avatar";
</script>

<script setup>
import { ref, computed, watch } from "vue";
import { Primitive, Slot } from "reka-ui";
import { defu } from "defu";
import { useAppConfig } from "#imports";
import ImageComponent from "#build/b24ui-image-component";
import { useComponentProps } from "../composables/useComponentProps";
import { useAvatarGroup } from "../composables/useAvatarGroup";
import { tv } from "../utils/tv";
import B24Chip from "./Chip.vue";
defineOptions({ inheritAttrs: false });
const _props = defineProps({
  as: { type: null, required: false },
  src: { type: String, required: false },
  alt: { type: String, required: false },
  icon: { type: [Function, Object], required: false },
  text: { type: String, required: false },
  size: { type: null, required: false },
  color: { type: null, required: false },
  chip: { type: [Boolean, Object], required: false },
  class: { type: null, required: false },
  style: { type: null, required: false },
  b24ui: { type: Object, required: false }
});
const props = useComponentProps("avatar", _props);
const as = computed(() => {
  if (typeof props.as === "string" || typeof props.as?.render === "function") {
    return { root: props.as };
  }
  return defu(props.as, { root: "span" });
});
const fallback = computed(
  () => props.text || (props.alt || "").replace(/[+\-*)(}\][{]/g, "").split(" ").map((word) => word.charAt(0)).join("").substring(0, 2)
);
const appConfig = useAppConfig();
const { size, color } = useAvatarGroup(_props);
const b24ui = computed(() => tv({ extend: theme, ...appConfig.b24ui?.avatar || {} })({
  size: size.value ?? props.size,
  color: color.value ?? props.color
}));
const rootClass = computed(() => b24ui.value.root({ class: [props.b24ui?.root, props.class] }));
const sizePx = computed(() => {
  const sizeClass = (rootClass.value || "").split(" ").find((c) => /^size-\d+$/.test(c));
  if (sizeClass) {
    const num = Number.parseFloat(sizeClass.split("-")[1] ?? "");
    if (!Number.isNaN(num)) return num * 4;
  }
  return null;
});
const error = ref(false);
watch(() => props.src, () => {
  if (error.value) {
    error.value = false;
  }
});
function onError() {
  error.value = true;
}
</script>

<template>
  <component
    :is="props.chip ? B24Chip : Primitive"
    :as="as.root"
    v-bind="props.chip ? typeof props.chip === 'object' ? { inset: true, ...props.chip } : { inset: true } : {}"
    data-slot="root"
    :class="rootClass"
    :style="props.style"
  >
    <component
      :is="as.img || ImageComponent"
      v-if="props.src && !error"
      :src="props.src"
      :alt="props.alt"
      :width="sizePx"
      :height="sizePx"
      v-bind="$attrs"
      data-slot="image"
      :class="b24ui.image({ class: props.b24ui?.image })"
      @error="onError"
    />

    <Slot v-else v-bind="$attrs">
      <slot>
        <Component :is="props.icon" v-if="props.icon" data-slot="icon" :class="b24ui.icon({ class: props.b24ui?.icon })" />
        <span v-else data-slot="fallback" :class="b24ui.fallback({ class: props.b24ui?.fallback })">{{ fallback || "\xA0" }}</span>
      </slot>
    </Slot>
  </component>
</template>
