<template>
	<el-dialog
		v-model="visible"
		title="添加音频"
		width="700px"
		:close-on-click-modal="false"
		@close="handleClose"
	>
		<!-- 上传音频模式 -->
		<el-form v-if="activeMode === 'upload'" ref="uploadFormRef" :model="uploadForm" :rules="uploadRules" label-width="100px" class="audio-form">
			<el-form-item label="音频名称" prop="name">
				<el-input v-model="uploadForm.name" placeholder="请输入音频名称" maxlength="50" show-word-limit />
			</el-form-item>
			
			<el-form-item label="音频类型">
				<el-radio-group v-model="activeMode">
					<el-radio label="upload">上传音频</el-radio>
					<el-radio label="tts">文本转语音</el-radio>
				</el-radio-group>
			</el-form-item>
			
			<el-form-item label="音色类型" prop="voiceType">
				<el-select v-model="uploadForm.voiceType" placeholder="请选择音色类型" style="width: 100%">
					<el-option label="男声" value="male" />
					<el-option label="女声" value="female" />
					<el-option label="童声" value="child" />
				</el-select>
			</el-form-item>
			
			<el-form-item label="上传文件" prop="file">
				<el-upload
					ref="uploadRef"
					class="audio-uploader"
					drag
					action="#"
					:auto-upload="false"
					:limit="1"
					accept=".mp3,.wav,.pcm,.flac"
					:on-change="handleFileChange"
					:on-exceed="handleExceed"
				>
					<el-icon class="el-icon--upload"><ele-UploadFilled /></el-icon>
					<div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
					<template #tip>
						<div class="el-upload__tip">支持 mp3、wav、pcm、flac 格式，文件大小不超过 50MB</div>
					</template>
				</el-upload>
			</el-form-item>
			
			<!-- 上传预览 -->
			<div v-if="uploadPreview.show" class="preview-section">
				<div class="preview-header">
					<span class="preview-title">文件信息</span>
					<el-tag type="success" size="small">已选择</el-tag>
				</div>
				<div class="preview-info">
					<span>文件名: {{ uploadPreview.fileName }}</span>
					<span>文件大小: {{ formatFileSize(uploadPreview.fileSize) }}</span>
				</div>
			</div>
		</el-form>
		
		<!-- 文本转语音模式 -->
		<el-form v-else ref="formRef" :model="form" :rules="rules" label-width="100px" class="audio-form">
			<el-form-item label="音频名称" prop="name">
				<el-input v-model="form.name" placeholder="请输入音频名称" maxlength="50" show-word-limit />
			</el-form-item>
			
			<el-form-item label="音频类型">
				<el-radio-group v-model="activeMode">
					<el-radio label="upload">上传音频</el-radio>
					<el-radio label="tts">文本转语音</el-radio>
				</el-radio-group>
			</el-form-item>
			
			<el-form-item label="文本内容" prop="text">
				<el-input
					v-model="form.text"
					type="textarea"
					:rows="5"
					placeholder="请输入要转换的文本内容"
					maxlength="500"
					show-word-limit
				/>
			</el-form-item>
			
			<el-form-item label="音色选择" prop="voice">
				<el-select v-model="form.voice" placeholder="请选择音色" style="width: 100%">
					<el-option-group label="男声">
						<el-option label="商务男声" value="male_business" />
						<el-option label="磁性男声" value="male_magnetic" />
						<el-option label="新闻男声" value="male_news" />
					</el-option-group>
					<el-option-group label="女声">
						<el-option label="甜美女声" value="female_sweet" />
						<el-option label="知性女声" value="female_intellectual" />
						<el-option label="温柔女声" value="female_gentle" />
					</el-option-group>
					<el-option-group label="童声">
						<el-option label="活泼童声" value="child_lively" />
						<el-option label="可爱童声" value="child_cute" />
					</el-option-group>
				</el-select>
			</el-form-item>
			
			<el-row :gutter="20">
				<el-col :span="12">
					<el-form-item label="语速">
						<el-slider v-model="form.speed" :min="0.5" :max="2" :step="0.1" :format-tooltip="(val: number) => val + 'x'" />
					</el-form-item>
				</el-col>
				<el-col :span="12">
					<el-form-item label="音量">
						<el-slider v-model="form.volume" :min="0" :max="100" :format-tooltip="(val: number) => val + '%'" />
					</el-form-item>
				</el-col>
			</el-row>
			
			<el-row :gutter="20">
				<el-col :span="12">
					<el-form-item label="音调">
						<el-slider v-model="form.pitch" :min="-12" :max="12" :step="1" :format-tooltip="(val: number) => (val > 0 ? '+' : '') + val" />
					</el-form-item>
				</el-col>
				<el-col :span="12">
					<el-form-item label="采样率">
						<el-select v-model="form.sampleRate" style="width: 100%">
							<el-option label="16000Hz" :value="16000" />
							<el-option label="22050Hz" :value="22050" />
							<el-option label="44100Hz" :value="44100" />
							<el-option label="48000Hz" :value="48000" />
						</el-select>
					</el-form-item>
				</el-col>
			</el-row>
			
			<el-form-item label="输出格式">
				<el-radio-group v-model="form.format">
					<el-radio label="mp3">MP3</el-radio>
					<el-radio label="wav">WAV</el-radio>
					<el-radio label="pcm">PCM</el-radio>
				</el-radio-group>
			</el-form-item>
			
			<!-- TTS预览区域 -->
			<div v-if="previewGenerated" class="preview-section">
				<div class="preview-header">
					<span class="preview-title">预览</span>
					<el-tag type="success" size="small">已生成</el-tag>
				</div>
				<div class="preview-player">
					<el-button
						:type="isPlaying ? 'danger' : 'primary'"
						circle
						@click="togglePreview"
					>
						<el-icon>
							<ele-VideoPlay v-if="!isPlaying" />
							<ele-VideoPause v-else />
						</el-icon>
					</el-button>
					<el-progress
						:percentage="playProgress"
						:show-text="false"
						style="flex: 1; margin: 0 15px"
					/>
					<span class="duration">{{ formatDuration(previewDuration) }}</span>
				</div>
				<div class="preview-info">
					<span>文件大小: {{ formatFileSize(previewFileSize) }}</span>
					<span>时长: {{ formatDuration(previewDuration) }}</span>
					<span>采样率: {{ form.sampleRate }}Hz</span>
				</div>
			</div>
		</el-form>
		
		<template #footer>
			<div class="dialog-footer">
				<el-button @click="handleClose">取消</el-button>
				<template v-if="activeMode === 'upload'">
					<el-button type="primary" :loading="uploading" :disabled="!uploadPreview.show" @click="handleUpload">
						<el-icon><ele-Upload /></el-icon>
						{{ uploading ? '上传中...' : '上传音频' }}
					</el-button>
				</template>
				<template v-else>
					<el-button type="warning" :loading="generating" @click="handleGenerate">
						<el-icon><ele-Headset /></el-icon>
						{{ generating ? '生成中...' : '生成预览' }}
					</el-button>
					<el-button type="primary" :disabled="!previewGenerated" :loading="saving" @click="handleSave">
						<el-icon><ele-Check /></el-icon>
						保存音频
					</el-button>
				</template>
			</div>
		</template>
	</el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, watch } from 'vue';
import { ElMessage } from 'element-plus';
import type { FormInstance, FormRules, UploadInstance, UploadFile, UploadRawFile } from 'element-plus';

const emit = defineEmits(['success']);

const visible = ref(false);
const activeMode = ref<'upload' | 'tts'>('upload');
const formRef = ref<FormInstance>();
const uploadFormRef = ref<FormInstance>();
const uploadRef = ref<UploadInstance>();
const generating = ref(false);
const saving = ref(false);
const uploading = ref(false);
const previewGenerated = ref(false);
const isPlaying = ref(false);
const playProgress = ref(0);
const previewDuration = ref(0);
const previewFileSize = ref(0);
let progressTimer: ReturnType<typeof setInterval> | null = null;

// 上传表单
const uploadForm = reactive({
	name: '',
	voiceType: '',
	file: null as File | null,
});

// 上传预览信息
const uploadPreview = reactive({
	show: false,
	fileName: '',
	fileSize: 0,
});

// TTS 表单
const form = reactive({
	name: '',
	text: '',
	voice: 'female_sweet',
	speed: 1.0,
	volume: 80,
	pitch: 0,
	sampleRate: 44100,
	format: 'mp3',
});

// 上传表单校验规则
const uploadRules = reactive<FormRules>({
	name: [{ required: true, message: '请输入音频名称', trigger: 'blur' }],
	voiceType: [{ required: true, message: '请选择音色类型', trigger: 'change' }],
});

// TTS 表单校验规则
const rules = reactive<FormRules>({
	name: [{ required: true, message: '请输入音频名称', trigger: 'blur' }],
	text: [
		{ required: true, message: '请输入文本内容', trigger: 'blur' },
		{ min: 1, max: 500, message: '文本内容长度在1-500个字符之间', trigger: 'blur' },
	],
	voice: [{ required: true, message: '请选择音色', trigger: 'change' }],
});

// 打开弹窗
const openDialog = () => {
	visible.value = true;
	resetForm();
};

// 重置表单
const resetForm = () => {
	activeMode.value = 'upload';
	// 重置上传表单
	uploadForm.name = '';
	uploadForm.voiceType = '';
	uploadForm.file = null;
	uploadPreview.show = false;
	uploadPreview.fileName = '';
	uploadPreview.fileSize = 0;
	uploadRef.value?.clearFiles();
	// 重置 TTS 表单
	form.name = '';
	form.text = '';
	form.voice = 'female_sweet';
	form.speed = 1.0;
	form.volume = 80;
	form.pitch = 0;
	form.sampleRate = 44100;
	form.format = 'mp3';
	previewGenerated.value = false;
	isPlaying.value = false;
	playProgress.value = 0;
	previewDuration.value = 0;
	previewFileSize.value = 0;
};

// 文件选择变化
const handleFileChange = (file: UploadFile) => {
	if (file.raw) {
		const maxSize = 50 * 1024 * 1024; // 50MB
		if (file.raw.size > maxSize) {
			ElMessage.error('文件大小不能超过 50MB');
			uploadRef.value?.clearFiles();
			return;
		}
		uploadForm.file = file.raw;
		uploadPreview.show = true;
		uploadPreview.fileName = file.name;
		uploadPreview.fileSize = file.raw.size;
		// 自动填充音频名称
		if (!uploadForm.name) {
			uploadForm.name = file.name.replace(/\.[^/.]+$/, '');
		}
	}
};

// 文件超出限制
const handleExceed = () => {
	ElMessage.warning('只能上传一个文件，请先删除已选文件');
};

// 上传音频
const handleUpload = async () => {
	if (!uploadFormRef.value) return;
	
	await uploadFormRef.value.validate((valid) => {
		if (!valid) return;
		
		if (!uploadForm.file) {
			ElMessage.warning('请选择要上传的音频文件');
			return;
		}
		
		uploading.value = true;
		
		// 模拟上传过程
		setTimeout(() => {
			uploading.value = false;
			ElMessage.success('音频上传成功');
			emit('success', {
				name: uploadForm.name,
				voiceType: uploadForm.voiceType,
				duration: Math.floor(Math.random() * 180) + 30,
				fileSize: uploadPreview.fileSize,
				sampleRate: 44100,
				format: uploadPreview.fileName.split('.').pop(),
			});
			handleClose();
		}, 1500);
	});
};

// 关闭弹窗
const handleClose = () => {
	stopPreview();
	visible.value = false;
};

// 生成预览
const handleGenerate = async () => {
	if (!formRef.value) return;
	
	await formRef.value.validate((valid) => {
		if (!valid) return;
		
		generating.value = true;
		
		// 模拟生成过程
		setTimeout(() => {
			// 根据文本长度估算时长（假设每秒5个字）
			const textLength = form.text.length;
			const baseDuration = Math.ceil(textLength / 5);
			previewDuration.value = Math.max(3, Math.round(baseDuration / form.speed));
			
			// 估算文件大小
			const bitrate = form.format === 'wav' ? 1411 : form.format === 'mp3' ? 128 : 256;
			previewFileSize.value = Math.round((previewDuration.value * bitrate * 1000) / 8);
			
			previewGenerated.value = true;
			generating.value = false;
			ElMessage.success('语音生成成功，请试听预览');
		}, 1500);
	});
};

// 播放/暂停预览
const togglePreview = () => {
	if (isPlaying.value) {
		stopPreview();
	} else {
		startPreview();
	}
};

// 开始播放
const startPreview = () => {
	isPlaying.value = true;
	playProgress.value = 0;
	
	const totalSteps = previewDuration.value * 10;
	let currentStep = 0;
	
	progressTimer = setInterval(() => {
		currentStep++;
		playProgress.value = Math.round((currentStep / totalSteps) * 100);
		
		if (playProgress.value >= 100) {
			stopPreview();
		}
	}, 100);
};

// 停止播放
const stopPreview = () => {
	isPlaying.value = false;
	playProgress.value = 0;
	if (progressTimer) {
		clearInterval(progressTimer);
		progressTimer = null;
	}
};

// 保存音频
const handleSave = async () => {
	saving.value = true;
	
	// 模拟保存过程
	setTimeout(() => {
		saving.value = false;
		ElMessage.success('音频保存成功');
		emit('success', {
			name: form.name,
			voiceType: form.voice.split('_')[0],
			duration: previewDuration.value,
			fileSize: previewFileSize.value,
			sampleRate: form.sampleRate,
			format: form.format,
		});
		handleClose();
	}, 1000);
};

// 格式化时长
const formatDuration = (seconds: number) => {
	const mins = Math.floor(seconds / 60);
	const secs = seconds % 60;
	return `${mins}:${secs.toString().padStart(2, '0')}`;
};

// 格式化文件大小
const formatFileSize = (bytes: number) => {
	if (bytes < 1024) return bytes + 'B';
	if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + 'KB';
	return (bytes / 1024 / 1024).toFixed(1) + 'MB';
};

// 监听表单变化，重置预览状态
watch(
	() => [form.text, form.voice, form.speed, form.pitch],
	() => {
		if (previewGenerated.value) {
			previewGenerated.value = false;
			stopPreview();
		}
	}
);

defineExpose({
	openDialog,
});
</script>

<style scoped lang="scss">
.audio-form {
	margin-top: 10px;
}

.audio-uploader {
	width: 100%;
	
	:deep(.el-upload-dragger) {
		width: 100%;
	}
}

.preview-section {
	margin-top: 20px;
	padding: 16px;
	background: #f5f7fa;
	border-radius: 8px;
	border: 1px solid #ebeef5;
	
	.preview-header {
		display: flex;
		align-items: center;
		gap: 10px;
		margin-bottom: 15px;
		
		.preview-title {
			font-size: 14px;
			font-weight: 600;
			color: #303133;
		}
	}
	
	.preview-player {
		display: flex;
		align-items: center;
		margin-bottom: 12px;
		
		.duration {
			font-size: 12px;
			color: #909399;
			min-width: 40px;
		}
	}
	
	.preview-info {
		display: flex;
		gap: 20px;
		font-size: 12px;
		color: #909399;
	}
}

.dialog-footer {
	display: flex;
	justify-content: flex-end;
	gap: 10px;
}
</style>
