<script setup>
import { getImageDefaultAltLabel } from '../../lib/markdown-image.js'

const props = defineProps({
  src: {
    type: String,
    default: ''
  },
  alt: {
    type: String,
    default: ''
  },
  /** 이미지 아래 표시용 캡션 */
  caption: {
    type: String,
    default: ''
  },
  variant: {
    type: String,
    default: 'regular'
  }
})

const loadFailed = ref(false)

const hasRenderableSrc = computed(() => String(props.src || '').trim().length > 0)

const errorLabel = computed(() => {
  const trimmed = String(props.src || '').trim()

  if (!trimmed) {
    return '이미지 URL이 비어 있습니다'
  }

  const filename = getImageDefaultAltLabel(trimmed)

  return filename ? `이미지를 불러올 수 없습니다 · ${filename}` : '이미지를 불러올 수 없습니다'
})

watch(() => props.src, () => {
  loadFailed.value = false
})

/**
 * 이미지 로드 실패 시 placeholder를 표시한다.
 * @returns {void}
 */
const onImageError = () => {
  loadFailed.value = true
}

/**
 * 이미지 로드 성공 시 오류 상태를 해제한다.
 * @returns {void}
 */
const onImageLoad = () => {
  loadFailed.value = false
}
</script>

<template>
  <figure
    class="prose-image mb-2.5"
    :class="{
      'prose-image--wide lg:-mx-10 lg:max-w-none': variant === 'wide',
      'prose-image--full lg:-mx-20 lg:max-w-none': variant === 'full'
    }"
  >
    <div
      class="prose-image__frame overflow-hidden rounded-[10px] border border-[var(--site-line)] bg-[var(--site-panel)]"
      :class="{
        'prose-image__frame--empty': !hasRenderableSrc || loadFailed,
        'prose-image__frame--broken': loadFailed
      }"
    >
      <img
        v-if="hasRenderableSrc && !loadFailed"
        class="prose-image__media w-full object-cover"
        :src="src"
        :alt="alt"
        @load="onImageLoad"
        @error="onImageError"
      >
      <div
        v-else
        class="prose-image__placeholder flex min-h-[180px] flex-col items-center justify-center gap-2 px-4 py-6 text-center"
        role="img"
        :aria-label="errorLabel"
      >
        <span class="prose-image__placeholder-icon text-2xl text-[var(--site-muted)]" aria-hidden="true">!</span>
        <p class="prose-image__placeholder-text max-w-full break-all text-sm text-[var(--site-muted)]">
          {{ errorLabel }}
        </p>
      </div>
    </div>
    <figcaption
      v-if="caption"
      class="prose-image__caption mt-1.5 text-center text-sm text-[var(--site-muted)]"
    >
      {{ caption }}
    </figcaption>
  </figure>
</template>

<style scoped>
.prose-image__frame--empty,
.prose-image__frame--broken {
  min-height: 180px;
}

.prose-image__frame:not(.prose-image__frame--empty):not(.prose-image__frame--broken) {
  min-height: 120px;
}

.prose-image__placeholder-icon {
  display: inline-flex;
  height: 2.5rem;
  width: 2.5rem;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  border: 1px dashed var(--site-line);
  background: color-mix(in srgb, var(--site-panel) 88%, #fff 12%);
  font-weight: 700;
}
</style>
