<script setup>
import { Delete, Edit, Plus, Search } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { onMounted, reactive, ref, watch } from 'vue'
import { deletePackage, getPackages, updatePackage } from '@/api/packageManagement'
import { getPkgCategoryTree } from '@/api/packageManagement'

const props = defineProps({
  categoryId: {
    type: [String, Number],
    default: 'all',
  },
  refreshKey: {
    type: Number,
    default: 0,
  },
  style: {
    type: Object,
    default: () => ({}),
  },
})

const emit = defineEmits(['view', 'add'])

const loading = ref(false)
const packageList = ref([])
const searchName = ref('')
const currentPackage = ref(null)

const loadPackages = async () => {
  loading.value = true
  try {
    const data = await getPackages({
      category_id:
        props.categoryId && String(props.categoryId) !== 'all' ? String(props.categoryId) : '',
      name: searchName.value.trim(),
    })
    packageList.value = data
  } finally {
    loading.value = false
  }
}

const handleSearch = () => loadPackages()

const handleReset = () => {
  searchName.value = ''
  loadPackages()
}

const handleView = (row) => {
  currentPackage.value = row
  emit('view', row)
}

// ── edit ──────────────────────────────────────────────────────────────────
const editVisible = ref(false)
const editLoading = ref(false)
const editForm = reactive({ id: null, name: '', category_id: null, remark: '' })
const categoryOptions = ref([])

const loadCategoryOptions = async () => {
  if (categoryOptions.value.length) return
  try {
    const tree = await getPkgCategoryTree()
    const flatten = (nodes, result = []) => {
      for (const n of nodes) {
        result.push({ value: n.id, label: n.name })
        if (n.children?.length) flatten(n.children, result)
      }
      return result
    }
    categoryOptions.value = flatten(tree)
  } catch {}
}

const handleEdit = async (row) => {
  await loadCategoryOptions()
  editForm.id = row.id
  editForm.name = row.name
  editForm.category_id = row.category_id ?? null
  editForm.remark = row.remark ?? ''
  editVisible.value = true
}

const submitEdit = async () => {
  if (!editForm.name.trim()) {
    ElMessage.warning('请输入数据包名称')
    return
  }
  editLoading.value = true
  try {
    const updated = await updatePackage(editForm.id, {
      name: editForm.name.trim(),
      category_id: editForm.category_id || null,
      remark: editForm.remark.trim() || null,
    })
    ElMessage.success('修改成功')
    editVisible.value = false
    // 更新列表中对应行
    const idx = packageList.value.findIndex(p => p.id === editForm.id)
    if (idx !== -1) Object.assign(packageList.value[idx], updated)
    if (currentPackage.value?.id === editForm.id) Object.assign(currentPackage.value, updated)
  } catch (e) {
    ElMessage.error(e?.response?.data?.detail || '修改失败')
  } finally {
    editLoading.value = false
  }
}

const handleDelete = async (row) => {
  try {
    await ElMessageBox.confirm(`确定删除数据包"${row.name}"吗？`, '提示', { type: 'warning' })
    await deletePackage(row.id)
    ElMessage.success('数据包已删除')
    if (currentPackage.value?.id === row.id) {
      currentPackage.value = null
    }
    await loadPackages()
  } catch {
    // user cancelled
  }
}

watch(() => props.categoryId, loadPackages)
watch(() => props.refreshKey, () => {
  currentPackage.value = null
  loadPackages()
})

onMounted(loadPackages)
</script>

<template>
  <el-card class="pane-card" shadow="hover" :style="props.style">
    <template #header>
      <div class="pane-header">
        <span>数据包列表</span>
        <el-button type="primary" :icon="Plus" size="small" @click="emit('add')">新增数据包</el-button>
      </div>
    </template>

    <div class="search-bar">
      <el-input
        v-model="searchName"
        placeholder="数据包名称"
        clearable
        :prefix-icon="Search"
        @keyup.enter="handleSearch"
        @clear="handleReset"
      />
      <el-button type="primary" @click="handleSearch">搜索</el-button>
      <el-button @click="handleReset">重置</el-button>
    </div>

    <el-table
      :data="packageList"
      v-loading="loading"
      border
      stripe
      highlight-current-row
      height="calc(100vh - 265px)"
      :row-class-name="({ row }) => (currentPackage?.id === row.id ? 'current-row' : '')"
      style="cursor: pointer"
      @row-click="handleView"
    >
      <el-table-column prop="name" label="数据包名称" min-width="100" show-overflow-tooltip />
      <el-table-column prop="created_at" label="创建时间" min-width="100" />
      <el-table-column prop="data_count" label="数据量" width="80" align="center" />
      <el-table-column label="操作" width="150" fixed="right" align="center">
        <template #default="{ row }">
          <div>
            <el-button link type="primary" :icon="Edit" @click.stop="handleEdit(row)" />
            <el-button link type="danger" :icon="Delete" @click.stop="handleDelete(row)" />
          </div>
        </template>
      </el-table-column>
    </el-table>
  </el-card>

  <!-- 编辑数据包 -->
  <el-dialog v-model="editVisible" title="编辑数据包" width="480px" :close-on-click-modal="false">
    <el-form label-width="90px">
      <el-form-item label="名称" required>
        <el-input v-model="editForm.name" placeholder="数据包名称" clearable />
      </el-form-item>
      <el-form-item label="分类">
        <el-select v-model="editForm.category_id" placeholder="选择分类（可选）" clearable style="width:100%">
          <el-option
            v-for="opt in categoryOptions"
            :key="opt.value"
            :label="opt.label"
            :value="opt.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="备注">
        <el-input v-model="editForm.remark" type="textarea" :rows="3" placeholder="备注（可选）" />
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="editVisible = false">取消</el-button>
      <el-button type="primary" :loading="editLoading" @click="submitEdit">保存</el-button>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.pane-card {
  height: 100%;
  overflow: hidden;
  border-radius: 0;
  border: none;
  border-right: 1px solid var(--border-color);
  box-shadow: none !important;
  display: flex;
  flex-direction: column;
  background: var(--bg-white);

  :deep(.el-card__header) {
    padding: 0 16px;
    height: 44px;
    display: flex;
    align-items: center;
    border-bottom: 1px solid var(--border-color);
    background: #F7F8FA;
  }

  :deep(.el-card__body) {
    flex: 1;
    overflow: hidden;
    padding: 12px 16px;
  }
}

.pane-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
}

.search-bar {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;

  .el-input {
    flex: 1;
  }
}

:deep(.el-table .current-row > td) {
  background: var(--primary-light) !important;
}

:deep(.el-table .el-button.is-link) {
  font-size: 13px;
  padding: 0 4px;
  height: auto;
  line-height: 1;
}
</style>
