<template>
	<view class="img-upload">
		<text v-if="label" class="img-upload__label">{{ label }}</text>
		<view class="img-upload__box" @click="chooseImage">
			<image
				v-if="displayUrl"
				class="img-upload__preview"
				:src="displayUrl"
				mode="aspectFill"
			/>
			<view v-else class="img-upload__placeholder">
				<u-icon name="camera-fill" color="#9a938c" size="40" />
				<text class="img-upload__tip">{{ placeholder }}</text>
			</view>
			<view v-if="uploading" class="img-upload__mask">
				<text>上传中…</text>
			</view>
		</view>
	</view>
</template>

<script setup>
import { ref, computed } from 'vue'
import { joinApiUrl } from '@/config'
import { uploadFile } from '@/utils/upload'

const props = defineProps({
	modelValue: { type: String, default: '' },
	label: { type: String, default: '' },
	placeholder: { type: String, default: '点击上传' }
})

const emit = defineEmits(['update:modelValue'])

const uploading = ref(false)

const displayUrl = computed(() => {
  const v = props.modelValue || ''
  if (!v) return ''
  if (/^https?:\/\//i.test(v)) return v
  return joinApiUrl(v)
})

function chooseImage() {
  if (uploading.value) return
  uni.chooseImage({
    count: 1,
    sizeType: ['compressed'],
    success: (res) => {
      const path = res.tempFilePaths && res.tempFilePaths[0]
      if (!path) return
      uploading.value = true
      uploadFile(path)
        .then((url) => {
          emit('update:modelValue', url)
        })
        .catch((e) => {
          uni.showToast({ title: e.message || '上传失败', icon: 'none' })
        })
        .finally(() => {
          uploading.value = false
        })
    }
  })
}
</script>

<style lang="scss" scoped>
.img-upload {
  padding: 16rpx 0;
}
.img-upload__label {
  display: block;
  margin-bottom: 12rpx;
  font-size: 28rpx;
  color: #5c5652;
}
.img-upload__box {
  position: relative;
  width: 200rpx;
  height: 200rpx;
  border-radius: 12rpx;
  background: #f5f2ef;
  overflow: hidden;
}
.img-upload__preview {
  width: 100%;
  height: 100%;
}
.img-upload__placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8rpx;
}
.img-upload__tip {
  font-size: 22rpx;
  color: #9a938c;
}
.img-upload__mask {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.45);
  color: #fff;
  font-size: 24rpx;
}
</style>
