<template>
	<div class="common-layout">
		<el-container>


			<el-container class="pt-4">

				<el-main class="p-2">
					<div class="panel-shell p-6">
						<div class="text-lg font-semibold mb-4">TTS</div>
						<div class="flex flex-col sm:flex-row items-stretch sm:items-center gap-3 mb-4">
							<!-- <el-input v-model="planIdInput" placeholder="planId" class="w-full sm:w-auto" style="max-width: 220px" /> -->
							<el-button type="primary" :loading="loadingWords" @click="onLoadWords">加载词汇</el-button>
							<!-- <el-select v-model="voice" placeholder="选择声线" class="w-full sm:w-auto" style="max-width: 160px">
								<el-option label="alloy" value="alloy" />
								<el-option label="verse" value="verse" />
								<el-option label="nova" value="nova" />
							</el-select> -->
							<!-- <el-select v-model="format" placeholder="格式" class="w-full sm:w-auto" style="max-width: 120px">
								<el-option label="mp3" value="mp3" />
								<el-option label="wav" value="wav" />
								<el-option label="ogg" value="ogg" />
							</el-select> -->
							<el-button type="success" :disabled="words.length === 0" :loading="generatingAll" class="!ml-0"
								@click="onGenerateAll">生成音频</el-button>
						</div>
						<div class="sm:hidden">
							<div v-for="row in tableData" :key="row.word" class="panel-shell p-4 mb-3">
								<div class="flex items-center justify-between">
									<div class="font-medium">{{ row.word }}</div>
									<el-tag :type="row.audioUrl ? 'success' : 'info'" effect="plain">
										{{ row.audioUrl ? '已生成' : '未生成' }}
									</el-tag>
								</div>
								<div class="mt-3 flex flex-wrap gap-2">
									<el-button size="small" type="primary" :loading="row.loading" @click="onGenerateOne(row)">生成音频</el-button>
									<el-button size="small" :disabled="!row.audioUrl" @click="onPlay(row)">播放</el-button>
									<el-button size="small" :disabled="!row.audioUrl" @click="onDownload(row)">下载</el-button>
								</div>
							</div>
						</div>
						<div class="hidden sm:block overflow-x-auto">
							<el-table :data="tableData" border class="min-w-[640px]" v-loading="loadingWords" size="small">
								<el-table-column prop="word" label="词汇/短语" min-width="200" />
								<el-table-column label="状态" width="120">
									<template #default="{ row }">
										<el-tag :type="row.audioUrl ? 'success' : 'info'" effect="plain">
											{{ row.audioUrl ? '已生成' : '未生成' }}
										</el-tag>
									</template>
								</el-table-column>
								<el-table-column label="操作" width="240" fixed="right">
									<template #default="{ row }">
										<el-button size="small" type="primary" :loading="row.loading" @click="onGenerateOne(row)">生成音频</el-button>
										<el-button size="small" class="ml-2" :disabled="!row.audioUrl" @click="onPlay(row)">播放</el-button>
										<el-button size="small" class="ml-2" :disabled="!row.audioUrl" @click="onDownload(row)">下载</el-button>
									</template>
								</el-table-column>
							</el-table>
						</div>
						<div class="mt-3 text-sm text-gray-500">
							共 {{ words.length }} 条
						</div>
					</div>
				</el-main>
			</el-container>
		</el-container>
	</div>
</template>

<script setup>
import Header from '@/layouts/components/Header.vue'
import { ref, computed, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import { getLessonPlanWords } from '@/api/plan'
import { synthesizeOpenAITTS } from '@/api/tts'
import { showMessage } from '@/composables/util'
import Sidebar from '@/layouts/components/Sidebar.vue'
const route = useRoute()
const planIdInput = ref(route.query.planId ? String(route.query.planId) : '')
const words = ref([])
const loadingWords = ref(false)
const generatingAll = ref(false)
const voice = ref('alloy')
const format = ref('mp3')

const tableData = computed(() => {
	return words.value.map(w => ({
		word: w,
		audioUrl: audioMap.value.get(w) || '',
		loading: loadingSet.value.has(w)
	}))
})

const audioMap = ref(new Map())
const loadingSet = ref(new Set())

async function onLoadWords() {
	if (!planIdInput.value) {
		showMessage('请输入 planId', 'error')
		return
	}
	loadingWords.value = true
	try {
		const res = await getLessonPlanWords(Number(planIdInput.value))
		const d = res.data
		const arr = d?.data?.words
		words.value = Array.isArray(arr) ? arr : []
		if (words.value.length === 0) {
			showMessage('未获取到词汇', 'warning')
		} else {
			showMessage('已加载词汇', 'success')
		}
	} finally {
		loadingWords.value = false
	}
}

async function onGenerateOne(row) {
	const text = row?.word
	if (!text) return
	loadingSet.value.add(text)
	try {
		const res = await synthesizeOpenAITTS(text, voice.value, format.value)
		const blob = res.data
		const url = URL.createObjectURL(blob)
		audioMap.value.set(text, url)
		showMessage('生成成功', 'success')
	} catch (e) {
		showMessage('生成失败', 'error')
	} finally {
		loadingSet.value.delete(text)
	}
}

async function onGenerateAll() {
	if (words.value.length === 0) return
	generatingAll.value = true
	try {
		for (const w of words.value) {
			loadingSet.value.add(w)
			try {
				const res = await synthesizeOpenAITTS(w, voice.value, format.value)
				const url = URL.createObjectURL(res.data)
				audioMap.value.set(w, url)
			} catch (e) {
			} finally {
				loadingSet.value.delete(w)
			}
		}
		showMessage('全部生成完成', 'success')
	} finally {
		generatingAll.value = false
	}
}

function onPlay(row) {
	const url = audioMap.value.get(row.word)
	if (!url) return
	const audio = new Audio(url)
	audio.play()
}

function onDownload(row) {
	const url = audioMap.value.get(row.word)
	if (!url) return
	const a = document.createElement('a')
	a.href = url
	const ext = format.value || 'mp3'
	a.download = `${row.word.replace(/\s+/g, '_')}.${ext}`
	document.body.appendChild(a)
	a.click()
	document.body.removeChild(a)
}

onMounted(() => {
	if (planIdInput.value) {
		onLoadWords()
	}
})
</script>

<style scoped></style>
