<template>
<div>
  <el-form inline :model="search">
    <el-form-item label="名称">
      <el-input size="small" v-model="search.name" />
    </el-form-item>
    <el-form-item label="所属歌单">
      <el-select size="small" v-model="search.lib_id" multiple collapse-tags>
        <el-option v-for="musicLib in musicLibs" :key="musicLib._id" :value="musicLib._id" :label="musicLib.name" />
      </el-select>
    </el-form-item>
    <el-form-item label="文件类型">
      <el-select size="small" v-model="search.ext" multiple >
        <el-option v-for="ext in exts" :key="ext" :value="ext" :label="ext" />
      </el-select>
    </el-form-item>
    <el-form-item label="标题">
      <el-input size="small" v-model="search.title" />
    </el-form-item>
    <el-form-item label="唱片集">
      <el-input size="small" v-model="search.album" />
    </el-form-item>
    <el-form-item label="艺术家">
      <el-input size="small" v-model="search.artist" />
    </el-form-item>
  </el-form>
  <div class="btn-container">
    <el-button type="success" plain size="small" icon="el-icon-caret-right" @click="playMusic">播放</el-button>
    <el-button type="primary" size="small" icon="el-icon-upload" @click="openUploadModal">上传音乐</el-button>
    <div class="search-btn">
      <el-button type="primary" @click="loadDataBase(true)" size="small" icon="el-icon-search">搜索</el-button>
      <el-button @click="reset" size="small" icon="el-icon-refresh-right">重置</el-button>
    </div>
  </div>
  <div class="table-container">
    <el-table :data="musicData" v-loading="loading" stripe height="715" @selection-change="dataSelect">
      <el-table-column type="selection" width="55" />
      <el-table-column prop="name" label="名称" show-overflow-tooltip role=""/>
      <el-table-column prop="ext" label="类型" width="100" />
      <el-table-column prop="size" label="文件大小" width="150">
        <template #default="scope">
          {{ prettyBytes(scope.row.size) }}
        </template>
      </el-table-column>
      <el-table-column prop="title" label="标题" show-overflow-tooltip />
      <el-table-column prop="album" label="唱片集" />
      <el-table-column prop="artist" label="艺术家" />
      <el-table-column prop="lib_id" label="所属歌单" >
        <template #default="scope">
          <template v-if="scope.row.isEditing && currentRow">
            <el-select v-model="currentRow.lib_id" size="mini">
              <el-option v-for="musicLib in musicLibs" :key="musicLib._id" :value="musicLib._id" :label="musicLib.name" />
            </el-select>
            <el-button type="text" @click="saveMusicLib(scope.row)">
              <i class="el-icon-check"></i>
            </el-button>
            <el-button type="text" @click="scope.row.isEditing = false">
              <i class="el-icon-close"></i>
            </el-button>
          </template>
          <template v-else>
            {{ findMusicLib(scope.row.lib_id) }}
            <el-button type="text" @click="updateLib(scope.row)">
              <i class="el-icon-edit-outline"></i>
            </el-button>
          </template>
        </template>
      </el-table-column>
      <el-table-column prop="lyric_id" label="歌词" width="120" >
        <template #default="scope">
          <i :class="scope.row.lyric_id ? 'el-icon-check' : 'el-icon-close'" ></i>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="230" >
        <template #default="scope">
          <el-button size="mini" plain @click="updateLyric(scope.row)">歌词</el-button>
          <el-button type="danger" size="mini" plain @click="remove(scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
  <div class="page-container">
    <el-pagination background 
      :page-sizes="$store.state.pageSizeOpts"
      :layout="$store.state.pageLayout"
      :total="total"
      @size-change="pageSizeChange"
      @current-change="pageChange">
    </el-pagination>
  </div>
  <el-dialog v-model="modifyLyricModal" title="编辑歌词" :width="600" >
    <el-form ref="lyricForm" :model="lyricFormData" :rules="lyricRuleValidate" :label-width="120">
      <el-form-item label="网易云ID" prop="cloud_id">
        <el-input v-model="lyricFormData.cloud_id" />
      </el-form-item>
      <el-form-item label="名称" prop="name">
        <el-input v-model="lyricFormData.name" />
      </el-form-item>
      <el-form-item label="歌词" prop="lyric">
        <el-input v-model="lyricFormData.lyric" type="textarea" :rows="4"/>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="modifyLyricModal = false">取消</el-button>
        <el-button type="primary" @click="saveLyric" :loading="modalLoading">确定</el-button>
      </span>
    </template>
  </el-dialog>
  <el-dialog v-model="uploadModal" title="上传音乐" :width="550" @closed="uploadModalClosed" >
    <el-form :label-width="80">
      <el-form-item label="歌单">
        <el-radio-group v-model="libIdSelected">
          <el-radio v-for="item in musicLibs" :key="item._id" :label="item._id" border size="small">{{item.name}}</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item >
        <el-upload
          ref="musicUpload"
          action="/api/v2/music/upload"
          name="file"
          accept=".mp3,.flac"
          :headers="{token: $store.state.loginInfo.token}"
          :on-success="uploadSuccess"
          :on-error="uploadError" 
          :auto-upload="false"
          multiple
          :data="{libId: libIdSelected}">
          <el-button size="small" type="primary">选择文件</el-button>
        </el-upload>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="uploadModal = false">取消</el-button>
        <el-button type="primary" @click="uploadMusic" >开始上传</el-button>
      </span>
    </template>
  </el-dialog>
  <el-drawer v-model="musicPlaying" :close-on-click-modal="false" size="40%" title="播放音乐">
    <music-player v-if="musicPlaying" :audio="musicList" :lrcType="3" ></music-player>
  </el-drawer>
</div>
</template>

<script lang="ts">
import { Options } from 'vue-class-component'
import BaseList from '../../model/baselist'
import { MsgResult, Page } from '../../model/common.dto'
import { ElButton, ElForm, ElFormItem, ElInput, ElTable, ElTableColumn, ElPagination, ElDialog, ElSelect, ElOption, ElRadioGroup, ElRadio, ElDrawer, ElUpload, ElMessage, ElMessageBox } from 'element-plus'
import { MusicModel, MusicLibModel, MusicLyricModel, MusicPlayerItem } from '../../model/api/music'
import MusicPlayer from './MusicPlayer.vue'
import prettyBytes from 'pretty-bytes'
import { VForm } from '../../types'

let selectedIds: string[] = []
@Options({
  name: 'Music',
  components: { ElButton, ElForm, ElFormItem, ElInput, ElTable, ElTableColumn, ElPagination, ElDialog, ElSelect, ElOption, ElRadioGroup, ElRadio, ElDrawer, ElUpload, MusicPlayer }
})
export default class Music extends BaseList<MusicPage> {
  search = new MusicPage()
  currentRow: MusicModel | null = null
  libIdSelected: string | null = null
  exts: string[] = []
  musicLibs: MusicLibModel[] = []
  musicData: MusicModel[] = []
  uploadModal: boolean = false
  modifyLyricModal: boolean = false
  lyricRuleValidate = {
    cloud_id: [
      { required: true, message: '请输入网易云ID', trigger: 'blur' }
    ],
    name: [
      { required: true, message: '请输入名称', trigger: 'blur' }
    ],
    lyric: [
      { required: true, message: '请输入歌词正文', trigger: 'blur' }
    ],
  }
  prettyBytes = prettyBytes
  lyricFormData: MusicLyricModel = {}
  // 是否正在播放音乐
  musicPlaying: boolean = false
  musicList: MusicPlayerItem[] = []
  created() {
    this.$http.get<never, any>('/api/v1/music/listLibs').then(data => {
      this.musicLibs = data
      this.loadData()
    })
    this.$http.get<never, any>('/api/v1/music/listExts').then(data => {
      this.exts = data
    })
  }
  async loadData() {
    this.loading = true
    const data = await this.$http.get<MusicPage, any>('/api/v1/music/list', {params: this.search})
    selectedIds = []
    this.loading = false
    this.total = data.total
    this.musicData = data.data
  }
  dataSelect(selection: MusicModel[]) {
    selectedIds = selection.map(item => item._id)
  }
  findMusicLib(value: string): string | null {
    const musicLib = this.musicLibs.find(item => item._id === value)
    return musicLib ? musicLib.name : null
  }
  // 根据当前搜索条件播放音乐
  async playMusic() {
    try {
      const data = await this.$http.get<any, any>('/api/v1/music/list/all', {params: selectedIds.length ? {ids: selectedIds} : this.search})
      this.musicList = data.map((item: MusicModel) => {
        const musicItem: MusicPlayerItem = {
          name: item.title || item.name,
          artist: item.artist,
          album: item.album,
          url: `/api/v2/common/music/load/${item._id}`,
          cover: `/api/v2/common/music/album/${item._id}`,
        }
        if(item.lyric_id) {
          musicItem.lrc = `/api/v1/common/music/lyric/${item.lyric_id}`
        }
        return musicItem
      })
      // 删除原本可能存在的播放器配置(包含播放地址 时间进度等信息)
      this.musicPlaying = true
    } catch (err) {
      console.error(err)
      ElMessage.error('获取播放列表失败')
    }
  }
  updateLib(row: MusicModel) {
    this.currentRow = { ...row }
    row.isEditing = true
  }
  remove(row: MusicModel) {
    ElMessageBox.confirm(`是否确认删除 ${row.name} ？`, '确认删除', {type: 'warning'}).then(async () => {
      const data = await this.$http.delete<{params: {id: string}}, any>('/api/v2/music/delete', {params: {id: row._id}})
      if(data.status) {
        ElMessage.success(data.message)
        this.loadData()
      } else {
        ElMessage.warning(data.message)
      }
    }).catch(() => {})
  }
  async updateLyric(row: MusicModel) {
    this.currentRow = { ...row }
    this.modifyLyricModal = true
    if (row.lyric_id) {
      const data = (await this.$http.get<any, any>('/api/v1/music/lyric/get', {params: {lyricId: row.lyric_id}}))
      data.cloud_id = data.cloud_id ? data.cloud_id.toString() : null
      this.lyricFormData = data
    } else {
      this.lyricFormData = {}
    }
  }
  async saveLyric() {
    (this.$refs.lyricForm as VForm).validate(async (valid: boolean) => {
      if (!valid) return
      this.modalLoading = true
      const data = await this.$http.post<MusicLyricModel, any>(`/api/music/lyric/save?musicId=${this.currentRow ? this.currentRow._id : ''}`, this.lyricFormData)
      this.modalLoading = false
      this.modifyLyricModal = false
      ElMessage.success(data.message)
      this.loadData()
      // 清空表单
      this.lyricFormData = {}
    })
  }
  async saveMusicLib(row: MusicModel) {
    if (!this.currentRow) return
    const data = await this.$http.post<{id: string, libId: string}, any>('/api/v2/music/updateLib', {id: this.currentRow._id, libId: this.currentRow.lib_id})
    ElMessage.success(data.message)
    row.lib_id = this.currentRow.lib_id
    row.isEditing = false
  }
  openUploadModal() {
    this.uploadModal = true
    this.libIdSelected = null
  }
  async uploadMusic() {
    if (!this.libIdSelected) {
      ElMessage.warning('请选择歌单')
      return
    }
    // 执行上传
    (this.$refs.musicUpload as typeof ElUpload).submit()
  }
  uploadSuccess(response: MsgResult) {
    if(response.code === 0) {
      ElMessage.success(response.message)
      this.loadData()
      this.uploadModal = false
    } else {
      ElMessage.warning(response.message)
    }
  }
  uploadError(error: Error) {
    ElMessage.error(error.message)
  }
  uploadModalClosed() {
    (this.$refs.musicUpload as typeof ElUpload).clearFiles()
  }
  /**
   * 创建媒体信息
   */
  // musicPlay() {
  //   if(!('mediaSession' in window.navigator)) return;
  //   const currentMusic = this.player.currentMusic
  //   const mediaSession: any = navigator.mediaSession
  //   mediaSession.metadata = new MediaMetadata({
  //     title: currentMusic.name,
  //     artist: currentMusic.artist,
  //     album: currentMusic.album,
  //     artwork: [{src: currentMusic.cover}]
  //   });
  //   mediaSession.setActionHandler('play', () => { // 播放
  //     this.player.play()
  //   })
  //   mediaSession.setActionHandler('pause', () => { // 暂停
  //     this.player.pause()
  //   })
  //   const currentIndex = this.musicList.findIndex(item => item.id === currentMusic.id)
  //   mediaSession.setActionHandler('previoustrack', () => { // 上一首
  //     if (currentIndex === 0) { // 已经是第一首
  //       this.player.switch(this.musicList.length - 1)
  //     } else {
  //       this.player.switch(currentIndex - 1)
  //     }
  //   })
  //   mediaSession.setActionHandler('nexttrack', () => { // 下一首
  //     if (currentIndex === this.musicList.length - 1) { // 已经是最后一首
  //       this.player.switch(0)
  //     } else {
  //       this.player.switch(currentIndex + 1)
  //     }
  //   })
  // }
}


class MusicPage extends Page {
  name?: string
  ext: string[] = []
  title?: string
  album?: string
  artist?: string
  lib_id?: string[] = []
  reset() {
    super.reset()
    this.name = undefined
    this.ext = []
    this.title = undefined
    this.album = undefined
    this.artist = undefined
    this.lib_id = []
  }
}
</script>