<template>
	<view class="avatar-uploader">
		<view class="avatar-wrapper" @click="onOpenSheet">
			<image class="avatar-image" :src="modelValue || placeholder" mode="aspectFill"></image>
			<slot name="badge">
				<image class="avatar-badge" :src="badgeIcon" mode="aspectFit" v-if="badgeIcon"></image>
			</slot>
		</view>

		<!-- 底部选择弹窗 -->
		<view class="action-sheet" v-if="internalVisible" @click="hideActionSheet">
			<view class="action-sheet-content" @click.stop>
				<view class="action-sheet-item" @click="handleChoose('camera')">
					<text class="action-sheet-text">{{ $i18n.t('takePhoto') }}</text>
				</view>
				<view class="action-sheet-item" @click="handleChoose('album')">
					<text class="action-sheet-text">{{ $i18n.t('chooseFromAlbum') }}</text>
				</view>
				<view class="action-sheet-cancel" @click="hideActionSheet">
					<text class="action-sheet-text">{{ $i18n.t('actionSheetCancel') }}</text>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
export default {
	name: 'AvatarUploader',
	props: {
		modelValue: {
			type: String,
			default: ''
		},
		qiniuToken: {
			type: String,
			default: ''
		},
		qiniuUploadUrl: {
			type: String,
			default: 'https://up-z2.qiniup.com'
		},
		qiniuKeyPrefix: {
			type: String,
			default: 'smartmeter/img/'
		},
		placeholder: {
			type: String,
			default: ''
		},
		badgeIcon: {
			type: String,
			default: ''
		}
	},
	data() {
		return {
			internalVisible: false
		}
	},
	methods: {
		// 点击显示上传方式
		onOpenSheet() {
			this.$emit('open');
			this.internalVisible = true;
		},
		// 点击隐藏上传方式
		hideActionSheet() {
			this.internalVisible = false;
			this.$emit('close');
		},
		// 上传图片
		handleChoose(source) {
			this.hideActionSheet();
			const sourceType = source === 'camera' ? ['camera'] : ['album'];
			uni.chooseImage({
				count: 1,
				sizeType: ['compressed'],
				sourceType,
				success: (imgRes) => {
					const tempPath = imgRes.tempFilePaths[0]
					this.uploadToQiniu(tempPath)
				},
				fail: (err) => {
					console.error('chooseImage failed:', err)
					uni.showToast({
						title: this.$i18n.t('imageOperationCancelled'),
						icon: 'none',
						duration: 3000
					})
				}
			})
		},
		uploadToQiniu(filePath) {
			if (!this.qiniuToken) {
				uni.showToast({ title: this.$i18n.t('uploadFailed'), icon: 'none' })
				return;
			}
			const key = this.qiniuKeyPrefix + this.generateGuid(20)
			uni.uploadFile({
				url: this.qiniuUploadUrl,
				name: 'file',
				filePath,
				formData: { token: this.qiniuToken, key },
				success: (res) => {
					try {
						const data = JSON.parse(res.data);
						const finalUrl = 'https://api.ccttiot.com/' + data.key;
						this.$emit('update:modelValue', finalUrl);
						this.$emit('success', finalUrl, data);
						uni.showToast({ title: this.$i18n.t('imageSelectedSuccess'), icon: 'success' })
					} catch (e) {
						console.error('parse upload response failed', e)
						uni.showToast({ title: this.$i18n.t('uploadFailed'), icon: 'none' })
					}
				},
				fail: (err) => {
					console.error('upload failed:', err)
					this.$emit('error', err)
					uni.showToast({ title: this.$i18n.t('uploadFailed'), icon: 'none' })
				}
			})
		},
		// 随机数
		generateGuid(length) {
			const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
			let result = '';
			for (let i = 0; i < length; i++) {
				result += chars.charAt(Math.floor(Math.random() * chars.length));
			}
			return 'static/' + result;
		}
	}
}
</script>

<style scoped lang="less">
	.avatar-uploader {
		position: relative;
	}
	.avatar-wrapper {
		position: relative;
		left: 50%;
		transform: translateX(-50%);
		width: 272rpx;
	}
	.avatar-image {
		width: 272rpx;
		height: 272rpx;
		border-radius: 50%;
	}
	.avatar-badge {
		width: 116rpx;
		height: 72rpx;
		position: absolute;
		right: 0;
		bottom: 0;
	}

	/* action sheet styles */
	.action-sheet {
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		background-color: rgba(0, 0, 0, 0.5);
		z-index: 9999;
		display: flex;
		align-items: flex-end;
		justify-content: center;
	}
	.action-sheet-content {
		width: 100%;
		background-color: #fff;
		border-radius: 20rpx 20rpx 0 0;
		padding-bottom: 40rpx;
		animation: slideUp 0.3s ease-out;
	}
	@keyframes slideUp {
		from { transform: translateY(100%); }
		to { transform: translateY(0); }
	}
	.action-sheet-item { padding: 30rpx 40rpx; border-bottom: 1rpx solid #f0f0f0; text-align: center; }
	.action-sheet-item:active { background-color: #f5f5f5; }
	.action-sheet-cancel { padding: 30rpx 40rpx; text-align: center; margin-top: 20rpx; background-color: #f8f8f8; }
	.action-sheet-cancel:active { background-color: #e8e8e8; }
	.action-sheet-text { font-size: 32rpx; color: #333; }
	.action-sheet-cancel .action-sheet-text { color: #666; }
</style>

