<template>
    <div class="taskList-container">
        <div class="flex-between mb-3">
            <span class="stat-label">合成任务列表</span>
        </div>
        <div class="flex-between mb-3">
            <div class="flex-center gap-2">
                <el-tag v-for="tab in tabs" :key="tab.key" :type="activeTab === tab.key ? '' : 'info'"
                    :effect="activeTab === tab.key ? 'dark' : 'plain'" style="cursor:pointer;"
                    @click="changeTab(tab.key)">
                    {{ tab.label }}
                </el-tag>
            </div>
        </div>
        <el-table :data="tasks" style="width:100%;" stripe>
            <el-table-column prop="taskCode" label="任务编号" />
            <el-table-column prop="text" label="文本内容" show-overflow-tooltip />
            <el-table-column prop="voice" label="音色" />
            <el-table-column prop="status" label="状态">
                <template #default="{ row }">
                    <el-tag :type="statusType(row.status)" size="small" effect="plain">
                        {{ row.statusName }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="audioDuration" label="时间">
                <template #default="scope">
                    {{ formatTime(scope.row.audioDuration) }}
                </template>
            </el-table-column>
            <el-table-column align="center" class-name="small-padding fixed-width" label="操作">
                <template #default="scope">
                    <el-button link @click="play(scope.row.audioFilePath)" type="primary"
                        icon="VideoPlay">播放</el-button>
                    <el-button icon="Delete" link type="primary" @click="handleDelete(scope.row.id)">删除</el-button>

                    <el-dropdown>
                        <span class="el-dropdown-link">
                            ...
                        </span>
                        <template #dropdown>
                            <el-dropdown-menu>
                                <el-dropdown-item>
                                    <el-button icon="Download" link type="primary"
                                        @click="handleDownload(scope.row)">下载</el-button>
                                </el-dropdown-item>
                                <el-dropdown-item>
                                    <el-button icon="Collection" link type="primary"
                                        @click="handleSave(scope.row.id)">保存</el-button>
                                </el-dropdown-item>
                                <el-dropdown-item>
                                    <el-button icon="Refresh" link type="primary"
                                        @click="regenerate(scope.row.id)">重新生成</el-button>
                                </el-dropdown-item>
                            </el-dropdown-menu>
                        </template>
                    </el-dropdown>
                </template>
            </el-table-column>
        </el-table>
        <div class="flex-between mt-3">
            <span class="text-muted text-sm">共 {{ totalTasks }} 条</span>
            <el-pagination background layout="prev, pager, next, jumper" :total="totalTasks" :page-size="10"
                v-model:current-page="page" small />
        </div>

        <el-dialog v-model="dialogVisible" title="播放音频"  width="600px" :destroy-on-close="true" @close="colseDialog">
            <div class="wave-container">
                <div class="wave">
                    <div v-for="(h, index) in waveform" :key="index" :style="{
                        width: '4px',
                        height: h + '%',
                        background: '#3b82f6',
                        borderRadius: '2px',
                        opacity: 0.6 + (h / 100) * 0.4
                    }"></div>
                </div>
                <div class="audio-container">
                    <AudioPlayer :src="audioUrl" @audioStatus="audioStatus" />
                </div>
            </div>
        </el-dialog>

        <el-dialog v-model="corpusDialogVisible" title="保存到语料库" :append-to-body="true" width="400px" @close="colseDialog">
            <el-form ref="formRef" :model="form"  label-width="auto">
                <el-form-item label="语料分类" :rules="[{ required: true, message: '请选择分类', trigger: 'blur' }]">
                    <el-tree-select
                        v-model="form.categoryId"
                        :data="treeData"
                        node-key="id"
                        :props="{
                            label: 'categoryName',
                            value: 'id',
                            children: 'children'
                        }"
                        :render-after-expand="false"
                        style="width: 240px"
                    />
                </el-form-item>
            </el-form>
            <template #footer>
                <el-button @click="corpusDialogVisible = false">取消</el-button>
                <el-button type="primary" @click="confirmCorpus">确定</el-button>
            </template>
        </el-dialog>
    </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { taskListApi, deleteTask, downloadWavApi, regenerateApi, saveTaskApi } from '@/api/corpusManger/speech_synthesis'
import { getCategoryTreeApi } from '@/api/corpusManger/corpus.js'
import { ElMessage, ElMessageBox } from 'element-plus'
import Download from '@/plugins/download'
import AudioPlayer from './AudioPlayer.vue';

const search = ref('')
const activeTab = ref('')
const page = ref(1)

const tabs = [
    { key: '', label: '全部任务' },
    { key: '1', label: '合成中' },
    { key: '2', label: '已合成' },
    { key: '3', label: '失败' }
]

const tasks = ref([])

const totalTasks = computed(() => tasks.value.length)

const changeTab = (key) => {
    activeTab.value = key
    getTaskList()
}

const statusMap = { '2': 'success', '1': 'warning', '0': 'info', '3': 'danger' }

const statusType = (status) => {
    return statusMap[status] || 'info'
}

const formatTime = (seconds) => {
    if (!seconds || isNaN(seconds)) return '00:00'
    const m = Math.floor(seconds / 60)
    const s = Math.floor(seconds % 60)
    return `${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`
}

const getTaskList = async (status = null) => {
    const obj = {
        pageNum: page.value,
        pageSize: 10,
    }
    if (activeTab.value) {
        obj.status = activeTab.value
    }
    const res = await taskListApi(obj)
    if (res.code == 0) {
        tasks.value = res.rows
        totalTasks.value = res.total
    }
}

const dialogVisible = ref(false)

// 波形数据
const waveform = ref(Array.from({ length: 60 }, () => Math.floor(Math.random() * 60 + 20)))
const timer = ref(null)

// 模拟波形动态变化
const updateWaveform = () => {
    waveform.value = Array.from({ length: 60 }, () => Math.floor(Math.random() * 60 + 20))
}

const audioUrl = ref('https://sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/music/audio.mp3')

const audioStatus = (isPlaying) => {
    if (isPlaying) {
        timer.value = setInterval(updateWaveform, 100)
    } else {
        if (timer.value) clearInterval(timer.value)
    }
}

onBeforeUnmount(() => {
    if (timer.value) clearInterval(timer.value)
})

const play = (url) => {
    dialogVisible.value = true
    audioUrl.value = import.meta.env.VITE_MINIO_URL + url
}

const colseDialog = () => {
    dialogVisible.value = false
    if (timer.value) clearInterval(timer.value)
}

const handleDelete = (id) => {
    ElMessageBox.confirm('是否删除该任务', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
    }).then(async () => {
        const res = await deleteTask(id)
        if (res.code === 200) {
            getTaskList()
            ElMessage.success(res.msg)
        } else {
            ElMessage.error(res.msg)
        }
    }).catch(() => { });

}

const handleDownload = async (row) => {
    const res = await downloadWavApi(row.id)
    const blob = new Blob([res], { type: `audio/${row.outputFormat}` })
    const blobUrl = URL.createObjectURL(blob)

    const a = document.createElement('a')
    a.href = blobUrl
    a.download = `${row.id}.${row.outputFormat}`
    a.click()

    URL.revokeObjectURL(blobUrl)
}

const regenerate = async (id) => {
    const res = await regenerateApi(id)
    if (res.code === 200) {
        getTaskList()
        ElMessage.success(res.msg)
    }
}

const corpusDialogVisible = ref(false)
const formRef = ref()
const treeData = ref([])
const form = ref({
    taskId: '',
    categoryId: ''
})

const handleSave = (taskId) => {
    corpusDialogVisible.value = true
    form.value.taskId = taskId
    getCategoryTree()
}

const getCategoryTree = async () => {
    const res = await getCategoryTreeApi()
    if (res.code === 200) {
        treeData.value = res.data
    }
}

const confirmCorpus = async () => {
    const result = await formRef.value.validate()
    if (result) {
        const res = await saveTaskApi(form.value)
        if (res.code === 200) {
            corpusDialogVisible.value = false
            ElMessage.success(res.msg)
        }
    }
}

onMounted(() => {
    getTaskList()
})

defineExpose({
    getTaskList
})
</script>

<style lang="scss" scoped>
.taskList-container {
    background: #fff;
    padding: 20px;
    border-radius: 12px;
}

.flex-between {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.flex-center {
    display: flex;
    align-items: center;
    gap: 6px;
}

.mb-3 {
    margin-bottom: 12px;
}

.mt-3 {
    margin-top: 12px;
}

.text-muted {
    color: #94a3b8;
}

.text-sm {
    font-size: 13px;
}

.gap-2 {
    gap: 8px;
}

.stat-label {
    font-size: 13px;
    color: #64748b;
    font-weight: 500;
}


.wave-container {
    border-radius: 12px;
    padding: 16px;
    min-height: 140px;
    position: relative;

    .wave {
        display: flex;
        align-items: flex-end;
        height: 80px;
        gap: 4px;
        justify-content: center;
    }

    .audio-container {
        width: 100%;
        margin: 10px 0;
    }
}
</style>