<template>
	<view>
		<view class="body">
			<view class="list">
				<view class="list_head fa sb">
					<image src="/static/images/timbre_logo.png" mode="widthFix"></image>{{ voicesInfo }}
				</view>
				
				<!-- 克隆音色按钮 -->
				<view class="clone-voice-btn" @click="showCloneModal">
					<text>🎤 克隆我的音色</text>
				</view>
				
				<view class="list_content">
					<view class="list_module fa sb" v-for="(item, index) in configVoicesList.voices" :key="index"  v-show="item.price_gold == 0"
						@click="selectTimbre(index)">
						<view class="list_detail fa f1">
							<view class="list_image">
								<image class="list_avatar" :src="item.avatar_url?global + item.avatar_url:'/static/images/replacement_picture.png'" mode="aspectFill"></image>
								<image class="list_voice" @click.stop="playVoice(item.sample_audio_url)"
									src="/static/images/timbre_voice.png" mode="widthFix"></image>
							</view>
							<view class="list_item f1">
								<view class="list_name h1">{{ item.name }}</view>
								<view class="list_tag h2">{{ item.style_tag }}</view>
							</view>
						</view>
						<view class="list_select faj" >
							<image
								:src="selectedItemIndex == index ? '/static/images/selectA.png' : '/static/images/select.png'"
								mode="widthFix"></image>
						</view>
					</view>
				</view>
			</view>
		</view>
		<view class="opt">
			<view class="opt_module">
				<view class="opt_data">
					<view class="opt_btn faj" @click="confirmSelection">
						确定选择
					</view>
				</view>
			</view>
		</view>
		
		<!-- 克隆音色弹窗 -->
		<view class="clone-modal" v-if="cloneModalVisible" @click="cloneModalVisible = false">
			<view class="clone-content" @click.stop>
				<view class="clone-title">克隆音色</view>
				<view class="clone-desc">上传一段清晰的音频（至少3秒），AI将克隆您的音色</view>
				
				<input 
					v-model="cloneVoiceName" 
					class="clone-input"
					placeholder="请输入音色名称（最多10个字符）"
					maxlength="10">
				</input>
				
				<view class="clone-upload-area" @click="chooseAudio">
					<view v-if="!audioFile" class="upload-placeholder">
						<text>📁 点击选择音频文件</text>
						<text class="upload-tip">支持 mp3、wav 格式</text>
					</view>
					<view v-else class="upload-success">
						<text>✅ {{ audioFile.name }}</text>
					</view>
				</view>
				
				<view class="clone-status" v-if="cloneStatus">
					<text :class="cloneStatusClass">{{ cloneStatusText }}</text>
				</view>
				
				<view class="clone-buttons">
					<view class="clone-btn cancel" @click="cancelClone">取消</view>
					<view class="clone-btn confirm" @click="startClone" :class="{ disabled: cloning }">
						{{ cloning ? '克隆中...' : '开始克隆' }}
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
import {
	ConfigVoices,
	LoverVoice,
	ConfigVoicesAvailable,
	LoverVoiceSimple
} from '@/utils/api.js'
import notHave from '@/components/not-have.vue';
import topSafety from '@/components/top-safety.vue';

import { useVoiceStore } from '@/store/index.js'
export default {
	components: {
		notHave,
		topSafety,
	},
	data() {
		return {
			global: this.baseURL,
			form: {
				gender: '',
				voice_id: '',
			},
			selectedItemIndex: -1, // 默认不选择任何项
			configVoicesList: { voices: [] },  // 修复：初始化为对象
			voicesInfo: '',
			currentAudioContext: null, // 添加当前音频上下文实例
			// 克隆音色相关
			cloneModalVisible: false,
			cloneVoiceName: '',
			audioFile: null,
			audioUrl: '',
			cloning: false,
			cloneStatus: '',
			cloneVoiceId: '',
			baseURLPy: 'http://127.0.0.1:8000',
		}
	},
	onLoad(options) {
		console.log('角色声音页面接参：',options)
		this.form.gender = options.sex
		console.log(this.form)
		this.configVoices()
	},
	methods: {
		configVoices() {
			let api = ''
			if(this.form.gender){
				api = ConfigVoices
			}else{
				api = ConfigVoicesAvailable
			}
			api({
				...this.form
			}).then(res => {
				if (res.code == 1) {
					this.configVoicesList = res.data
					if (this.configVoicesList.selected_voice_id != null) {
						let found = false;
						for (let i = 0; i < this.configVoicesList.voices.length; i++) {
							if (this.configVoicesList.voices[i].id == this.configVoicesList.selected_voice_id) {
								this.voicesInfo = this.configVoicesList.voices[i].name
								this.selectedItemIndex = i
								this.form.voice_id = this.configVoicesList.voices[i].id
								found = true;
								break;
							}
						}
						if (!found) {
							// 如果没有找到 selected_voice_id，则使用默认值
							for (let i = 0; i < this.configVoicesList.voices.length; i++) {
								if (this.configVoicesList.voices[i].id == this.configVoicesList.default_voice_id) {
									this.voicesInfo = this.configVoicesList.voices[i].name
									this.selectedItemIndex = i
									this.form.voice_id = this.configVoicesList.voices[i].id
									break;
								}
							}
						}
					} else {
						for (let i = 0; i < this.configVoicesList.voices.length; i++) {
							if (this.configVoicesList.voices[i].id == this.configVoicesList.default_voice_id) {
								this.voicesInfo = this.configVoicesList.voices[i].name
								this.selectedItemIndex = i
								this.form.voice_id = this.configVoicesList.voices[i].id
								break;
							}
						}
					}

				} else {
					uni.showToast({
						title: res.msg,
						icon: 'none',
						position: 'top'
					})
				}
			})
		},
		// 设置声音
		loverVoice() {
			let api = ''
			if(this.form.gender){
				api = LoverVoice
			}else{
				api = LoverVoiceSimple
			}
			api(this.form).then(res => {
				if (res.code == 1) {
					uni.showToast({
						title: '设置成功',
						icon: 'none',
						position: 'top'
					})
					const voiceStore = useVoiceStore()
					voiceStore.setVoice(this.form.voice_id, this.voicesInfo)
					setTimeout(() => {
						uni.navigateBack({
							delta: 1
						});
					}, 1000);
				} else {
					uni.showToast({
						title: res.msg,
						icon: 'none',
						position: 'top'
					})
				}
			})
		},
		// 选择音色
		selectTimbre(index) {
			this.selectedItemIndex = index;
			this.voicesInfo = this.configVoicesList.voices[index].name
			this.form.voice_id = this.configVoicesList.voices[index].id
		},
		playVoice(url) {
			// 如果当前有正在播放的音频，先停止它
			if (this.currentAudioContext) {
				this.currentAudioContext.stop();
				this.currentAudioContext.destroy(); // 释放资源
			}
			
			// 创建新的音频上下文
			this.currentAudioContext = uni.createInnerAudioContext();
			this.currentAudioContext.src = this.global + url; // 设置音频源

			// 播放音频
			this.currentAudioContext.play();

			// 监听播放结束事件，播放结束后清空当前音频上下文
			this.currentAudioContext.onEnded(() => {
				console.log('音频播放结束');
				if (this.currentAudioContext) {
					this.currentAudioContext.destroy();
					this.currentAudioContext = null;
				}
			});

			// 监听播放错误事件
			this.currentAudioContext.onError((err) => {
				console.error('音频播放失败:', err);
				if (this.currentAudioContext) {
					this.currentAudioContext.destroy();
					this.currentAudioContext = null;
				}
				uni.showToast({
					title: '播放失败',
					icon: 'none'
				});
			});
		},
		confirmSelection() {
			console.log(this.form)
			console.log(this.selectedItemIndex)
			if (this.selectedItemIndex < 0) {
				uni.showToast({
					title: '请选择音色',
					icon: 'none'
				});
			} else {
				console.log(this.form)
				this.loverVoice()
			}
		},
		
		// ===== 克隆音色相关方法 =====
		showCloneModal() {
			this.cloneModalVisible = true;
			this.cloneVoiceName = '';
			this.audioFile = null;
			this.audioUrl = '';
			this.cloneStatus = '';
		},
		
		cancelClone() {
			this.cloneModalVisible = false;
			this.cloning = false;
		},
		
		chooseAudio() {
			uni.chooseFile({
				count: 1,
				extension: ['.mp3', '.wav', '.m4a'],
				success: (res) => {
					this.audioFile = {
						path: res.tempFilePaths[0],
						name: res.tempFiles[0].name || '音频文件'
					};
					console.log('选择的音频:', this.audioFile);
				},
				fail: (err) => {
					console.error('选择文件失败:', err);
					uni.showToast({
						title: '选择文件失败',
						icon: 'none'
					});
				}
			});
		},
		
		async startClone() {
			if (this.cloning) return;
			
			if (!this.cloneVoiceName.trim()) {
				uni.showToast({
					title: '请输入音色名称',
					icon: 'none'
				});
				return;
			}
			
			if (!this.audioFile) {
				uni.showToast({
					title: '请选择音频文件',
					icon: 'none'
				});
				return;
			}
			
			this.cloning = true;
			this.cloneStatus = 'uploading';
			
			try {
				// 1. 上传音频文件到 OSS
				const uploadResult = await this.uploadAudio();
				if (!uploadResult) {
					throw new Error('上传失败');
				}
				
				this.audioUrl = uploadResult;
				this.cloneStatus = 'cloning';
				
				// 2. 调用克隆 API
				const cloneResult = await this.callCloneAPI();
				if (!cloneResult) {
					throw new Error('克隆失败');
				}
				
				this.cloneVoiceId = cloneResult.voice_id;
				this.cloneStatus = 'polling';
				
				// 3. 轮询状态
				await this.pollCloneStatus();
				
			} catch (error) {
				console.error('克隆失败:', error);
				this.cloneStatus = 'failed';
				this.cloning = false;
			}
		},
		
		uploadAudio() {
			return new Promise((resolve, reject) => {
				uni.uploadFile({
					url: this.baseURL + '/api/common/upload',
					filePath: this.audioFile.path,
					name: 'file',
					header: {
						token: uni.getStorageSync("token") || "",
					},
					success: (res) => {
						const data = JSON.parse(res.data);
						if (data.code === 1) {
							resolve(data.data.url);
						} else {
							reject(new Error(data.msg));
						}
					},
					fail: reject
				});
			});
		},
		
		callCloneAPI() {
			return new Promise((resolve, reject) => {
				uni.request({
					url: this.baseURLPy + '/config/voices/clone',
					method: 'POST',
					header: {
						'Content-Type': 'application/json',
						'token': uni.getStorageSync("token") || "",
					},
					data: {
						audio_url: this.audioUrl,
						voice_name: this.cloneVoiceName,
						gender: this.form.gender || 'female'
					},
					success: (res) => {
						if (res.data.code === 1) {
							resolve(res.data.data);
						} else {
							reject(new Error(res.data.message));
						}
					},
					fail: reject
				});
			});
		},
		
		async pollCloneStatus() {
			const maxAttempts = 30; // 最多轮询30次
			const interval = 10000; // 每10秒轮询一次
			
			for (let i = 0; i < maxAttempts; i++) {
				await new Promise(resolve => setTimeout(resolve, interval));
				
				try {
					const status = await this.checkCloneStatus();
					
					if (status === 'OK') {
						// 克隆成功，保存到数据库
						await this.saveClonedVoice();
						this.cloneStatus = 'success';
						this.cloning = false;
						
						uni.showToast({
							title: '克隆成功！',
							icon: 'success'
						});
						
						// 刷新音色列表
						setTimeout(() => {
							this.cloneModalVisible = false;
							this.configVoices();
						}, 2000);
						
						return;
					} else if (status === 'FAILED') {
						throw new Error('克隆失败');
					}
					// 继续轮询
				} catch (error) {
					console.error('查询状态失败:', error);
					this.cloneStatus = 'failed';
					this.cloning = false;
					return;
				}
			}
			
			// 超时
			this.cloneStatus = 'timeout';
			this.cloning = false;
		},
		
		checkCloneStatus() {
			return new Promise((resolve, reject) => {
				uni.request({
					url: this.baseURLPy + `/config/voices/clone/${this.cloneVoiceId}/status`,
					method: 'GET',
					header: {
						'token': uni.getStorageSync("token") || "",
					},
					success: (res) => {
						if (res.data.code === 1) {
							resolve(res.data.data.status);
						} else {
							reject(new Error(res.data.message));
						}
					},
					fail: reject
				});
			});
		},
		
		saveClonedVoice() {
			return new Promise((resolve, reject) => {
				uni.request({
					url: this.baseURLPy + `/config/voices/clone/${this.cloneVoiceId}/save`,
					method: 'POST',
					header: {
						'token': uni.getStorageSync("token") || "",
					},
					success: (res) => {
						if (res.data.code === 1) {
							resolve(res.data.data);
						} else {
							reject(new Error(res.data.message));
						}
					},
					fail: reject
				});
			});
		}
	},
	
	computed: {
		cloneStatusText() {
			const statusMap = {
				'uploading': '正在上传音频...',
				'cloning': '正在克隆音色...',
				'polling': '正在生成音色，请稍候...',
				'success': '✅ 克隆成功！',
				'failed': '❌ 克隆失败',
				'timeout': '⏱️ 克隆超时，请稍后重试'
			};
			return statusMap[this.cloneStatus] || '';
		},
		
		cloneStatusClass() {
			return {
				'status-processing': ['uploading', 'cloning', 'polling'].includes(this.cloneStatus),
				'status-success': this.cloneStatus === 'success',
				'status-error': ['failed', 'timeout'].includes(this.cloneStatus)
			};
		}
	}
}
</script>
<style>
page {
	background: #F6F8FA;
}
</style>
<style>
.body {
	position: relative;
	padding: 0 40rpx 40rpx 40rpx;
}

.list {
	position: relative;
	margin: 30rpx 0 0 0;
}

.list_head {
	position: relative;
	margin: 0 0 30rpx 0;
	padding: 28rpx 40rpx;
	font-weight: 400;
	font-size: 30rpx;
	color: #9E9E9E;
	line-height: 50rpx;
	background: #FFFFFF;
	border-radius: 12rpx;
}

.list_head image {
	width: 68rpx;
	height: 66rpx;
	display: block;
	border-radius: 100rpx;
}

.list_content {
	position: relative;
}

.list_module {
	position: relative;
	margin: 0 0 30rpx 0;
	padding: 28rpx 40rpx;
	background: #FFFFFF;
	border-radius: 12rpx;
}

.list_detail {
	position: relative;
	overflow: hidden;
}

.list_image {
	position: relative;
}

.list_avatar {
	width: 88rpx;
	height: 88rpx;
	display: block;
	flex-shrink: 0;
	border-radius: 100rpx;
}

.list_voice {
	position: absolute;
	right: -10rpx;
	bottom: -10rpx;
	width: 48rpx;
	height: 48rpx;
}

.list_item {
	position: relative;
	margin: 0 0 0 24rpx;
	overflow: hidden;
}

.list_name {
	font-weight: 500;
	font-size: 32rpx;
	color: #333333;
	line-height: 50rpx;
}

.list_tag {
	font-weight: 400;
	font-size: 28rpx;
	color: #9E9E9E;
	line-height: 50rpx;
}

.list_select {
	position: relative;
}

.list_select image {
	width: 36rpx;
	height: 36rpx;
	flex-shrink: 0;
}

.opt {
	position: relative;
	height: 150rpx;
}

.opt_module {
	position: fixed;
	padding: 5rpx 0 70rpx 0;
	height: 85rpx;
	width: 100%;
	background: #F6F8FA;
	bottom: 0;
	left: 0;
	box-sizing: content-box;
	border-top: 1px solid #f0f0f0;
	z-index: 2;
}

.opt_data {
	padding: 5rpx 50rpx;
	font-size: 28rpx;
}

.opt_btn {
	padding: 24rpx 0;
	font-weight: 400;
	font-size: 32rpx;
	color: #FFFFFF;
	line-height: 50rpx;
	background: linear-gradient(135deg, #9F47FF 0%, #0053FA 100%);
	border-radius: 12rpx;
}

/* 克隆音色按钮 */
.clone-voice-btn {
	margin: 0 0 30rpx 0;
	padding: 24rpx 40rpx;
	background: linear-gradient(135deg, #FF6B9D 0%, #C239B3 100%);
	border-radius: 12rpx;
	text-align: center;
	color: #FFFFFF;
	font-size: 32rpx;
	font-weight: 500;
}

/* 克隆音色弹窗 */
.clone-modal {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	bottom: 0;
	background: rgba(0, 0, 0, 0.6);
	display: flex;
	align-items: center;
	justify-content: center;
	z-index: 9999;
}

.clone-content {
	width: 85%;
	max-width: 600rpx;
	background: #FFFFFF;
	border-radius: 20rpx;
	padding: 40rpx;
}

.clone-title {
	font-size: 36rpx;
	font-weight: bold;
	color: #333;
	text-align: center;
	margin-bottom: 20rpx;
}

.clone-desc {
	font-size: 26rpx;
	color: #999;
	text-align: center;
	margin-bottom: 30rpx;
	line-height: 1.5;
}

.clone-input {
	width: 100%;
	padding: 20rpx;
	border: 2rpx solid #E0E0E0;
	border-radius: 10rpx;
	font-size: 28rpx;
	margin-bottom: 30rpx;
}

.clone-upload-area {
	width: 100%;
	min-height: 200rpx;
	border: 2rpx dashed #9F47FF;
	border-radius: 10rpx;
	display: flex;
	align-items: center;
	justify-content: center;
	margin-bottom: 30rpx;
	background: #F9F9F9;
}

.upload-placeholder {
	display: flex;
	flex-direction: column;
	align-items: center;
	color: #666;
}

.upload-placeholder text:first-child {
	font-size: 32rpx;
	margin-bottom: 10rpx;
}

.upload-tip {
	font-size: 24rpx;
	color: #999;
}

.upload-success {
	color: #4CAF50;
	font-size: 28rpx;
	padding: 20rpx;
	text-align: center;
}

.clone-status {
	text-align: center;
	margin-bottom: 30rpx;
	font-size: 28rpx;
}

.status-processing {
	color: #2196F3;
}

.status-success {
	color: #4CAF50;
}

.status-error {
	color: #F44336;
}

.clone-buttons {
	display: flex;
	justify-content: space-between;
	gap: 20rpx;
}

.clone-btn {
	flex: 1;
	padding: 20rpx;
	text-align: center;
	border-radius: 10rpx;
	font-size: 28rpx;
}

.clone-btn.cancel {
	background: #f5f5f5;
	color: #666;
}

.clone-btn.confirm {
	background: linear-gradient(135deg, #9F47FF 0%, #0053FA 100%);
	color: #fff;
}

.clone-btn.disabled {
	opacity: 0.6;
}
</style>