<template>
  <div class="vnc-command-manage">
    <div class="toolbar">
      <el-button type="primary" :icon="Plus" @click="openCreateGroup">新建分组</el-button>
      <el-button :icon="Refresh" @click="loadList">刷新</el-button>
    </div>

    <div v-loading="loading" class="group-list">
      <el-empty v-if="!groups.length && !loading" description="暂无指令分组" />

      <el-card v-for="group in groups" :key="group.id" shadow="never" class="group-card">
        <!-- 分组头部 -->
        <div class="group-header">
          <div class="group-title">
            <div v-if="group.icon" class="group-icon-img">
              <img :src="group.icon" :alt="group.name" />
            </div>
            <span v-else class="group-icon">{{ group.defaultIcon }}</span>
            <span class="group-name">{{ group.name }}</span>
            <el-tag size="small" type="info" style="margin-left:8px">{{ (group.items || []).length }} 条指令</el-tag>
          </div>
          <div class="group-actions">
            <el-button link type="primary" size="small" @click="openCreateItem(group)">添加指令</el-button>
            <el-button link type="primary" size="small" @click="openEditGroup(group)">编辑</el-button>
            <el-button link type="danger" size="small" @click="handleDeleteGroup(group)">删除</el-button>
          </div>
        </div>

        <!-- 指令列表 -->
        <el-table v-if="group.items && group.items.length" :data="group.items" size="small" stripe style="margin-top:8px">
          <el-table-column prop="label" label="指令名称" min-width="140" />
          <el-table-column prop="cmd" label="指令内容" min-width="220" show-overflow-tooltip>
            <template #default="{ row }">
              <code class="cmd-text">{{ row.cmd }}</code>
            </template>
          </el-table-column>
          <el-table-column label="变量" width="80" align="center">
            <template #default="{ row }">
              <el-tag v-if="parseVars(row.vars).length" size="small" type="warning">{{ parseVars(row.vars).length }} 个</el-tag>
              <span v-else style="color:#c0c4cc">-</span>
            </template>
          </el-table-column>
          <el-table-column prop="sort" label="排序" width="70" align="center" />
          <el-table-column label="操作" width="120" fixed="right">
            <template #default="{ row }">
              <el-button link type="primary" size="small" @click="openEditItem(row, group)">编辑</el-button>
              <el-button link type="danger" size="small" @click="handleDeleteItem(row)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
        <el-empty v-else :image-size="40" description="暂无指令" style="padding:12px 0" />
      </el-card>
    </div>

    <!-- 新建/编辑分组弹窗 -->
    <el-dialog v-model="groupDialogVisible" :title="groupForm.id ? '编辑分组' : '新建分组'" width="440px" destroy-on-close>
      <el-form :model="groupForm" label-width="90px">
        <el-form-item label="分组名称" required>
          <el-input v-model="groupForm.name" placeholder="请输入分组名称" />
        </el-form-item>
        <el-form-item label="文本图标">
          <el-input v-model="groupForm.defaultIcon" placeholder="如 📚，无文件图标时显示" />
        </el-form-item>
        <el-form-item label="图标文件">
          <div class="icon-file-row">
            <div v-if="groupForm._iconUrl" class="icon-preview">
              <img :src="groupForm._iconUrl" alt="图标预览" />
            </div>
            <el-button size="small" @click="showIconSelector = true">
              {{ groupForm.iconFileId ? '更换图标' : '选择图标文件' }}
            </el-button>
            <el-button v-if="groupForm.iconFileId" size="small" type="danger" plain
              @click="groupForm.iconFileId = ''; groupForm._iconUrl = ''">清除</el-button>
            <span v-if="groupForm._iconName" style="font-size:12px;color:#909399;margin-left:6px">{{ groupForm._iconName }}</span>
          </div>
        </el-form-item>
        <el-form-item label="排序">
          <el-input-number v-model="groupForm.sort" :min="0" controls-position="right" style="width:100%" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="groupDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="submitLoading" @click="submitGroup">确定</el-button>
      </template>
    </el-dialog>

    <!-- 图标文件选择器 -->
    <ImageSelector v-model="showIconSelector" @confirm="onIconSelected" />

    <!-- 新建/编辑指令项弹窗 -->
    <el-dialog v-model="itemDialogVisible" :title="itemForm.id ? '编辑指令' : '添加指令'" width="560px" destroy-on-close>
      <el-form :model="itemForm" label-width="90px">
        <el-form-item label="指令名称" required>
          <el-input v-model="itemForm.label" placeholder="如：重启 Nginx" />
        </el-form-item>
        <el-form-item label="指令内容" required>
          <el-input v-model="itemForm.cmd" type="textarea" :rows="3"
            placeholder="支持 %var% 变量占位符，如：cd %path% && ls" />
        </el-form-item>
        <el-form-item label="排序">
          <el-input-number v-model="itemForm.sort" :min="0" controls-position="right" style="width:100%" />
        </el-form-item>
        <!-- 变量配置 -->
        <el-form-item label="变量列表">
          <div class="vars-editor">
            <div v-for="(v, i) in varsList" :key="i" class="var-row">
              <el-input v-model="v.k" placeholder="变量名(如 path)" style="width:140px" />
              <el-input v-model="v.p" placeholder="提示文字(如 目录路径)" style="flex:1;margin:0 8px" />
              <el-button :icon="Delete" circle size="small" type="danger" plain @click="varsList.splice(i, 1)" />
            </div>
            <el-button size="small" :icon="Plus" @click="varsList.push({ k: '', p: '' })" style="margin-top:6px">添加变量</el-button>
            <div style="font-size:12px;color:#909399;margin-top:4px">变量在指令中以 %变量名% 形式使用</div>
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="itemDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="submitLoading" @click="submitItem">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, Refresh, Delete } from '@element-plus/icons-vue'
import ImageSelector from '@/components/admin/ImageSelector.vue'
import {
  getVncCommandGroupList, createVncCommandGroup, updateVncCommandGroup, deleteVncCommandGroup,
  createVncCommandItem, updateVncCommandItem, deleteVncCommandItem
} from '@/api/admin/vncCommand'
import { extractApiError } from '@/utils/kvmErrorUtil'

const loading = ref(false)
const submitLoading = ref(false)
const groups = ref([])

const loadList = async () => {
  loading.value = true
  try {
    const res = await getVncCommandGroupList()
    if (res?.data?.code === 200) {
      const d = res.data.data
      groups.value = Array.isArray(d) ? d : (d?.data || d?.list || [])
    } else { groups.value = [] }
  } catch { groups.value = [] } finally { loading.value = false }
}

const parseVars = (vars) => {
  if (!vars) return []
  try { const v = typeof vars === 'string' ? JSON.parse(vars) : vars; return Array.isArray(v) ? v : [] } catch { return [] }
}

// ---- 分组 ----
const groupDialogVisible = ref(false)
const showIconSelector = ref(false)
const groupForm = reactive({ id: 0, name: '', defaultIcon: '', iconFileId: '', sort: 0 })

const openCreateGroup = () => {
  Object.assign(groupForm, { id: 0, name: '', defaultIcon: '', iconFileId: '', sort: 0 })
  groupDialogVisible.value = true
}
const openEditGroup = (g) => {
  Object.assign(groupForm, { 
    id: g.id, 
    name: g.name, 
    defaultIcon: g.defaultIcon || '', 
    iconFileId: g.iconFileId || '',
    sort: g.sort || 0 
  })
  // 设置预览数据
  if (g.icon) {
    groupForm._iconUrl = g.icon
  }
  groupDialogVisible.value = true
}
const submitGroup = async () => {
  if (!groupForm.name) { ElMessage.warning('请填写分组名称'); return }
  submitLoading.value = true
  try {
    const res = groupForm.id
      ? await updateVncCommandGroup({ id: groupForm.id, name: groupForm.name, defaultIcon: groupForm.defaultIcon, icon_file_id: groupForm.iconFileId, sort: groupForm.sort })
      : await createVncCommandGroup({ name: groupForm.name, defaultIcon: groupForm.defaultIcon, icon_file_id: groupForm.iconFileId, sort: groupForm.sort })
    if (res?.data?.code === 200) { ElMessage.success(groupForm.id ? '修改成功' : '创建成功'); groupDialogVisible.value = false; loadList() }
    else ElMessage.error(extractApiError(res?.data, '操作失败'))
  } catch (e) { ElMessage.error(extractApiError(e?.response?.data, '操作失败')) } finally { submitLoading.value = false }
}
const handleDeleteGroup = (g) => {
  ElMessageBox.confirm(`确定删除分组「${g.name}」？将同时删除该分组下所有指令！`, '删除确认', { type: 'error' })
    .then(async () => {
      try {
        const res = await deleteVncCommandGroup({ id: g.id })
        if (res?.data?.code === 200) { ElMessage.success('删除成功'); loadList() }
        else ElMessage.error(extractApiError(res?.data, '删除失败'))
      } catch (e) { ElMessage.error(extractApiError(e?.response?.data, '删除失败')) }
    }).catch(() => {})
}

// ---- 指令项 ----
const itemDialogVisible = ref(false)
const itemForm = reactive({ id: 0, group_id: 0, label: '', cmd: '', sort: 0 })
const varsList = ref([])

const openCreateItem = (group) => {
  Object.assign(itemForm, { id: 0, group_id: group.id, label: '', cmd: '', sort: 0 })
  varsList.value = []
  itemDialogVisible.value = true
}
const openEditItem = (item, group) => {
  Object.assign(itemForm, { id: item.id, group_id: group.id, label: item.label, cmd: item.cmd, sort: item.sort || 0 })
  varsList.value = parseVars(item.vars).map(v => ({ k: v.k, p: v.p }))
  itemDialogVisible.value = true
}
const submitItem = async () => {
  if (!itemForm.label) { ElMessage.warning('请填写指令名称'); return }
  if (!itemForm.cmd) { ElMessage.warning('请填写指令内容'); return }
  submitLoading.value = true
  try {
    const validVars = varsList.value.filter(v => v.k)
    const varsJson = validVars.length ? JSON.stringify(validVars) : ''
    const res = itemForm.id
      ? await updateVncCommandItem({ id: itemForm.id, label: itemForm.label, cmd: itemForm.cmd, sort: itemForm.sort, vars: varsJson })
      : await createVncCommandItem({ group_id: itemForm.group_id, label: itemForm.label, cmd: itemForm.cmd, sort: itemForm.sort, vars: varsJson })
    if (res?.data?.code === 200) { ElMessage.success(itemForm.id ? '修改成功' : '创建成功'); itemDialogVisible.value = false; loadList() }
    else ElMessage.error(extractApiError(res?.data, '操作失败'))
  } catch (e) { ElMessage.error(extractApiError(e?.response?.data, '操作失败')) } finally { submitLoading.value = false }
}
const handleDeleteItem = (item) => {
  ElMessageBox.confirm(`确定删除指令「${item.label}」？`, '删除确认', { type: 'warning' })
    .then(async () => {
      try {
        const res = await deleteVncCommandItem({ id: item.id })
        if (res?.data?.code === 200) { ElMessage.success('删除成功'); loadList() }
        else ElMessage.error(extractApiError(res?.data, '删除失败'))
      } catch (e) { ElMessage.error(extractApiError(e?.response?.data, '删除失败')) }
    }).catch(() => {})
}

// 图标选择处理
const onIconSelected = (selectedFile) => {
  if (selectedFile && selectedFile.id) {
    groupForm.iconFileId = selectedFile.id
    // 添加预览URL和文件名用于显示
    groupForm._iconUrl = selectedFile.url
    groupForm._iconName = selectedFile.realName
  }
  showIconSelector.value = false
}

loadList()
</script>

<style scoped>
.vnc-command-manage { padding: 20px; }
.toolbar { display: flex; gap: 8px; margin-bottom: 16px; }
.group-list { display: flex; flex-direction: column; gap: 16px; }
.group-card { border-radius: 8px; }
.group-header { display: flex; justify-content: space-between; align-items: center; }
.group-title { display: flex; align-items: center; gap: 6px; }
.group-icon { font-size: 18px; }
.group-icon-img { width: 24px; height: 24px; border-radius: 4px; overflow: hidden; display: flex; align-items: center; justify-content: center; }
.group-icon-img img { width: 100%; height: 100%; object-fit: cover; }
.group-name { font-size: 15px; font-weight: 600; color: #303133; }
.group-actions { display: flex; gap: 4px; }
.cmd-text { font-family: monospace; font-size: 12px; color: #409eff; background: #f0f7ff; padding: 2px 6px; border-radius: 4px; }
.vars-editor { width: 100%; }
.var-row { display: flex; align-items: center; margin-bottom: 8px; }
.icon-file-row { display: flex; align-items: center; gap: 8px; }
.icon-preview { width: 32px; height: 32px; border-radius: 4px; overflow: hidden; border: 1px solid #dcdfe6; }
.icon-preview img { width: 100%; height: 100%; object-fit: cover; }
</style>
