<template>
  <div>
    <!-- 查询区域 -->
    <div class="card" style="margin-bottom: 10px">
      <el-input
          style="width: 240px; margin-right: 10px"
          v-model="vocabulary.name"
          placeholder="请输入名称查询"
          prefix-icon="Search"
      />
      <el-button type="primary" @click="fetchWords">查 询</el-button>
      <el-button type="warning" @click="reset">重 置</el-button>
      <el-button type="primary" @click="openTodayPlanDialog">今日背诵计划</el-button>
    </div>

    <!-- 操作按钮区域 -->
    <div class="card" style="margin-bottom: 10px">
      <el-button
          type="primary"
          :disabled="!selectedIds.size"
          @click="addSelectedWordsToPlan"
          style="margin-right: 10px"
      >
        加入背诵计划
      </el-button>
    </div>

    <!-- 表格区域 -->
    <div class="card">
      <el-table
          ref="tableRef"
          :data="tableData"
          :row-key="row => row.id"
          stripe
          border
          style="width: 100%"
          @selection-change="handleSelectionChange"
          :row-class-name="getRowClassName"
      >
        <el-table-column type="selection" width="55" :selectable="isSelectable" />
        // 单词列
        <el-table-column prop="word" label="单词">
          <template #default="{ row }">
            <el-tooltip v-if="todayPlanWordIds.has(row.id)" content="已在今日计划中" placement="top">
              <span>{{ row.word }}</span>
            </el-tooltip>
            <span v-else>{{ row.word }}</span>
          </template>
        </el-table-column>

        <el-table-column prop="definition" label="词义" />
        <el-table-column prop="customContent" label="例句" />
        <el-table-column label="操作" width="100">
          <template #default="{ row }">
            <el-button size="small" @click="playWord(row.word)">🔊 发音</el-button>
          </template>
        </el-table-column>
      </el-table>


      <!-- 分页 -->
      <el-pagination
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          :page-size="pageSize"
          :page-sizes="[10, 20, 30, 50]"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          style="margin-top: 15px; text-align: right"
      />
    </div>

    <!-- 今日背诵计划弹窗 -->
    <el-dialog title="📘 今日背诵计划" v-model="todayPlanDialogVisible" width="60%">
      <div style="margin-bottom: 10px; display: flex; justify-content: space-between;">
        <div>共 {{ todayPlanTotal }} 个单词</div>
      </div>

      <el-table
          :data="todayPlanWords"
          @selection-change="handleTodaySelectionChange"
          stripe
          border
          style="width: 100%"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column prop="wordText" label="单词" />
        <el-table-column prop="meaning" label="词义" />
      </el-table>

      <template #footer>
        <el-button @click="todayPlanDialogVisible = false">关闭</el-button>
        <el-button
            type="success"
            :disabled="!selectedTodayWords.length"
            @click="exportSelectedTodayWords"
        >
          导出选中单词
        </el-button>
        <el-button
            type="danger"
            :disabled="!selectedTodayWords.length"
            @click="deleteSelectedTodayWords"
        >
          删除选中单词
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import axios from 'axios'

// 用户 ID
const userId = localStorage.getItem('userId')

// 表格相关
const vocabulary = reactive({ name: '' })
const tableData = ref([])
const total = ref(0)
const pageSize = ref(10)
const currentPage = ref(1)
const selectedIds = ref(new Set())
const tableRef = ref(null)

// 今日计划相关
const todayPlanDialogVisible = ref(false)
const todayPlanWords = ref([])
const selectedTodayWords = ref([])
const todayPlanTotal = ref(0)
const todayPlanCurrentPage = ref(1)
const todayPlanWordIds = ref(new Set()) // ✅ 新增：保存已加入计划的单词 ID

// 判断某行是否可选中
const isSelectable = (row) => {
  return !todayPlanWordIds.value.has(row.id)
}




// 获取单词数据
const fetchWords = async () => {
  try {
    const params = {
      pageNum: currentPage.value,
      pageSize: pageSize.value,
      keyword: vocabulary.name || undefined
    }
    const res = await axios.get('http://localhost:8080/words', { params })
    tableData.value = res.data.records
    total.value = res.data.total

    await nextTick()
    restoreSelection()
  } catch (err) {
    ElMessage.error('获取单词列表失败')
  }
}

// 多选变化
const handleSelectionChange = (selection) => {
  selection.forEach(item => selectedIds.value.add(item.id))
  tableData.value.forEach(row => {
    if (!selection.find(s => s.id === row.id)) {
      selectedIds.value.delete(row.id)
    }
  })
}

// 恢复勾选状态
const restoreSelection = () => {
  if (!tableRef.value) return
  tableRef.value.clearSelection()
  tableData.value.forEach(row => {
    if (selectedIds.value.has(row.id)) {
      tableRef.value.toggleRowSelection(row, true)
    }
  })
}

// 重置查询
const reset = () => {
  vocabulary.name = ''
  currentPage.value = 1
  fetchWords()
}

// 分页
const handleSizeChange = (val) => {
  pageSize.value = val
  currentPage.value = 1
  fetchWords()
}
const handleCurrentChange = (val) => {
  currentPage.value = val
  fetchWords()
}

// 发音
const playWord = (text) => {
  if (!text) {
    ElMessage.warning('无效的单词发音')
    return
  }
  const utterance = new SpeechSynthesisUtterance(text)
  utterance.lang = 'en-US'
  window.speechSynthesis.speak(utterance)
}

// 加入背诵计划
const addSelectedWordsToPlan = async () => {
  if (!selectedIds.value.size) {
    ElMessage.warning('请先选择单词')
    return
  }
  try {
    const wordIds = Array.from(selectedIds.value)
    await axios.post('http://localhost:8080/today-plan/add', {
      userId,
      wordIds
    })

    ElMessage.success('单词已加入背诵计划')
    if (todayPlanDialogVisible.value) {
      loadTodayPlan(todayPlanCurrentPage.value)
    }

    // 重新加载已加入计划的 ID，刷新禁选状态
    await loadTodayPlan()
    fetchWords()

  } catch (err) {
    if (err.response && err.response.status === 409) {
      const data = err.response.data || {}
      const existingIds = data.existingWordIds || []

      // 你可以根据已有单词ID在tableData中找到对应的单词, 拼接提示内容
      const existingWords = tableData.value
          .filter(item => existingIds.includes(item.id))
          .map(item => item.word)
          .join('，')

      ElMessage.warning(`部分单词已存在长期记忆，请不要重复添加: ${existingWords}`)

      // 仍然刷新接口，保持界面状态
      if (todayPlanDialogVisible.value) {
        await loadTodayPlan(todayPlanCurrentPage.value)
      }
      await loadTodayPlan()
      fetchWords()
    } else {
      ElMessage.error('加入背诵计划失败')
    }
  }
}

// 打开今日计划弹窗
const openTodayPlanDialog = () => {
  todayPlanDialogVisible.value = true
  loadTodayPlan()
}

// 加载今日计划
const loadTodayPlan = async () => {
  try {
    const res = await axios.get('http://localhost:8080/today-plan/todaylist', {
      params: { userId }
    })

    todayPlanWords.value = res.data
    todayPlanTotal.value = res.data.length
    todayPlanWordIds.value = new Set(res.data.map(item => item.wordId || item.id)) // ✅ 更新禁选 ID 集合

  } catch (err) {
    ElMessage.error('加载今日背诵单词失败')
  }
}

// 今日计划选择
const handleTodaySelectionChange = (val) => {
  selectedTodayWords.value = val
}

// 导出选中
const exportSelectedTodayWords = async () => {
  if (!selectedTodayWords.value.length) {
    ElMessage.warning('请先选择单词')
    return
  }
  try {
    const selectedIds = selectedTodayWords.value.map(item => item.id)
    const params = new URLSearchParams()
    params.append('userId', userId)
    selectedIds.forEach(id => params.append('ids', id))

    const res = await axios.get('http://localhost:8080/plan-excel/export-selected', {
      params,
      paramsSerializer: params => params.toString(),
      responseType: 'blob'
    })

    const blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.setAttribute('download', 'today_words.xlsx')
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)

  } catch (err) {
    ElMessage.error('导出失败')
  }
}

// 删除今日单词
const deleteSelectedTodayWords = async () => {
  if (!selectedTodayWords.value.length) {
    ElMessage.warning('请先选择要删除的单词')
    return
  }

  try {
    const confirm = await ElMessageBox.confirm(
        '确定要从今日背诵计划中删除选中的单词吗？',
        '提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
    )

    const idsToDelete = selectedTodayWords.value.map(item => item.id)

    await axios.post('http://localhost:8080/today-plan/delete', {
      userId,
      wordIds: idsToDelete
    })

    ElMessage.success('删除成功')
    loadTodayPlan()

  } catch (err) {
    if (err !== 'cancel') {
      ElMessage.error('删除失败')
    }
  }
}

// 初始化加载
onMounted(async () => {
  await loadTodayPlan()
  fetchWords()
})
</script>


这个是怎么获取指定的用户id，api是怎么用的