<!--
 * @Author: LiZhiWei
 * @Date: 2025-04-24 15:29:17
 * @LastEditors: LiZhiWei
 * @LastEditTime: 2025-12-30 12:45:42
 * @Description: 
-->
<template>
  <div>
    <slot
      name="image"
      :src="srcList[0]"
      :src-list="srcList"
      :index="index"
      :preview="previewApi"
    >
      <img v-if="srcList[0]" class="image" :src="srcList[0]" alt="" @click="open(0)" />
    </slot>

    <div v-if="visible" class="viewfile-image-preview" @click.self="close">
      <button class="viewfile-image-preview-close" type="button" @click="close">×</button>
      <button v-if="srcList.length > 1" class="viewfile-image-preview-prev" type="button" @click.stop="prev">‹</button>
      <img class="viewfile-image-preview-img" :src="srcList[index]" alt="" />
      <button v-if="srcList.length > 1" class="viewfile-image-preview-next" type="button" @click.stop="next">›</button>
    </div>
  </div>
</template>

<script setup>
import { computed, onBeforeUnmount, onMounted, ref } from "vue"

const props = defineProps({
  image: String,
  srcList: Array,
})

const visible = ref(false)
const index = ref(0)

const srcList = computed(() => {
  const list = Array.isArray(props.srcList) ? props.srcList : []
  if (list.length) return list.map((v) => String(v || "")).filter(Boolean)
  const src = String(props.image || "")
  return src ? [src] : []
})

const previewApi = computed(() => {
  return {
    visible: visible.value,
    open,
    close,
    next,
    prev,
  }
})

function open(i = 0) {
  if (!srcList.value.length) return
  index.value = Math.max(0, Math.min(srcList.value.length - 1, Number(i) || 0))
  visible.value = true
}

function close() {
  visible.value = false
}

function next() {
  if (srcList.value.length <= 1) return
  index.value = (index.value + 1) % srcList.value.length
}

function prev() {
  if (srcList.value.length <= 1) return
  index.value = (index.value - 1 + srcList.value.length) % srcList.value.length
}

function onKeydown(e) {
  if (!visible.value) return
  if (e.key === "Escape") close()
  if (e.key === "ArrowRight") next()
  if (e.key === "ArrowLeft") prev()
}

onMounted(() => {
  window.addEventListener("keydown", onKeydown)
})

onBeforeUnmount(() => {
  window.removeEventListener("keydown", onKeydown)
})
</script>

<style scoped>
.image {
  display: block;
  width: auto;
  height: 100%;
  margin: 0 auto;
}

.viewfile-image-preview {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.72);
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
}

.viewfile-image-preview-img {
  max-width: calc(100vw - 120px);
  max-height: calc(100vh - 120px);
  object-fit: contain;
  display: block;
}

.viewfile-image-preview-close,
.viewfile-image-preview-prev,
.viewfile-image-preview-next {
  position: absolute;
  border: 0;
  background: rgba(0, 0, 0, 0.36);
  color: #fff;
  cursor: pointer;
  line-height: 1;
}

.viewfile-image-preview-close {
  right: 16px;
  top: 16px;
  width: 40px;
  height: 40px;
  border-radius: 20px;
  font-size: 28px;
}

.viewfile-image-preview-prev,
.viewfile-image-preview-next {
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  border-radius: 22px;
  font-size: 28px;
}

.viewfile-image-preview-prev {
  left: 16px;
}

.viewfile-image-preview-next {
  right: 16px;
}
</style>
