<template>
	<view class="image-upload-container">
		<view class="upload-list">
			<view class="upload-item" v-for="(item, index) in value" :key="index">
				<u-image :src="item" width="160rpx" height="160rpx" border-radius="8"
					@click="onPreview(index)"></u-image>
				<view class="delete-btn" @click.stop="onDelete(index)">
					<u-icon name="close" color="#ffffff" size="20"></u-icon>
				</view>
			</view>
			<view class="upload-btn" v-if="value.length < maxCount" @click="onChoose"
				:style="{ backgroundColor: bgColor }">
				<u-icon name="camera" size="48" color="#909399"></u-icon>
				<text class="btn-text">图片/视频</text>
			</view>
		</view>
		<view class="upload-tip" v-if="tip">
			<u-icon name="info-circle" size="24" color="#909399"></u-icon>
			<text class="tip-text">{{ tip }}</text>
		</view>
	</view>
</template>

<script>
	export default {
		name: 'CommonImageUpload',
		props: {
			value: {
				type: Array,
				default: () => []
			},
			maxCount: {
				type: Number,
				default: 9
			},
			bgColor: {
				type: String,
				default: '#f4f5f6'
			},
			uploadUrl: {
				type: String,
				required: true
			},
			header: {
				type: Object,
				default: () => ({})
			},
			name: {
				type: String,
				default: 'file'
			},
			tip: {
				type: String,
				default: ''
			}
		},
		methods: {
			onChoose() {
				uni.chooseImage({
					count: this.maxCount - this.value.length,
					success: async (res) => {
						uni.showLoading({
							title: '上传中...'
						});
						const tempFilePaths = res.tempFilePaths;
						const uploadPromises = tempFilePaths.map(path => {
							return this.uploadFileAjax(path);
						});

						try {
							const results = await Promise.all(uploadPromises);
							const newList = [...this.value, ...results];
							this.$emit('input', newList);
							uni.hideLoading();
						} catch (e) {
							uni.hideLoading();
							uni.showToast({
								title: e.msg || '上传失败',
								icon: 'none'
							});
							console.error(e);
						}
					}
				});
			},
			uploadFileAjax(filePath) {
				return new Promise((resolve, reject) => {
					// 合并 header，确保 token 存在
					const header = {
						'Authorization': uni.getStorageSync('token') || '',
						...this.header
					};

					// 处理 URL，如果传入的是完整 URL 则直接使用，否则拼接 baseUrl
					let url = this.uploadUrl;
					if (!url.startsWith('http')) {
						url = uni.$u.http.config.baseUrl + url;
					}

					uni.uploadFile({
						url: url,
						filePath: filePath,
						name: this.name,
						header: header,
						success: (res) => {
							try {
								const data = JSON.parse(res.data);
								if (data.code == 200) {
									resolve(data.data);
								} else {
									reject(data);
								}
							} catch (e) {
								reject({ msg: '解析失败' });
							}
						},
						fail: (err) => {
							reject(err);
						}
					});
				});
			},

			onDelete(index) {
				const newList = [...this.value];
				newList.splice(index, 1);
				this.$emit('input', newList);
			},
			onPreview(index) {
				uni.previewImage({
					urls: this.value,
					current: index
				});
			}
		}
	}
</script>

<style lang="scss" scoped>
	.image-upload-container {
		width: 100%;
	}

	.upload-list {
		display: flex;
		flex-wrap: wrap;
		margin: 0 -10rpx;
	}

	.upload-item,
	.upload-btn {
		width: 160rpx;
		height: 160rpx;
		margin: 10rpx;
		border-radius: 8rpx;
		position: relative;
	}

	.upload-btn {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;

		.btn-text {
			font-size: 24rpx;
			color: #909399;
			margin-top: 10rpx;
		}
	}

	.delete-btn {
		position: absolute;
		top: 0;
		right: 0;
		width: 40rpx;
		height: 40rpx;
		background-color: rgba(0, 0, 0, 0.5);
		border-bottom-left-radius: 8rpx;
		border-top-right-radius: 8rpx;
		display: flex;
		align-items: center;
		justify-content: center;
		z-index: 1;
	}

	.upload-tip {
		margin-top: 20rpx;
		display: flex;
		align-items: center;

		.tip-text {
			font-size: 24rpx;
			color: #909399;
			margin-left: 10rpx;
		}
	}
</style>
