<template>
  <div class="table-box">
    <div class="card table-search">
      <el-form ref="elSearchFormRef" :inline="true" size="small" :model="searchForm" class="demo-form-inline" @keyup.enter="onSubmit">
        <el-form-item label="歌曲名称">
          <el-input v-model="searchForm.title" placeholder="歌曲名称" style="width:150px"></el-input>
        </el-form-item>
        <el-form-item label="歌手">
          <el-input v-model="searchForm.artist" placeholder="歌手" style="width:120px"></el-input>
        </el-form-item>
        <el-form-item label="歌单">
          <el-select v-model="searchForm.groupId" placeholder="选择歌单" clearable style="width:150px">
            <el-option v-for="g in groupOptions" :key="g.id" :label="g.name" :value="g.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="searchForm.status" placeholder="状态" clearable style="width:100px">
            <el-option label="启用" :value="1" />
            <el-option label="禁用" :value="0" />
          </el-select>
        </el-form-item>
        <div class="operation">
          <el-button type="primary" icon="search" @click="onSubmit">查询</el-button>
          <el-button icon="refresh" @click="onResetSearch">重置</el-button>
        </div>
      </el-form>
    </div>

    <div class="card table-main">
      <div class="table-header">
        <div class="header-button-lf">
          <el-button type="primary" icon="Plus" @click="openDialog()">新增歌曲</el-button>
        </div>
        <div class="header-button-ri">
          <el-button :icon="Refresh" circle @click="refresh" />
        </div>
      </div>

      <el-table ref="myTable" :data="tableData" border size="small">
        <el-table-column prop="id" label="ID" align="center" width="80" />
        <el-table-column prop="title" label="歌曲名称" align="center" min-width="150" />
        <el-table-column prop="artist" label="歌手" align="center" width="120" />
        <el-table-column label="所属歌单" align="center" width="120">
          <template #default="{ row }">
            {{ getGroupName(row.groupId) }}
          </template>
        </el-table-column>
        <el-table-column label="试听" align="center" width="80">
          <template #default="{ row }">
            <el-button v-if="row.url" type="primary" link size="small" @click="playAudio(row.url)">
              <el-icon><VideoPlay /></el-icon>
            </el-button>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column prop="duration" label="时长(秒)" align="center" width="80" />
        <el-table-column prop="sort" label="排序" align="center" width="70" />
        <el-table-column prop="status" label="状态" align="center" width="80">
          <template #default="{ row }">
            <el-tag :type="row.status === 1 ? 'success' : 'info'">
              {{ row.status === 1 ? '启用' : '禁用' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="createdAt" label="创建时间" align="center" min-width="160">
          <template #default="{ row }">
            <span v-if="row.createdAt">{{ formatUnix(row.createdAt) }}</span>
          </template>
        </el-table-column>
        <el-table-column fixed="right" label="操作" align="center" width="150">
          <template #default="scope">
            <el-button type="primary" link @click="openDialog(scope.row)">编辑</el-button>
            <el-button type="danger" link @click="handleDelete(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <Pagination :pageable="pageable" @handleCurrent="handleCurrent" />
    </div>
  </div>

  <!-- 编辑弹窗 -->
  <el-dialog v-model="dialogVisible" :title="isEdit ? '编辑歌曲' : '新增歌曲'" width="600px" center destroy-on-close>
    <el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px">
      <el-form-item label="所属歌单" prop="groupId">
        <el-select v-model="formData.groupId" placeholder="请选择歌单" style="width: 100%">
          <el-option v-for="g in groupOptions" :key="g.id" :label="g.name" :value="g.id" />
        </el-select>
      </el-form-item>
      <el-form-item label="歌曲名称" prop="title">
        <el-input v-model="formData.title" placeholder="请输入歌曲名称" />
      </el-form-item>
      <el-form-item label="歌手" prop="artist">
        <el-input v-model="formData.artist" placeholder="请输入歌手名称" />
      </el-form-item>
      <el-form-item label="音频文件" prop="url">
        <div class="upload-audio-wrapper">
          <div v-if="formData.url" class="audio-preview">
            <audio :src="audioPreviewUrl || formData.url" controls style="width: 100%"></audio>
            <div class="audio-actions">
              <el-button type="primary" size="small" @click="triggerAudioUpload">重新上传</el-button>
              <el-button type="danger" size="small" @click="clearAudio">删除</el-button>
            </div>
          </div>
          <el-upload
            v-else
            ref="audioUploadRef"
            class="audio-uploader"
            drag
            action="#"
            :auto-upload="false"
            :on-change="handleAudioChange"
            :show-file-list="false"
            accept=".mp3"
          >
            <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
            <div class="el-upload__text">拖拽 MP3 文件到此处 或 <em>点击上传</em></div>
          </el-upload>
          <el-upload
            v-show="false"
            ref="audioReuploadRef"
            action="#"
            :auto-upload="false"
            :on-change="handleAudioChange"
            :show-file-list="false"
            accept=".mp3"
          />
          <div v-if="audioUploading" class="upload-progress">
            <el-progress :percentage="audioUploadProgress" :status="audioUploadProgress === 100 ? 'success' : undefined" />
          </div>
        </div>
      </el-form-item>
      <el-form-item label="排序" prop="sort">
        <el-input-number v-model="formData.sort" :min="0" style="width: 100%" />
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-radio-group v-model="formData.status">
          <el-radio :value="1">启用</el-radio>
          <el-radio :value="0">禁用</el-radio>
        </el-radio-group>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="dialogVisible = false">取消</el-button>
      <el-button type="primary" :loading="submitLoading" @click="handleSubmit">确定</el-button>
    </template>
  </el-dialog>

  <!-- 试听弹窗 -->
  <el-dialog v-model="playerVisible" title="试听" width="400px" center destroy-on-close>
    <audio :src="playerUrl" controls autoplay style="width: 100%"></audio>
  </el-dialog>
</template>

<script setup>
import { ref, reactive, onMounted } from "vue";
import dayjs from "dayjs";
import { Refresh, UploadFilled, VideoPlay } from "@element-plus/icons-vue";
import { ElNotification, ElMessageBox } from "element-plus";
import Pagination from "@/components/Pangination/Pagination.vue";
import { getMusicList, createMusic, updateMusic, deleteMusic, getMusicGroupList } from "@/api/modules/daytask.js";
import { uploadImg } from "@/api/modules/upload.js";

const formatUnix = (ts) => ts ? dayjs.unix(ts).format("YYYY-MM-DD HH:mm:ss") : "";

// 歌单选项
const groupOptions = ref([]);
const loadGroupOptions = async () => {
  const res = await getMusicGroupList({ pageSize: 100 });
  if (res.data) groupOptions.value = res.data.list || [];
};
const getGroupName = (id) => {
  const g = groupOptions.value.find(g => g.id === id);
  return g ? g.name : "-";
};

// 试听
const playerVisible = ref(false);
const playerUrl = ref("");
const playAudio = (url) => {
  playerUrl.value = url;
  playerVisible.value = true;
};

// 搜索
const searchForm = reactive({ title: "", artist: "", groupId: null, status: null });
const tableData = ref([]);
const pageable = reactive({ current: 1, pageSize: 20, total: 0 });

const getList = async () => {
  const params = { current: pageable.current, pageSize: pageable.pageSize, ...searchForm };
  Object.keys(params).forEach(k => { if (params[k] === "" || params[k] === null) delete params[k]; });
  const res = await getMusicList(params);
  if (res.data) {
    tableData.value = res.data.list || [];
    pageable.total = res.data.paging?.total || 0;
  }
};

const onSubmit = () => { pageable.current = 1; getList(); };
const onResetSearch = () => { searchForm.title = ""; searchForm.artist = ""; searchForm.groupId = null; searchForm.status = null; onSubmit(); };
const handleCurrent = (val) => { pageable.current = val; getList(); };
const refresh = () => getList();

// 弹窗
const dialogVisible = ref(false);
const isEdit = ref(false);
const formRef = ref(null);
const submitLoading = ref(false);
const formData = reactive({ id: null, groupId: null, title: "", artist: "", url: "", duration: 0, sort: 0, status: 1 });
const formRules = {
  groupId: [{ required: true, message: "请选择歌单", trigger: "change" }],
  title: [{ required: true, message: "请输入歌曲名称", trigger: "blur" }],
  url: [{ required: true, message: "请上传音频文件", trigger: "change" }],
};

// 音频上传
const audioUploadRef = ref(null);
const audioReuploadRef = ref(null);
const audioPreviewUrl = ref("");
const audioUploading = ref(false);
const audioUploadProgress = ref(0);

const handleAudioChange = async (file) => {
  const rawFile = file.raw;
  audioPreviewUrl.value = URL.createObjectURL(rawFile);

  // 自动获取音频时长
  const audio = new Audio(audioPreviewUrl.value);
  audio.addEventListener("loadedmetadata", () => {
    formData.duration = Math.round(audio.duration);
  });

  // 自动填充歌曲名称（如果为空）
  if (!formData.title) {
    formData.title = rawFile.name.replace(/\.[^/.]+$/, "");
  }

  // 上传
  audioUploading.value = true;
  audioUploadProgress.value = 0;
  try {
    const fd = new FormData();
    fd.append("file", rawFile);
    fd.append("autoSave", "false");

    const progressInterval = setInterval(() => {
      if (audioUploadProgress.value < 90) audioUploadProgress.value += 10;
    }, 100);

    const res = await uploadImg(fd);
    clearInterval(progressInterval);

    if (res.code === 200) {
      audioUploadProgress.value = 100;
      formData.url = res.data.path;
      if (formRef.value) formRef.value.clearValidate("url");
      ElNotification.success("音频上传成功");
    } else {
      ElNotification.error(res.msg || "音频上传失败");
      clearAudio();
    }
  } catch (e) {
    ElNotification.error("音频上传失败");
    clearAudio();
  } finally {
    audioUploading.value = false;
  }
};

const triggerAudioUpload = () => {
  audioReuploadRef.value?.$el.querySelector("input")?.click();
};

const clearAudio = () => {
  formData.url = "";
  formData.duration = 0;
  audioPreviewUrl.value = "";
};

const openDialog = (row) => {
  isEdit.value = !!row;
  audioPreviewUrl.value = "";
  if (row) {
    Object.assign(formData, {
      id: row.id,
      groupId: row.groupId,
      title: row.title,
      artist: row.artist || "",
      url: row.url,
      duration: row.duration || 0,
      sort: row.sort || 0,
      status: row.status,
    });
  } else {
    Object.assign(formData, { id: null, groupId: null, title: "", artist: "", url: "", duration: 0, sort: 0, status: 1 });
  }
  dialogVisible.value = true;
};

const handleSubmit = async () => {
  await formRef.value?.validate();
  submitLoading.value = true;
  try {
    // 后端期望格式: { id, data: { ...fields } }
    const { id, ...fields } = formData;
    if (isEdit.value) {
      await updateMusic({ id, data: fields });
    } else {
      await createMusic({ data: fields });
    }
    ElNotification.success({ title: "成功", message: isEdit.value ? "编辑成功" : "新增成功" });
    dialogVisible.value = false;
    getList();
  } catch (e) {
    ElNotification.error({ title: "错误", message: e.message || "操作失败" });
  } finally {
    submitLoading.value = false;
  }
};

const handleDelete = (row) => {
  ElMessageBox.confirm("确定删除该歌曲吗？", "提示", { type: "warning" }).then(async () => {
    await deleteMusic({ id: row.id });
    ElNotification.success({ title: "成功", message: "删除成功" });
    getList();
  }).catch(() => {});
};

onMounted(() => { loadGroupOptions(); getList(); });
</script>

<style scoped>
.upload-audio-wrapper {
  width: 100%;
}

.audio-uploader {
  width: 100%;
}

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

.audio-uploader :deep(.el-upload-dragger) {
  width: 100%;
  height: auto;
  min-height: 120px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 15px;
}

.audio-preview {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
}

.audio-actions {
  display: flex;
  gap: 10px;
}

.upload-progress {
  margin-top: 10px;
  width: 100%;
}
</style>
