<template>
	<view class="image-preview" :style="wrapStyle" @click="onTap">
		<image
			v-if="showImage"
			class="image-preview__img"
			:src="realSrc"
			:mode="mode"
			@error="onError"
			@load="onLoad"
		/>
		<view v-else class="image-preview__slot">
			<image
				v-if="placeholder"
				class="image-preview__img"
				:src="placeholder"
				:mode="mode"
			/>
			<u-icon v-else name="photo" color="#c0c4cc" :size="iconSize" />
		</view>
	</view>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { resolveFileUrl, resolveFileUrlList } from '@/utils/image'

const props = defineProps({
	/** 后端路径或逗号分隔多图（展示首张） */
	src: {
		type: String,
		default: ''
	},
	width: {
		type: [String, Number],
		default: ''
	},
	height: {
		type: [String, Number],
		default: ''
	},
	mode: {
		type: String,
		default: 'aspectFill'
	},
	/** 无图或加载失败时的占位图；默认空则显示灰色图标（避免误显示 logo） */
	placeholder: {
		type: String,
		default: ''
	},
	/** 点击预览大图 */
	preview: {
		type: Boolean,
		default: false
	},
	/** 预览列表；不传则从 src 逗号拆分 */
	previewList: {
		type: Array,
		default: () => []
	},
	previewIndex: {
		type: Number,
		default: 0
	},
	iconSize: {
		type: [String, Number],
		default: 28
	}
})

const loadFailed = ref(false)

const realSrc = computed(() => {
	if (!props.src) return ''
	return resolveFileUrl(props.src)
})

const resolvedPreviewList = computed(() => {
	if (props.previewList && props.previewList.length) {
		return resolveFileUrlList(props.previewList)
	}
	return resolveFileUrlList(props.src)
})

const showImage = computed(() => !!(realSrc.value && !loadFailed.value))

const wrapStyle = computed(() => {
	const style = {}
	if (props.width !== '' && props.width != null) {
		style.width = formatSize(props.width)
	}
	if (props.height !== '' && props.height != null) {
		style.height = formatSize(props.height)
	}
	return style
})

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

function formatSize(val) {
	if (typeof val === 'number') {
		return `${val}rpx`
	}
	const s = String(val)
	if (/^\d+$/.test(s)) {
		return `${s}rpx`
	}
	return s
}

function onError() {
	loadFailed.value = true
}

function onLoad() {
	loadFailed.value = false
}

function onTap() {
	if (!props.preview) return
	const urls = resolvedPreviewList.value
	if (!urls.length) return
	const idx = Math.min(Math.max(props.previewIndex, 0), urls.length - 1)
	uni.previewImage({
		urls,
		current: urls[idx]
	})
}
</script>

<style lang="scss" scoped>
.image-preview {
	display: block;
	width: 100%;
	height: 100%;
	overflow: hidden;
	background: #ebeef5;
}
.image-preview__img {
	width: 100%;
	height: 100%;
	display: block;
}
.image-preview__slot {
	width: 100%;
	height: 100%;
	display: flex;
	align-items: center;
	justify-content: center;
	background: #ebeef5;
}
</style>
