<script setup>
import { RouterLink, RouterView } from "vue-router"
import { nextTick, onMounted, ref } from "vue"

import { getQrcode, getList, monitorState, Generate, monitorMusic, getDetails, lyricsGenerateHttp, lyricsMonitorHttp, quitLoginHttp, likeDetailsHttp } from "./utils/api"
import { ElMessage } from "element-plus"
import triangleIcon from "@/components/triangle-icon.vue"

onMounted(() => {
    // getLoginQrcode()
    getListData()
})

let list = ref([])
let listIndex = ref(null) // 列表选中的 Index

const getListData = () => {
    getList().then(res => {
        if (res.code == 401) {
            getLoginQrcode()
            return
        }

        if (res.code != 200) return
        const data = res.data || []
        let isNeedMonitor = false
        data.forEach(element => {
            if (element.status != "complete") {
                isNeedMonitor = true
            }
        })

        if (isNeedMonitor) {
            monitorMusicState()
        }

        // data[0].audio_url = "./21be5d73-221f-4e7b-82f0-26c7c71b797e.mp3"

        islogin.value = true
        list.value = data || []
    })
}

let wxloginVisible = ref(false) // 登录弹窗显示状态
let wxloginQrcodeLose = ref(false) // 登录二维码失效状态
let islogin = ref(false) // 登录状态
let token = ""
let qrcode = ref("")

// 获取二维码
const getLoginQrcode = () => {
    getQrcode().then(res => {
        if (res.code != 200) return

        const data = res.data || {}
        token = data.token || ""
        qrcode.value = data.qrcode || ""
        wxloginVisible.value = true

        monitorLogin()
    })
}

// 监听扫码状态
let monitorTimer = null
const monitorLogin = () => {
    monitorTimer = setInterval(() => {
        monitorState({ token: token }).then(res => {
            if (res.code == 401) {
                getLoginQrcode()
                return
            }

            // code 200 为登录成功 400 是等待 201 是失效
            if (res.code == 400) return

            clearInterval(monitorTimer)

            if (res.code == 201) {
                wxloginQrcodeLose.value = true
            }

            if (res.code == 200) {
                ElMessage({
                    showClose: true,
                    message: res.message,
                    type: "success",
                })
                wxloginVisible.value = false
                getListData()
                localStorage.setItem("token", res.data?.token)
            }
        })
    }, 3000)
}

const handleClose = () => {
    wxloginVisible.value = false
    wxloginQrcodeLose.value = false
    clearInterval(monitorTimer)
}

let options = ref([
    {
        label: "V2 (老款模型，最长生成1分钟左右)",
        value: "chirp-v2-xxl-alpha",
    },
    {
        label: "V3 (广泛、多才多艺，最多生成2分钟)",
        value: "chirp-v3-0",
    },
    {
        label: "V3.5 (最新模型，更好的歌曲结构，最长生成4分钟）",
        value: "chirp-v3-5",
    },
])

let type = ref("inspiration") //   inspiration 灵感  custom 自定义

const cutType = key => {
    // 恢复默认值
    obj.value = Object.assign({}, obj.value, {
        "has_vocal": true,
        "prompt": "",
        "gpt_description_prompt": "",
        "mv": "chirp-v3-5",
        "tags": "",
    })

    // console.log(obj.value)
    type.value = key
}

let obj = ref({
    "gpt_description_prompt": "", // 描述
    "mv": "chirp-v3-5",
    "make_instrumental": false,
    "tags": "", // 标签
    "prompt": "", // 提示
    "history": null,
    "concat_history": null,
    "type": "gen",
    "duration": null, // 持续时间
    "refund_credits": null, // 优惠
    "stream": true, // 流派
    "infill": null, // 填充物
    "has_vocal": true, // 是否有声音
    "error_type": null,
    "error_message": null,
})

// 点击创建音乐
const creativeMusic = () => {
    Generate({ ...obj.value }).then(res => {
        if (res.code == 401) {
            getLoginQrcode()
            return
        }
        if (res.code != 200) {
            ElMessage({
                showClose: true,
                message: res.message,
                type: "error",
            })
            return
        }
        const data = res.data || {}
        list.value = data.list.concat(list.value)
        // list.value = list.value.unshift()

        monitorMusicState(data.metadataid)
        ElMessage({
            showClose: true,
            message: "提交成功",
            type: "success",
        })
    })
}

// let styleVisible = ref(true) // 风格弹窗状态
// bass, drum, guitar, rock, pop, electro, electronic, metal, heavy metal, heavy metal, heavy metal, heavy metal
let stylelist = ["bass", "drum", "guitar", "rock", "pop", "electro", "electronic", "metal", "heavy metal", "Subscribe", "heavy metal", "beat", "synth", "hard rock", "rap", "catchy", "powerful", "indie pop"]

const addStyle = item => {
    obj.value.tags = obj.value.tags.trim()
    if (obj.value.tags) obj.value.tags += ","

    obj.value.tags += item
}

const handleMusicList = index => {
    let targetlist = list.value || []
    let target = targetlist[index]
    listIndex.value = index

    // console.log(target.metadataid)
    if (target.status !== "complete") {
        monitorMusicState(target.metadataid || "没有metadataid")
    }
    getMusicDetails(target.id)
}

let monitorMusicTimer = null
// 监听音乐的生成状态
const monitorMusicState = metadataid => {
    clearTimeout(monitorMusicTimer)
    monitorMusicTimer = setTimeout(() => {
        monitorMusic({ metadataid }).then(res => {
            if (res.code == 401) {
                getLoginQrcode()
                return
            }
            if (res.code != 200) return
            const data = res.data || {}
            const dataList = data.list || []

            if (data.status != "complete") {
                monitorMusicState(metadataid)
            }

            let obj = {}
            // let isnoneed = 0 // isnoneed > 0 需要继续监听的意思   submitted streaming 代表生产中
            dataList.forEach((element, index) => {
                // if (element.status != "complete") isnoneed++
                // 打开详情并且 已经生成成功后刷新详情
                if (element.status == "complete" && songInfo.value.sid == element.sid) {
                    getMusicDetails(element.id)
                }
                obj[element.sid] = index
            })

            // if (isnoneed > 0) {
            //     monitorMusicState(metadataid)
            // }

            let targetlist = list.value || []
            targetlist.forEach((element, index) => {
                if (obj[element.sid] >= 0) {
                    targetlist[index] = dataList[obj[element.sid]]
                    delete obj[element.sid]
                }
            })

            for (const key in obj) {
                targetlist.unshift(dataList[obj[key]])
            }
            list.value = targetlist
        })
    }, 10000)
}

let songInfo = ref({}) // 歌详情

const getMusicDetails = id => {
    getDetails({ id }).then(res => {
        if (res.code == 401) {
            getLoginQrcode()
            return
        }
        if (res.code != 200) {
            ElMessage({
                showClose: true,
                message: res.message,
            })
            return
        }

        songInfo.value = res.data

        previewState.value = true
    })
}

const audio = ref(null)
const isPlaying = ref(false)
let audioSrc = ref("")

let previewState = ref(false)
const closeInfo = () => {
    // previewState.value = false
    songInfo.value = {}
}

const playAudio = index => {
    if (index == undefined) {
        index = listIndex.value || 0
    }
    let targetlist = list.value || []
    let target = targetlist[index] || {}
    const url = target.audio_url || ""
    if (audioSrc.value != url) {
        audio.value.src = url
        currentTime.value = 0
    }
    audio.value.play()
    listIndex.value = index
}

const togglePlayPause = () => {
    if (isPlaying.value) {
        pauseAudio()
    } else {
        playAudio()
    }
}

const updatePlayStatus = () => {
    isPlaying.value = !audio.value.paused
    audioSrc.value = audio.value.src || ""
}

const pauseAudio = () => {
    audio.value.pause()
}

const nextAudio = () => {
    if (listIndex.value == null) return
    let targetlist = list.value || []
    let index = listIndex.value
    index = (index + 1) % targetlist.length
    let target = targetlist[index]
    audio.value.src = target.audio_url
    audio.value.play()

    listIndex.value = index
}

const prevAudio = () => {
    if (listIndex.value == null) return

    let targetlist = list.value || []
    let index = listIndex.value
    index = (index - 1 + targetlist.length) % targetlist.length

    let target = targetlist[index]
    audio.value.src = target.audio_url
    audio.value.play()

    listIndex.value = index
}

const currentTime = ref(0)
const duration = ref(0)

const updateCurrentTime = () => {
    // console.log("4454545")
    currentTime.value = audio.value.currentTime
}

const updateDuration = () => {
    duration.value = audio.value.duration
}

const seekAudio = value => {
    if (value >= 0) {
        audio.value.currentTime = value
    }
    // console.log(value)

    if (isNaN(value)) {
        currentTime.value = 0
        // console.log(currentTime.value)
    }
}

const formatTime = time => {
    if (isNaN(time)) return "0:00"
    if (time == Infinity) {
        return "-- : --"
    }
    const minutes = Math.floor(time / 60)
    const seconds = Math.floor(time % 60)
    return `${minutes}:${seconds < 10 ? "0" : ""}${seconds}`
}

// 生成类似
const generatingSimilar = index => {
    let target = list.value[index]

    // 判断是显示哪个模式
    if (target.metadata.prompt) {
        cutType("custom")
    } else {
        cutType("inspiration")
    }

    // console.log("target", target)

    nextTick(() => {
        // console.log("target.model_name", target.model_name)
        obj.value = { ...target.metadata, mv: target.model_name, title: target.title }
    })
}

// 判断风格是否已经在输入框了
const judgingExistence = item => {
    const tags = obj.value?.tags || ""
    return !tags.includes(item)
}

// 生成歌词
const lyricsGenerating = () => {
    if (lyricsMonitorState.value) return
    const prompt = obj.value.prompt || ""
    lyricsMonitorState.value = true
    lyricsGenerateHttp({ prompt })
        .then(res => {
            if (res.code == 401) {
                getLoginQrcode()
                lyricsMonitorState.value = false
                return
            }

            if (res.code != 200) {
                ElMessage({
                    showClose: true,
                    message: res.message,
                    type: "error",
                })
                lyricsMonitorState.value = false
                return
            }
            const data = res.data
            // console.log("data", data)
            lyricsMonitor(data.id)
        })
        .catch(() => {
            lyricsMonitorState.value = false
        })
}

let lyricsMonitorTimer = null
let lyricsMonitorState = ref(false) // 生成状态
// 监听歌词生成
const lyricsMonitor = id => {
    setTimeout(() => {
        lyricsMonitorHttp({ id })
            .then(res => {
                if (res.code == 401) {
                    getLoginQrcode()
                    return
                }

                const data = res.data

                if (data.status == "complete") {
                    obj.value.prompt = data.text
                    obj.value.title = data.title
                    lyricsMonitorState.value = false
                } else {
                    lyricsMonitor(id)
                }
            })
            .catch(err => {
                console.log("err", err)
                lyricsMonitor(id)
            })
    }, 3000)
}

// 退出登录
const logOut = () => {
    localStorage.setItem("token", "")
    islogin.value = false
    quitLoginHttp()
    songInfo.value = {}
    list.value = []
}

// 登录
const register = () => {
    getLoginQrcode()
}

// 点击列表 点赞
const handlelike = index => {
    let targetlist = list.value || []
    let target = targetlist[index] || {}

    likeDetailsHttp({ id: target.id }).then(res => {
        if (res.code != 200) {
            ElMessage({
                showClose: true,
                message: res.message,
                type: "error",
            })
            return
        }
        const data = res.data || {}
        list.value[index]["is_upvote"] = data.is_upvote || 0
        // 判断 详情预览和点赞的是不是同一首
        if (target.sid == songInfo.value.sid) {
            songInfo.value["is_upvote"] = data.is_upvote || 0
        }
    })

    // target.is_liked = 1
}

// 切换纯音乐
const switchchange = value => {
    // 当切换到纯音乐时去掉歌词
    if (!value) {
        obj.value.prompt = ""
    }
}
</script>

<template>
    <div>
        <!-- <div class="flexflex" style="height: calc(100vh - 69px); overflow: auto;"> -->
        <div class="flexflex">
            <div class="left-box">
                <img class="left-bj left-bj1" src="./assets/img/left-bj1.png" />
                <img class="left-bj left-bj2" src="./assets/img/left-bj2.png" />
                <img class="left-bj left-bj3" src="./assets/img/left-bj1.png" />
                <img class="hemisphere-icon" src="./assets/img/hemisphere-icon.png" />
                <img class="logo" src="./assets/img/logo-icon.png" />
                <img class="star" src="./assets/img/star-icon.png" />

                <div class="tab-box">
                    <div class="tab-item" :class="{ 'sel': type == 'inspiration' }" @click="cutType('inspiration')">灵感模式</div>
                    <div class="tab-item" :class="{ 'sel': type == 'custom' }" @click="cutType('custom')">自定义模式</div>
                </div>
                <template v-if="type == 'inspiration'">
                    <div class="description">
                        <div class="title-box flexacenter">
                            <div class="title-left flexacenter">
                                歌曲描述
                                <el-popover placement="right" :width="300" trigger="click" content='描述你想要的音乐风格和主题（例如"关于假日"）。使用流派和氛围，而不是特定的艺术家和歌曲。' popper-class="popper-description">
                                    <template #reference>
                                        <img class="question-icon" src="./assets/img/question-icon.svg" />
                                    </template>
                                </el-popover>
                            </div>
                            <div class="title-right"></div>
                        </div>
                        <el-input v-model="obj.gpt_description_prompt" class="description-input" style="width: 100%;" type="textarea" placeholder="请输入您的歌曲描述，例如：一首关于青春的冷酷的电子歌曲" maxlength="200" show-word-limit autosize resize="none" />
                    </div>
                    <div class="toggle-switch title-box flexacenter">
                        <div class="title-left flexacenter">
                            <el-switch v-model="obj.has_vocal" class="ml-2" style="--el-switch-on-color: #fbd38d; --el-switch-off-color: #ffffff3d;" :active-value="false" :inactive-value="true" />
                            纯音乐
                            <el-popover placement="right" :width="150" trigger="click" content="没有歌词的音乐。">
                                <template #reference>
                                    <img class="question-icon" src="./assets/img/question-icon.svg" />
                                </template>
                            </el-popover>
                        </div>
                    </div>
                    <div class="section model">
                        <div class="title-box flexacenter">
                            <div class="title-left flexacenter">
                                音乐模型
                                <el-popover placement="right" :width="150" trigger="click" content="官方suno音乐模型">
                                    <template #reference>
                                        <img class="question-icon" src="./assets/img/question-icon.svg" />
                                    </template>
                                </el-popover>
                            </div>
                        </div>

                        <el-select v-model="obj.mv" placeholder="选择模型" size="large" popper-class="model-select" :popper-append-to-body="false" :suffix-icon="triangleIcon">
                            <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
                        </el-select>
                    </div>
                    <div class="creation-btn flexcenter" @click="creativeMusic()">创作</div>
                </template>
                <template v-else>
                    <div class="toggle-switch title-box flexacenter">
                        <div class="title-left flexacenter">
                            <el-switch v-model="obj.has_vocal" style="--el-switch-on-color: #fbd38d; --el-switch-off-color: #ffffff3d;" :active-value="false" :inactive-value="true" @change="switchchange" />
                            纯音乐
                            <el-popover placement="right" :width="150" trigger="click" content="没有歌词的音乐。">
                                <template #reference>
                                    <img class="question-icon" src="./assets/img/question-icon.svg" />
                                </template>
                            </el-popover>
                        </div>
                    </div>

                    <div class="lyric" v-if="obj.has_vocal">
                        <div class="title-box flexacenter">
                            <div class="title-left flexacenter">
                                歌词
                                <el-popover placement="right" :width="300" trigger="click" content="随机生成歌词，自己写，或者从Al那里得到一些帮助。使用两首诗（8行）获得最佳效果。">
                                    <template #reference>
                                        <img class="question-icon" src="./assets/img/question-icon.svg" />
                                    </template>
                                </el-popover>
                            </div>
                            <div class="title-right flexacenter">
                                <!-- <el-popover popper-class="type-popover" placement="right" :width="280" trigger="click" :teleported="false">
                                    <div class="lyric-type flexflex">
                                        <div class="lyric-type-item flexcenter" v-for="item in 7" :key="item">主歌</div>
                                    </div>
                                    <template #reference>
                                        <div class="meta-tags flexcenter">添加元标签</div>
                                    </template>
                                </el-popover> -->
                            </div>
                        </div>

                        <div class="lyric-content">
                            <el-input v-model="obj.prompt" class="lyric-input" maxlength="3000" style="width: 100%;" :rows="4" type="textarea" placeholder="请输入你的歌词" autosize resize="none" />
                            <div class="random-btn flexcenter" @click="lyricsGenerating()">
                                <img v-if="lyricsMonitorState" class="loading-icon" src="./assets/img/loading-icon.svg" />
                                <template v-else>{{ obj.prompt ? "AI优化歌词" : "生成歌词" }}</template>
                            </div>
                            <div class="numberwords">{{ obj.prompt.length }}/3000</div>
                        </div>
                    </div>
                    <div class="style">
                        <div class="title-box flexacenter">
                            <div class="title-left flexacenter">
                                音乐风格
                                <el-popover placement="right" :width="300" trigger="click" content="描述你想要的音乐风格 例如：流行、摇滚、史诗。Suno的模型无法识别具体的艺人名称，但能理解音乐类型和氛围。">
                                    <template #reference>
                                        <img class="question-icon" src="./assets/img/question-icon.svg" />
                                    </template>
                                </el-popover>
                            </div>
                        </div>
                        <div class="style-content">
                            <el-input v-model="obj.tags" class="style-input" maxlength="2000" style="width: 100%;" :rows="4" type="textarea" placeholder="输入音乐风格（英文）" autosize resize="none" />
                            <!-- <div class="random-btn flexcenter">选择音乐风格</div> -->
                            <div class="style-list">
                                <template v-for="item in stylelist">
                                    <div :key="item" class="style-item" v-if="judgingExistence(item)" @click="addStyle(item)">{{ item }}</div>
                                </template>
                            </div>
                        </div>
                    </div>
                    <div class="name">
                        <div class="title-box flexacenter">
                            <div class="title-left flexacenter">
                                歌曲名称
                                <el-popover placement="right" trigger="click" content="为你的歌曲命名">
                                    <template #reference>
                                        <img class="question-icon" src="./assets/img/question-icon.svg" />
                                    </template>
                                </el-popover>
                            </div>
                        </div>

                        <el-input class="name-input" v-model="obj.title" style="width: 300px;" maxlength="50" placeholder="请输入歌曲名称" />
                    </div>
                    <div class="section model">
                        <div class="title-box flexacenter">
                            <div class="title-left flexacenter">
                                音乐模型
                                <el-popover placement="right" :width="150" trigger="click" content="官方suno音乐模型">
                                    <template #reference>
                                        <img class="question-icon" src="./assets/img/question-icon.svg" />
                                    </template>
                                </el-popover>
                            </div>
                        </div>

                        <el-select v-model="obj.mv" placeholder="选择模型" size="large" style="width: 100%;" popper-class="model-select" :suffix-icon="triangleIcon">
                            <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
                        </el-select>
                    </div>
                    <div class="creation-btn flexcenter" @click="creativeMusic()">创作</div>
                </template>
                <!-- <div class="flex1"></div> -->
                <!-- <div class="user-box" v-if="islogin"> -->
                <div class="user-box" v-if="false">
                    <img class="user-img" src="https://cdn1.suno.ai/defaultPink.jpg" />
                    <div class="user-text flex1">微信用户</div>

                    <el-popover popper-class="user-popover" placement="top" :width="300" trigger="click">
                        <div class="user-btn flexcenter" @click.stop="logOut()">退出登录</div>
                        <template #reference>
                            <div class="user-dot flexcenter">
                                <img class="user-dot-icon" src="./assets/img/dot.svg" />
                            </div>
                        </template>
                    </el-popover>
                </div>
            </div>
            <div class="middle-box flex1">
                <template v-if="list.length == 0">
                    <div class="nodata">暂无数据</div>
                </template>
                <template v-else>
                    <div class="list">
                        <div class="item flexflex" :class="{ 'sel': listIndex == index, 'playing': audioSrc == item.audio_url }" v-for="(item, index) in list" :key="index" @click="handleMusicList(index)">
                            <div class="progress-bar" v-if="item.status != 'complete'">生成中...</div>
                            <div class="img-box" @click="isPlaying && audioSrc == item.audio_url ? pauseAudio() : playAudio(index)">
                                <img v-if="item.image_url" class="img" :src="item.image_url" />
                                <img v-else class="img" src="https://suno.ansnid.com/attachment/Zvt57TuJSUvkyhw-xG7avCGHpt5oNTyM1Nwws44-UqaPEyOpLewjBmkLTe6SsJ5o8oxYDW_C7QrwtE0o7mQElMUC3lm6UrpsPr3ey21qvjUeOOPrNv6_QpsEVrOxyJ36niqc_cWN6UYoEk7POhf2DtewNDQyOQ~~" />
                                <div class="play flexcenter">
                                    <img v-if="audioSrc == item.audio_url && isPlaying" class="suspend-btn" src="./assets/img/suspend.png" />
                                    <img v-else class="play-btn" src="./assets/img/play-icon.png" />
                                </div>
                            </div>
                            <div class="content flexflex flex1">
                                <div class="name">{{ item.title }}</div>
                                <div class="desc">{{ item.tags || item?.metadata?.tags }}</div>
                            </div>

                            <div class="like-box flexcenter" @click.stop="handlelike(index)">
                                <img v-if="item.is_upvote == 1" class="like-icon" src="./assets/img/like-c-icon.png" />
                                <img v-else class="like-icon" src="./assets/img/like-icon.png" />
                            </div>

                            <el-popover popper-class="dot-popover" placement="bottom" :width="220" trigger="click" :teleported="false">
                                <div class="dot-list" @click.stop="">
                                    <!-- <a class="dot-item" target="_parent" v-if="item.audio_url" :href="item.audio_url" :download="item.title + '.mp3'">下载MP3</a> -->
                                    <a class="dot-item" target="_blank" v-if="item.audio_url" :href="item.audio_url">下载MP3</a>
                                    <a class="dot-item" target="_blank" v-if="item.video_url" :href="item.video_url">下载视频</a>
                                    <div class="dot-item" @click="generatingSimilar(index)">生成类似</div>
                                </div>
                                <template #reference>
                                    <div class="dot flexcenter" @click.stop="">
                                        <img class="dot-icon" src="./assets/img/dot.svg" />
                                    </div>
                                </template>
                            </el-popover>
                        </div>
                    </div>
                </template>
            </div>
            <!-- <div class="right-box" v-if="previewState"> -->
            <div class="right-box flexflex">
                <template v-if="JSON.stringify(songInfo) === '{}'">
                    <div class="nosong">选择要预览的歌曲。</div>
                </template>
                <template v-else>
                    <div class="song-info-box">
                        <div class="close flexcenter" @click="closeInfo()">
                            <img class="close-icon" src="./assets/img/icon12.svg" />
                        </div>
                        <img class="song-picture" :src="songInfo.image_large_url" />
                        <div class="song-info">
                            <div class="name">{{ songInfo.title }}</div>
                            <div class="desc" v-html="songInfo?.metadata?.tags"></div>
                            <div class="like-box flexcenter" @click.stop="handlelike(listIndex)">
                                <img v-if="songInfo.is_upvote == 0" class="like-icon" src="./assets/img/like-icon.png" />
                                <img v-else class="like-icon" src="./assets/img/like-c-icon.png" />
                            </div>
                            <div class="desc" v-html="songInfo?.metadata?.prompt"></div>
                        </div>
                    </div>
                </template>

                <div class="register-box flexacenter" v-if="islogin">
                    <div class="register-text">Welcome！</div>
                    <div class="register-btn" @click.stop="logOut()">[退出登录]</div>
                </div>
            </div>
        </div>

        <div class="base-bottom flexflex">
            <div class="base-middle flexflex">
                <div class="btn flexacenter">
                    <div class="btn-item btn-left flexcenter" @click="prevAudio()">
                        <img class="btn-icon" src="./assets/img/arrows-icon.svg" />
                    </div>
                    <div class="btn-item btn-centre flexcenter" @click="togglePlayPause()">
                        <img v-if="isPlaying" class="suspend" src="./assets/img/suspend-icon.svg" />
                        <img v-else class="suspend" src="./assets/img/play-icon.svg" />
                    </div>
                    <div class="btn-item btn-right flexcenter" @click="nextAudio()">
                        <img class="btn-icon" src="./assets/img/arrows-icon.svg" />
                    </div>
                </div>
                <div class="audio-box flexacenter">
                    <div class="time">{{ formatTime(currentTime) }}</div>
                    <el-slider class="progress-box" :show-tooltip="false" v-model="currentTime" :min="0" :max="duration" @change="seekAudio" />
                    <div class="time time-right">{{ formatTime(duration) }}</div>
                </div>
                <!-- <img class="cyclical-icon" src="./assets/img/loop.png" />
                <img class="cyclical-icon" src="./assets/img/single.png" /> -->
            </div>
        </div>

        <el-dialog class="wxlogin" v-model="wxloginVisible" width="480" :before-close="handleClose" align-center="true" :show-close="false">
            <div class="wxlogin-box">
                <div class="close-box">
                    <img class="close-icon" src="" />
                </div>
                <div class="wxlogin-title">微信登录</div>
                <div class="qrcode-box flexcenter">
                    <img class="qrcode-img" :src="qrcode" />
                    <div class="lose-box flexcenter" v-if="wxloginQrcodeLose" @click="getLoginQrcode()">
                        二维码失效，点击重新获取
                    </div>
                </div>
                <div class="hint">扫码关注【SunoAI音乐创作工具】即可登录</div>
            </div>
        </el-dialog>

        <audio ref="audio" @timeupdate="updateCurrentTime" @loadedmetadata="updateDuration" @ended="nextAudio" @play="updatePlayStatus" @pause="updatePlayStatus"></audio>
    </div>
</template>

<style scoped lang="less">
audio {
    display: none;
}
body {
    background-color: #000;
}

.left-box {
    width: 320px;
    // height: calc(100vh - 69px);
    height: 100vh;
    overflow: auto;
    padding: 10px;
    background-color: #000;
    // background-image: url("./assets/img/left-bj.svg");
    background: -webkit-linear-gradient(289.179008025811deg, rgba(107, 77, 229, 1) 0%, rgba(144, 91, 212, 1) 38%, rgba(83, 37, 142, 1) 70%, rgba(47, 51, 145, 1) 100%);
    background: -moz-linear-gradient(160.820991974189deg, rgba(107, 77, 229, 1) 0%, rgba(144, 91, 212, 1) 38%, rgba(83, 37, 142, 1) 70%, rgba(47, 51, 145, 1) 100%);
    background: linear-gradient(160.820991974189deg, rgba(107, 77, 229, 1) 0%, rgba(144, 91, 212, 1) 38%, rgba(83, 37, 142, 1) 70%, rgba(47, 51, 145, 1) 100%);
    // border-right: 1px solid #252323;
    border-right: 1px solid rgba(255, 255, 255, 0.2);
    // height: calc(100vh - 69px);
    position: relative;
    z-index: 1;
    // display: flex;
    // flex-direction: column;

    .left-bj {
        &.left-bj1 {
            top: 0;
            height: 341px;
        }
        &.left-bj2 {
            top: 341px;
            height: 551px;
            transform: rotate(180deg);
        }
        &.left-bj3 {
            top: 892px;
        }
        position: fixed;
        left: 0;
        width: 319px;
        // height: 440px;
        z-index: -1;
    }

    .hemisphere-icon {
        position: absolute;
        top: 0;
        left: 0;
        width: 80px;
        height: 83px;
    }
    .logo {
        width: 131px;
        height: 32px;
        margin: 20px auto 44px;
        display: block;
    }
    .star {
        z-index: -1;
        position: absolute;
        bottom: 10px;
        left: 0;
        width: 154px;
        height: 158px;
        left: 34px;
        bottom: 63px;
    }
    .user-box {
        display: flex;
        align-items: center;
        // padding: 4px;
        padding-left: 10px;
        margin-top: 10px;
        margin-bottom: 10px;
        .user-img {
            width: 32px;
            height: 32px;
            border-radius: 50%;
        }
        .user-text {
            color: #fff;
            font-size: 14px;
            padding-left: 7px;
        }

        .user-dot {
            padding: 0 12px;
            min-width: 32px;
            height: 32px;
            cursor: pointer;
            border-radius: 6px;
            .user-dot-icon {
                width: 16px;
                height: 16px;
            }
        }
    }

    .tab-box {
        display: flex;
        align-items: center;
        padding: 0 5px;
        height: 46px;
        border: 1px solid rgba(255, 255, 255, 0.196078);
        background: rgba(255, 255, 255, 0.0980392);
        border-radius: 10px;
        color: #adadad;
        margin-bottom: 24px;

        .tab-item {
            flex: 1;
            cursor: pointer;
            text-align: center;
            font-size: 18px;
            height: 36px;
            line-height: 36px;
            color: rgba(255, 255, 255, 0.8);
            &:first-of-type {
                margin-right: 5px;
            }
            &.sel {
                color: #000;
                background: -webkit-linear-gradient(344.577838681261deg, rgba(254, 233, 125, 1) 0%, rgba(231, 194, 91, 1) 49%, rgba(254, 140, 125, 1) 100%);
                background: -moz-linear-gradient(105.422161318739deg, rgba(254, 233, 125, 1) 0%, rgba(231, 194, 91, 1) 49%, rgba(254, 140, 125, 1) 100%);
                background: linear-gradient(105.422161318739deg, rgba(254, 233, 125, 1) 0%, rgba(231, 194, 91, 1) 49%, rgba(254, 140, 125, 1) 100%);
                border: none;
                border-radius: 10px;
            }
        }
    }

    .description {
        margin-bottom: 24px;
        .title {
            margin-bottom: 10px;
        }

        .description-input {
            /deep/ .el-textarea__inner {
                box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.196078) inset !important;
                background: rgba(255, 255, 255, 0.0980392);
                border-radius: 10px;

                color: #fff;
                min-height: 180px !important;
                // max-height: 300px;
                padding: 16px 13px;
            }
            /deep/ .el-input__count {
                font-size: 13px;
                color: rgba(255, 255, 255, 0.498039215686275);
                background: transparent;
            }
            // min-height: 31px;
            min-height: 94px;
            width: 100%;
            color: #ffffffeb;
            line-height: 1.5;
            border-radius: 4px;
        }
    }

    .toggle-switch {
        color: #fff;
        font-size: 14px;
        .el-switch {
            margin-right: 10px;
        }
        margin-bottom: 24px !important;
    }

    .title-box {
        margin-bottom: 10px;
        justify-content: space-between;

        .title-left {
            font-size: 16px;
            color: rgba(255, 255, 255, 0.8);
            .question-icon {
                width: 16px;
                height: 16px;
                margin-left: 10px;
                cursor: pointer;
            }

            /deep/ .el-popper {
                font-size: 12px;
                color: #fff;
            }
        }
        .title-right {
            .meta-tags {
                width: 80px;
                height: 28px;
                color: rgb(204 204 204);
                background-color: rgb(26 26 26);
                font-size: 12px;
                border-radius: 4px;
                cursor: pointer;
            }
        }
    }

    .model {
        margin-bottom: 24px;
        .title {
            margin-bottom: 10px;
        }
        /deep/ .el-select__wrapper {
            box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.196078) inset !important;
            background: rgba(255, 255, 255, 0.0980392);
            height: 40px;
            line-height: 40px;
            border-radius: 10px;

            .el-select__selected-item {
                color: #fff;
            }
        }

        // /deep/ .el-popper {
        //     .el-select-dropdown.model-select {
        //         .el-select-dropdown__item {
        //             color: #606266;
        //             &.is-selected {
        //                 color: #fff;
        //             }
        //             &.is-hovering {
        //                 background: #232426 !important;
        //             }
        //         }
        //     }
        // }
    }

    .creation-btn {
        padding: 0 16px;
        cursor: pointer;
        min-height: 44px;
        height: 50px;
        background: -webkit-linear-gradient(350.537677791974deg, rgba(254, 233, 125, 1) 0%, rgba(231, 194, 91, 1) 49%, rgba(254, 140, 125, 1) 100%);
        background: -moz-linear-gradient(99.4623222080256deg, rgba(254, 233, 125, 1) 0%, rgba(231, 194, 91, 1) 49%, rgba(254, 140, 125, 1) 100%);
        background: linear-gradient(99.4623222080256deg, rgba(254, 233, 125, 1) 0%, rgba(231, 194, 91, 1) 49%, rgba(254, 140, 125, 1) 100%);
        border: none;
        border-radius: 10px;
        font-weight: 650;
        font-size: 24px;
        color: #000000;
    }

    .lyric {
        .title-box {
            .el-popper.type-popover {
                .lyric-type {
                    justify-content: space-between;
                    flex-wrap: wrap;
                    gap: 10px;
                    padding: 10px;
                    .lyric-type-item {
                        width: 72px;
                        height: 24px;
                        color: rgb(170 170 170);
                        cursor: pointer;
                        border-radius: 9999px;
                        border: 1px solid #aaa;
                        &:hover {
                            border-color: #ddd;
                        }
                    }
                }
            }
        }

        .lyric-content {
            /deep/ .lyric-input {
                .el-textarea__inner {
                    background: transparent;
                    box-shadow: none;
                    color: #fff;
                    min-height: 107px !important;
                    max-height: 300px;
                    padding: 16px 13px;
                }

                .el-input__count {
                    background: transparent;
                }
            }
            padding-bottom: 7px;
            box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.196078) inset !important;
            // border: 1px solid rgba(255, 255, 255, 0.196078);
            background: rgba(255, 255, 255, 0.0980392);

            border-radius: 10px;
            color: #adadad;
            margin-bottom: 24px;

            position: relative;
            .numberwords {
                position: absolute;
                bottom: 6px;
                right: 13px;
                font-size: 13px;
                color: rgba(255, 255, 255, 0.498039215686275);
            }
        }
    }

    .style {
        .style-content {
            /deep/ .style-input {
                .el-textarea__inner {
                    background: transparent;
                    box-shadow: none;
                    min-height: 100px !important;
                    color: #fff;
                    max-height: 300px;
                    padding: 16px 13px;
                }
            }
            padding-bottom: 5px;
            // box-shadow: 0 0 0 1px #252323 inset !important;
            // margin-bottom: 10px;
            border: 1px solid rgba(255, 255, 255, 0.196078);
            background: rgba(255, 255, 255, 0.0980392);
            margin-bottom: 24px;
            border-radius: 10px;

            .style-list {
                width: calc(100% - 12px);
                display: flex;
                overflow: auto;
                white-space: pre;
                margin: 0 6px;
                box-sizing: border-box;

                .style-item {
                    padding: 0 8px;
                    font-size: 14px;
                    color: #000000;
                    cursor: pointer;
                    border-radius: 10px;
                    height: 26px;
                    line-height: 26px;
                    background-color: rgba(255, 255, 255, 0.6);
                    margin-bottom: 8px;

                    &:not(:last-of-type) {
                        margin-right: 6px;
                    }
                }

                &::-webkit-scrollbar {
                    width: 13px;
                    height: 13px;
                    background-color: rgba(255, 255, 255, 0.6);
                    border-radius: 10px;
                }

                &::-webkit-scrollbar-thumb {
                    border-radius: 10px;
                    background-color: rgba(255, 255, 255, 1);
                }
            }
        }
    }

    .random-btn {
        // background: rgba(255, 255, 255, 0.16);
        // width: 120px;
        margin-left: 7px;
        cursor: pointer;
        // padding: 0 12px;
        // min-width: 32px;
        // height: 32px;
        // border-radius: 6px;
        // color: #fff;
        // font-size: 12px;
        width: 109px;
        height: 36px;
        background-color: rgba(255, 255, 255, 0.6);
        // border: none;
        border-radius: 10px;
        font-size: 16px;
        color: #000000;
        .loading-icon {
            width: 20px;
            height: 20px;
            animation: rotate 1s linear infinite;
            @keyframes rotate {
                0% {
                    transform: rotate(0deg);
                }
                100% {
                    transform: rotate(360deg);
                }
            }
        }
    }

    .name {
        margin-bottom: 24px;

        .name-input {
            /deep/ .el-input__wrapper {
                // background: none;
                // box-shadow: 0 0 0 1px #252323 inset !important;
                box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.196078) inset !important;
                background: rgba(255, 255, 255, 0.0980392);
                height: 40px;
                border-radius: 10px;
            }

            /deep/ .el-input__inner {
                color: #fff;
            }
        }
    }
}

/deep/ .el-popper {
    background: rgb(25, 25, 26) !important;
    border: none !important;
    box-shadow: 0 0 0 1px #252323 inset !important;

    &.is-light .el-popper__arrow:before {
        border-color: #252323 !important;
        background: rgb(25, 25, 26) !important;
    }
}

.right-box {
    width: 294px;
    height: 100vh;
    overflow: auto;
    // height: calc(100vh - 69px);
    overflow: auto;
    position: relative;
    flex-direction: column;
    justify-content: space-between;
    .song-info-box {
        height: calc(100vh - 40px);
        overflow: auto;
    }
    .nosong {
        color: #a0aec0;
        font-size: 14px;
        text-align: center;
        padding-top: 40px;
    }

    .close {
        position: absolute;
        top: 10px;
        right: 10px;
        background-color: #fff3;
        width: 40px;
        height: 40px;
        border-radius: 5px;
        cursor: pointer;
    }

    .song-picture {
        width: 100%;
    }
    .song-info {
        font-size: 14px;
        padding: 10px;
        color: #fff;
        overflow: auto;

        .name {
            line-height: 24px;
            font-size: 14px;
            word-wrap: break-word;
        }

        .desc {
            white-space: pre-line;
            line-height: 24px;
            // margin-bottom: 40px;
            word-wrap: break-word;
        }

        .like-box {
            padding: 0 10px;
            width: fit-content;
            height: 32px;
            cursor: pointer;
            margin-bottom: 20px;

            &:hover {
                border-radius: 5px;
                background: rgba(255, 255, 255, 0.08);
            }

            .like-icon {
                width: 17px;
            }
        }
    }

    .register-box {
        justify-content: space-between;
        align-items: center;
        height: 40px;
        padding: 0 15px;
        border-top: 1px solid rgba(255, 255, 255, 0.2);
        background-color: rgba(51, 51, 51, 1);

        .register-text {
            font-weight: 650;
            font-size: 20px;
            color: #8080ff;
        }

        .register-btn {
            font-size: 13px;
            cursor: pointer;
            color: rgba(255, 255, 255, 0.498039215686275);
        }
    }
}

.middle-box {
    border-right: 1px solid rgba(255, 255, 255, 0.2);
    // height: calc(100vh - 69px);
    height: 100vh;
    overflow: auto;
    padding-top: 10px;
    padding-bottom: 120px;
    .nodata {
        color: #a0aec0;
        font-size: 14px;
        text-align: center;
        padding-top: 40px;
    }

    .list {
        .item {
            padding-left: 30px;
            padding-right: 30px;
            margin-bottom: 10px;
            cursor: pointer;
            align-items: center;
            &.sel,
            &:hover {
                background: radial-gradient(3010.06% 152.11% at 27.33% 38.98%, rgba(61, 58, 58, 0.43) 0%, rgba(25, 24, 24, 0.57) 100%) !important;
            }

            &.playing {
                .img-box {
                    .play {
                        display: flex;
                    }
                }
                .content {
                    .name {
                        color: #e7c25b;
                    }
                }
            }

            .img-box {
                position: relative;
                width: 80px;
                height: 80px;
                margin-right: 20px;
                border-radius: 6px;

                .img {
                    width: 80px;
                    height: 80px;
                    border-radius: 6px;
                }
                &:hover {
                    .play {
                        display: flex;
                    }
                }
                .suspend-box,
                .play {
                    position: absolute;
                    top: 0;
                    left: 0;
                    width: 100%;
                    height: 100%;
                    background: rgba(0, 0, 0, 0.6);
                    .play-btn {
                        width: 36px;
                    }

                    .suspend-btn {
                        width: 46px;
                    }
                }

                .play {
                    display: none;
                }
            }

            position: relative;

            .progress-bar {
                width: 100%;
                height: 100%;
                position: absolute;
                top: 0;
                left: 0;
                z-index: 1;
                color: #fff;
                font-size: 14px;
                display: flex;
                align-items: center;
                justify-content: center;
                background: linear-gradient(270deg, rgba(0, 0, 0, 0.8), rgba(255, 255, 255, 0.8));
                background-size: 300% 100%;
                animation: gradientAnimation 5s linear infinite;
            }

            @keyframes gradientAnimation {
                0% {
                    background-position: 0% 50%;
                }
                50% {
                    background-position: 100% 50%;
                }
                100% {
                    background-position: 0% 50%;
                }
            }

            .content {
                font-size: 14px;
                line-height: 21px;
                flex-direction: column;
                justify-content: center;
                margin-right: 10px;
                .name {
                    font-weight: 700;
                    color: #fff;
                    word-break: break-word;
                    font-size: 18px;
                    color: rgba(255, 255, 255, 0.8);
                    margin-bottom: 6px;
                }
                .desc {
                    overflow: hidden;
                    display: -webkit-box;
                    -webkit-box-orient: vertical;
                    -webkit-line-clamp: 2;
                    line-clamp: 2;
                    word-break: break-all;
                    word-wrap: break-word;
                    white-space: normal;
                    color: rgba(255, 255, 255, 0.8);
                    font-size: 14px;
                }
            }

            .like-box {
                padding: 0 10px;
                height: 32px;
                cursor: pointer;
                &:hover {
                    border-radius: 5px;
                    background: rgba(255, 255, 255, 0.08);
                }

                .like-icon {
                    width: 17px;
                }
            }

            .dot {
                padding: 0 10px;
                min-width: 32px;
                height: 32px;
                cursor: pointer;
                &:hover {
                    border-radius: 5px;
                    background: rgba(255, 255, 255, 0.08);
                }

                .dot-icon {
                    widows: 16px;
                    height: 16px;
                }
            }

            /deep/ .dot-popover {
                padding: 0;

                .dot-list {
                    padding: 5px 0;
                    .dot-item {
                        padding-left: 10px;
                        padding-right: 10px;
                        line-height: 30px;
                        cursor: pointer;
                        height: 30px;
                        font-size: 14px;
                        color: #fff;
                        display: block;
                        text-decoration: none;
                        &:hover {
                            background: radial-gradient(3010.06% 152.11% at 27.33% 38.98%, rgba(61, 58, 58, 0.43) 0%, rgba(25, 24, 24, 0.57) 100%);
                        }
                    }
                }
            }
        }
    }
}

.base-bottom {
    background-color: rgb(22 22 22);
    border: 1px solid rgba(255, 255, 255, 0.19);
    // border-top: 1px solid #222222;
    padding-left: 24px;
    padding-right: 24px;
    // padding-top: 24px;
    height: 68px;
    display: flex;
    justify-content: center;
    // align-items: center;
    position: fixed;
    bottom: 10px;
    width: 540px;
    height: 96px;
    border-radius: 10px;
    z-index: 10;
    left: 50%;
    transform: translateX(-50%);

    .base-middle {
        flex-direction: column;
        align-items: center;
        padding-top: 18px;
        margin-bottom: 6px;
        .btn {
            // margin-right: 24px;

            .btn-item {
                width: 36px;
                height: 36px;
                background: inherit;
                background-color: rgba(255, 255, 255, 0.8);
                border: none;
                border-radius: 18px;
                cursor: pointer;
                transition: all 0.3s;
                // &:hover {
                // .el-icon {
                //     font-size: 30px;
                // }
                // }

                .btn-icon {
                    width: 15px;
                    height: 16px;
                }

                &.btn-left {
                    .btn-icon {
                        transform: rotate(180deg);
                    }
                }

                &.btn-centre {
                    margin-left: 20px;
                    margin-right: 20px;
                    // background-color: #fbd38d;
                    background: transparent;
                    img {
                        width: 36px;
                        height: 36px;
                        // width: 20px;
                    }
                }
            }
        }

        .audio-box {
            position: relative;
            margin-left: 16px;
            margin-right: 16px;
            .time {
                top: -17px;
                left: 0;
                position: absolute;
                color: rgba(255, 255, 255, 0.8);
                font-size: 14px;
                &.time-right {
                    right: 0;
                    left: auto;
                }
            }

            .progress-box {
                width: 500px;

                /deep/ .el-slider__runway {
                    height: 6px;
                    background-color: rgba(255, 255, 255, 0.803921568627451);
                    .el-slider__bar {
                        background: rgba(128, 128, 255, 1);
                        height: 6px;
                    }
                }
                /deep/ .el-slider__button {
                    border: none;
                    height: 16px;
                    width: 16px;
                    background: rgba(128, 128, 255, 1);
                }
            }
        }
        .cyclical-icon {
            height: 14px;
            margin-right: 5px;
            margin: 0 12px;
            cursor: pointer;
        }
    }
}

/deep/ .el-dialog {
    border-radius: 10px;
    color: #fff !important;
    border: 1px solid rgba(255, 255, 255, 0.08) !important;
    background: rgb(25, 25, 26) !important;
    padding: 16px;
    .el-dialog__header {
        display: none;
    }

    &.wxlogin {
        .el-dialog__body {
            .wxlogin-box {
                display: flex;
                flex-direction: column;
                align-items: center;
                position: relative;

                .close-box {
                    width: 0;
                    height: 0;
                    position: absolute;
                    top: 15px;
                    right: 15px;
                }

                .wxlogin-title {
                    color: #969595;
                    padding: 0 20px;
                    height: 40px;
                    margin-bottom: 10px;
                    line-height: 40px;
                    font-size: 18px;
                }

                .qrcode-box {
                    width: 300px;
                    height: 300px;
                    position: relative;
                    .qrcode-img {
                        width: 100%;
                        height: 100%;
                    }
                    .lose-box {
                        position: absolute;
                        top: 0;
                        left: 0;
                        width: 100%;
                        height: 100%;
                        background: rgba(0, 0, 0, 0.6);
                        color: #fff;
                    }
                }

                .hint {
                    margin-top: 20px;
                    margin-bottom: 20px;
                    color: rgb(204 204 204);
                    text-align: center;
                }

                .remark {
                    text-align: center;
                    font-size: 12px;
                    color: rgb(180 185 191);
                    a {
                        color: rgb(88 101 242);
                        text-decoration: underline;
                    }
                }
            }
        }
    }
}
</style>

<style lang="less">
.el-popper {
    background: rgb(25, 25, 26) !important;
    border: none !important;
    box-shadow: 0 0 0 1px #252323 inset !important;
    font-size: 12px !important;
    color: #fff !important;

    &.is-light .el-popper__arrow:before {
        border-color: #252323 !important;
        background: rgb(25, 25, 26) !important;
        border-left-color: transparent !important;
        border-top-color: transparent !important;
    }
}

.el-popper.model-select {
    .el-select-dropdown__item {
        color: #606266;
        &.is-selected {
            color: #fff;
        }
        &.is-hovering {
            background: #232426 !important;
        }
    }
}
.user-popover {
    .user-btn {
        width: 100%;
        height: 40px;
        border-radius: 8px;
        cursor: pointer;
        margin-top: 12px;
        margin-bottom: 8px;
        border: 1px solid rgba(255, 255, 255, 0.16);
        color: #fff;
    }
}

.el-switch {
    .el-switch__core {
        height: 24px;
        min-width: 48px;
        border-radius: 48px;
        .el-switch__action {
            width: 18px;
            height: 18px;
        }
    }

    &.is-checked .el-switch__core {
        background: -webkit-linear-gradient(350.53767779deg, #fee97d 0%, #e7c25b 49%, #fe8c7d 100%);
        background: -moz-linear-gradient(99.46232221deg, #fee97d 0%, #e7c25b 49%, #fe8c7d 100%);
        background: linear-gradient(99.46232221deg, #fee97d 0%, #e7c25b 49%, #fe8c7d 100%);
        border: none;
        .el-switch__action {
            left: calc(100% - 21px);
        }
    }
}
</style>
