<template>
  <div class="dictionary-management">
    <div class="page-header">
      <h2>字典管理</h2>
      <p>管理系统字典类型和字典项</p>
    </div>

    <!-- 主容器：树 + 列表 -->
    <div class="content-container">
      <!-- 左侧：字典类型树 -->
      <div class="tree-panel">
        <div class="tree-header">
          <h3>字典类型</h3>
          <div class="tree-actions">
            <el-button type="primary" size="small" @click="openCreateCategoryDialog">
              <el-icon><Plus /></el-icon>
              新增
            </el-button>
            <el-button 
              type="warning" 
              size="small" 
              @click="openEditCategoryDialog" 
              :disabled="!selectedCategory"
            >
              <el-icon><Edit /></el-icon>
              修改
            </el-button>
            <el-button 
              type="danger" 
              size="small" 
              @click="deleteCategoryConfirm" 
              :disabled="!selectedCategory"
            >
              <el-icon><Delete /></el-icon>
              删除
            </el-button>
          </div>
        </div>
        <el-tree
          ref="treeRef"
          :data="categoryTree"
          node-key="category_id"
          :props="{ children: 'children', label: 'category_name' }"
          default-expand-all
          highlight-current
          @node-click="handleTreeNodeClick"
          v-loading="treeLoading"
        />
      </div>

      <!-- 右侧：字典项列表 -->
      <div class="list-panel">
        <div class="list-header">
          <div v-if="selectedCategory">
            <h3>{{ selectedCategory.category_name }} 中的字典项</h3>
          </div>
          <div v-else>
            <h3>请在左侧选择字典类型</h3>
          </div>
          <div class="list-actions" v-if="selectedCategory">
            <el-input
              v-model="searchKeyword"
              placeholder="搜索字典项"
              style="width: 200px; margin-right: 10px"
              clearable
              @clear="loadItems"
            >
              <template #prefix>
                <el-icon><Search /></el-icon>
              </template>
            </el-input>
            <el-select
              v-model="searchEnableFlag"
              placeholder="状态"
              style="width: 120px; margin-right: 10px"
              clearable
              @change="loadItems"
            >
              <el-option label="全部" value="" />
              <el-option label="启用" value="1" />
              <el-option label="禁用" value="0" />
            </el-select>
            <el-button type="primary" @click="loadItems">
              <el-icon><Search /></el-icon>
              查询
            </el-button>
            <el-button type="primary" @click="openCreateItemDialog">
              <el-icon><Plus /></el-icon>
              新增
            </el-button>
            <el-button 
              type="danger" 
              @click="batchDeleteItems"
              :disabled="selectedItems.length === 0"
            >
              <el-icon><Delete /></el-icon>
              批量删除
            </el-button>
          </div>
        </div>

        <!-- 字典项列表 -->
        <el-table
          v-if="selectedCategory"
          v-loading="loading"
          :data="items"
          style="width: 100%"
          @selection-change="handleSelectionChange"
        >
          <el-table-column type="selection" width="55" />
          <el-table-column prop="dict_name" label="字典名称" min-width="150" show-overflow-tooltip />
          <el-table-column prop="dict_value" label="字典值" width="120" show-overflow-tooltip />
          <el-table-column prop="dict_desc" label="字典备注" min-width="150" show-overflow-tooltip>
            <template #default="{ row }">
              <el-tooltip v-if="row.dict_desc && row.dict_desc.length > 100" :content="row.dict_desc" placement="top">
                <span>{{ row.dict_desc.substring(0, 100) }}...</span>
              </el-tooltip>
              <span v-else>{{ row.dict_desc }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="sort" label="排序" width="80" align="center" />
          <el-table-column prop="enable_flag" label="状态" width="100" align="center">
            <template #default="{ row }">
              <el-switch
                v-model="row.enable_flag"
                active-value="1"
                inactive-value="0"
                @change="handleStatusChange(row)"
              />
            </template>
          </el-table-column>
          <el-table-column prop="created_by_name" label="创建人" width="100" />
          <el-table-column prop="created_time" label="创建时间" width="160">
            <template #default="{ row }">
              {{ formatDate(row.created_time) }}
            </template>
          </el-table-column>
          <el-table-column prop="updated_by_name" label="修改人" width="100" />
          <el-table-column prop="updated_time" label="修改时间" width="160">
            <template #default="{ row }">
              {{ formatDate(row.updated_time) }}
            </template>
          </el-table-column>
          <el-table-column label="操作" width="150" fixed="right">
            <template #default="{ row }">
              <el-button type="warning" size="small" @click="editItem(row)">
                修改
              </el-button>
              <el-button type="danger" size="small" @click="deleteItem(row)">
                删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>

        <div v-else class="empty-state">
          <el-empty description="请在左侧选择一个字典类型" />
        </div>

        <!-- 分页 -->
        <div v-if="selectedCategory" class="pagination">
          <el-pagination
            v-model:current-page="currentPage"
            v-model:page-size="pageSize"
            :page-sizes="[10, 20, 50, 100]"
            :total="total"
            layout="total, sizes, prev, pager, next, jumper"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </div>
      </div>
    </div>

    <!-- 创建/编辑字典类型对话框 -->
    <el-dialog
      v-model="showCategoryDialog"
      :title="editingCategory ? '编辑字典类型' : '创建字典类型'"
      width="600px"
      @close="resetCategoryForm"
    >
      <el-form
        ref="categoryFormRef"
        :model="categoryForm"
        :rules="categoryRules"
        label-width="120px"
      >
        <el-form-item label="字典类型ID" prop="category_id" v-if="editingCategory">
          <el-input v-model="categoryForm.category_id" disabled />
        </el-form-item>
        <el-form-item label="字典类型编号" prop="category_no">
          <el-input v-model="categoryForm.category_no" placeholder="请输入字典类型编号" maxlength="512" />
        </el-form-item>
        <el-form-item label="字典类型名称" prop="category_name">
          <el-input v-model="categoryForm.category_name" placeholder="请输入字典类型名称" maxlength="512" />
        </el-form-item>
        <el-form-item label="字典类型备注" prop="category_desc">
          <el-input 
            v-model="categoryForm.category_desc" 
            type="textarea" 
            :rows="3"
            placeholder="请输入字典类型备注" 
            maxlength="512"
            show-word-limit
          />
        </el-form-item>
        <el-form-item label="父节点" prop="parent_field">
          <el-tree-select
            v-model="categoryForm.parent_field"
            :data="categoryTreeForSelect"
            node-key="category_id"
            :props="{ children: 'children', label: 'category_name' }"
            placeholder="请选择父节点（默认为根节点）"
            check-strictly
            clearable
          />
        </el-form-item>
        <el-form-item label="字典层级" prop="category_level">
          <el-input v-model="categoryForm.category_level" placeholder="请输入字典层级" maxlength="1" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showCategoryDialog = false">取消</el-button>
        <el-button type="primary" @click="submitCategoryForm" :loading="submitting">
          确定
        </el-button>
      </template>
    </el-dialog>

    <!-- 创建/编辑字典项对话框 -->
    <el-dialog
      v-model="showItemDialog"
      :title="editingItem ? '编辑字典项' : '创建字典项'"
      width="600px"
      @close="resetItemForm"
    >
      <el-form
        ref="itemFormRef"
        :model="itemForm"
        :rules="itemRules"
        label-width="120px"
      >
        <el-form-item label="字典名称" prop="dict_name">
          <el-input v-model="itemForm.dict_name" placeholder="请输入字典名称" maxlength="512" />
        </el-form-item>
        <el-form-item label="字典值" prop="dict_value">
          <el-input v-model="itemForm.dict_value" placeholder="请输入字典值" maxlength="512" />
        </el-form-item>
        <el-form-item label="字典备注" prop="dict_desc">
          <el-input 
            v-model="itemForm.dict_desc" 
            type="textarea" 
            :rows="3"
            placeholder="请输入字典备注" 
            maxlength="512"
            show-word-limit
          />
        </el-form-item>
        <el-form-item label="字典类型" prop="category_id">
          <el-tree-select
            v-model="itemForm.category_id"
            :data="categoryTree"
            node-key="category_id"
            :props="{ children: 'children', label: 'category_name' }"
            placeholder="请选择字典类型"
            check-strictly
          />
        </el-form-item>
        <el-form-item label="排序" prop="sort">
          <el-input-number v-model="itemForm.sort" :min="0" controls-position="right" />
        </el-form-item>
        <el-form-item label="启用状态" prop="enable_flag">
          <el-radio-group v-model="itemForm.enable_flag">
            <el-radio label="1">启用</el-radio>
            <el-radio label="0">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showItemDialog = false">取消</el-button>
        <el-button type="primary" @click="submitItemForm" :loading="submitting">
          确定
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus'
import { Plus, Edit, Delete, Search } from '@element-plus/icons-vue'
import { dictApi, type DictCategory, type DictItem, type DictCategoryForm, type DictItemForm } from '@/api/dict'

// 树相关
const treeRef = ref()
const treeLoading = ref(false)
const categoryTree = ref<DictCategory[]>([])
const selectedCategory = ref<DictCategory | null>(null)

// 列表相关
const loading = ref(false)
const items = ref<DictItem[]>([])
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)
const selectedItems = ref<DictItem[]>([])

// 搜索相关
const searchKeyword = ref('')
const searchEnableFlag = ref('')

// 字典类型对话框
const showCategoryDialog = ref(false)
const editingCategory = ref(false)
const categoryFormRef = ref<FormInstance>()
const categoryForm = reactive<DictCategoryForm & { category_id?: string }>({
  category_id: '',
  category_no: '',
  category_name: '',
  category_desc: '',
  parent_field: '0',
  category_level: ''
})

const categoryRules: FormRules = {
  category_name: [
    { required: true, message: '请输入字典类型名称', trigger: 'blur' },
    { max: 512, message: '字典类型名称不能超过512个字符', trigger: 'blur' }
  ],
  category_no: [
    { max: 512, message: '字典类型编号不能超过512个字符', trigger: 'blur' }
  ],
  category_desc: [
    { max: 512, message: '字典类型备注不能超过512个字符', trigger: 'blur' }
  ]
}

// 字典项对话框
const showItemDialog = ref(false)
const editingItem = ref(false)
const itemFormRef = ref<FormInstance>()
const itemForm = reactive<DictItemForm & { dict_id?: number }>({
  dict_id: undefined,
  dict_name: '',
  dict_value: '',
  dict_desc: '',
  category_id: '',
  enable_flag: '1',
  sort: 0
})

const itemRules: FormRules = {
  dict_name: [
    { required: true, message: '请输入字典名称', trigger: 'blur' },
    { max: 512, message: '字典名称不能超过512个字符', trigger: 'blur' }
  ],
  dict_value: [
    { required: true, message: '请输入字典值', trigger: 'blur' },
    { max: 512, message: '字典值不能超过512个字符', trigger: 'blur' }
  ],
  dict_desc: [
    { max: 512, message: '字典备注不能超过512个字符', trigger: 'blur' }
  ],
  category_id: [
    { required: true, message: '请选择字典类型', trigger: 'change' }
  ]
}

const submitting = ref(false)

// 计算属性：用于选择父节点的树（排除当前编辑的节点）
const categoryTreeForSelect = computed(() => {
  if (!editingCategory.value) {
    return [{ category_id: '0', category_name: '根节点', children: categoryTree.value }]
  }
  // 编辑时需要排除自己和子节点
  const filterNode = (nodes: DictCategory[], excludeId: string): DictCategory[] => {
    return nodes.filter(node => node.category_id !== excludeId).map(node => ({
      ...node,
      children: node.children ? filterNode(node.children, excludeId) : []
    }))
  }
  return [{ 
    category_id: '0', 
    category_name: '根节点', 
    children: filterNode(categoryTree.value, categoryForm.category_id || '')
  }]
})

// 加载字典类型树
const loadCategoryTree = async () => {
  treeLoading.value = true
  try {
    const res = await dictApi.getCategoryTree()
    if (res.code === '000000') {
      categoryTree.value = res.data || []
    } else {
      ElMessage.error(res.message || '加载字典类型树失败')
    }
  } catch (error: any) {
    console.error('加载字典类型树失败:', error)
    ElMessage.error('加载字典类型树失败')
  } finally {
    treeLoading.value = false
  }
}

// 树节点点击
const handleTreeNodeClick = (data: DictCategory) => {
  selectedCategory.value = data
  currentPage.value = 1
  searchKeyword.value = ''
  searchEnableFlag.value = ''
  loadItems()
}

// 加载字典项列表
const loadItems = async () => {
  if (!selectedCategory.value) return
  
  loading.value = true
  try {
    const res = await dictApi.getItemList({
      category_id: selectedCategory.value.category_id,
      keyword: searchKeyword.value || undefined,
      enable_flag: searchEnableFlag.value || undefined,
      page: currentPage.value,
      page_size: pageSize.value
    })
    if (res.code === '000000') {
      items.value = res.data.list || []
      total.value = res.data.total || 0
    } else {
      ElMessage.error(res.message || '加载字典项列表失败')
    }
  } catch (error: any) {
    console.error('加载字典项列表失败:', error)
    ElMessage.error('加载字典项列表失败')
  } finally {
    loading.value = false
  }
}

// 分页相关
const handleSizeChange = (val: number) => {
  pageSize.value = val
  currentPage.value = 1
  loadItems()
}

const handleCurrentChange = (val: number) => {
  currentPage.value = val
  loadItems()
}

// 选择变化
const handleSelectionChange = (val: DictItem[]) => {
  selectedItems.value = val
}

// ==================== 字典类型操作 ====================

// 打开创建字典类型对话框
const openCreateCategoryDialog = () => {
  editingCategory.value = false
  resetCategoryForm()
  showCategoryDialog.value = true
}

// 打开编辑字典类型对话框
const openEditCategoryDialog = () => {
  if (!selectedCategory.value) return
  
  editingCategory.value = true
  Object.assign(categoryForm, {
    category_id: selectedCategory.value.category_id,
    category_no: selectedCategory.value.category_no || '',
    category_name: selectedCategory.value.category_name,
    category_desc: selectedCategory.value.category_desc || '',
    parent_field: selectedCategory.value.parent_field || '0',
    category_level: selectedCategory.value.category_level || ''
  })
  showCategoryDialog.value = true
}

// 重置字典类型表单
const resetCategoryForm = () => {
  categoryFormRef.value?.resetFields()
  Object.assign(categoryForm, {
    category_id: '',
    category_no: '',
    category_name: '',
    category_desc: '',
    parent_field: '0',
    category_level: ''
  })
}

// 提交字典类型表单
const submitCategoryForm = async () => {
  if (!categoryFormRef.value) return
  
  await categoryFormRef.value.validate(async (valid) => {
    if (!valid) return
    
    submitting.value = true
    try {
      const data: DictCategoryForm = {
        category_no: categoryForm.category_no || undefined,
        category_name: categoryForm.category_name,
        category_desc: categoryForm.category_desc || undefined,
        parent_field: categoryForm.parent_field || '0',
        category_level: categoryForm.category_level || undefined
      }
      
      if (editingCategory.value && categoryForm.category_id) {
        // 更新
        const res = await dictApi.updateCategory(categoryForm.category_id, data)
        if (res.code === '000000') {
          ElMessage.success('字典类型更新成功')
          showCategoryDialog.value = false
          await loadCategoryTree()
        } else {
          ElMessage.error(res.message || '字典类型更新失败')
        }
      } else {
        // 创建
        const res = await dictApi.createCategory(data)
        if (res.code === '000000') {
          ElMessage.success('字典类型创建成功')
          showCategoryDialog.value = false
          await loadCategoryTree()
        } else {
          ElMessage.error(res.message || '字典类型创建失败')
        }
      }
    } catch (error: any) {
      console.error('提交字典类型失败:', error)
      ElMessage.error('操作失败')
    } finally {
      submitting.value = false
    }
  })
}

// 删除字典类型确认
const deleteCategoryConfirm = () => {
  if (!selectedCategory.value) return
  
  ElMessageBox.confirm(
    `确定要删除字典类型"${selectedCategory.value.category_name}"吗？`,
    '删除确认',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(async () => {
    await deleteCategory()
  }).catch(() => {
    // 取消删除
  })
}

// 删除字典类型
const deleteCategory = async () => {
  if (!selectedCategory.value) return
  
  try {
    const res = await dictApi.deleteCategory(selectedCategory.value.category_id)
    if (res.code === '000000') {
      ElMessage.success('字典类型删除成功')
      selectedCategory.value = null
      items.value = []
      await loadCategoryTree()
    } else {
      ElMessage.error(res.message || '字典类型删除失败')
    }
  } catch (error: any) {
    console.error('删除字典类型失败:', error)
    ElMessage.error('删除失败')
  }
}

// ==================== 字典项操作 ====================

// 打开创建字典项对话框
const openCreateItemDialog = () => {
  if (!selectedCategory.value) {
    ElMessage.warning('请先选择字典类型')
    return
  }
  
  editingItem.value = false
  resetItemForm()
  itemForm.category_id = selectedCategory.value.category_id
  showItemDialog.value = true
}

// 编辑字典项
const editItem = (row: DictItem) => {
  editingItem.value = true
  Object.assign(itemForm, {
    dict_id: row.dict_id,
    dict_name: row.dict_name,
    dict_value: row.dict_value,
    dict_desc: row.dict_desc || '',
    category_id: row.category_id,
    enable_flag: row.enable_flag,
    sort: row.sort || 0
  })
  showItemDialog.value = true
}

// 重置字典项表单
const resetItemForm = () => {
  itemFormRef.value?.resetFields()
  Object.assign(itemForm, {
    dict_id: undefined,
    dict_name: '',
    dict_value: '',
    dict_desc: '',
    category_id: '',
    enable_flag: '1',
    sort: 0
  })
}

// 提交字典项表单
const submitItemForm = async () => {
  if (!itemFormRef.value) return
  
  await itemFormRef.value.validate(async (valid) => {
    if (!valid) return
    
    submitting.value = true
    try {
      const data: DictItemForm = {
        dict_name: itemForm.dict_name,
        dict_value: itemForm.dict_value,
        dict_desc: itemForm.dict_desc || undefined,
        category_id: itemForm.category_id,
        enable_flag: itemForm.enable_flag,
        sort: itemForm.sort
      }
      
      if (editingItem.value && itemForm.dict_id) {
        // 更新
        const res = await dictApi.updateItem(itemForm.dict_id, data)
        if (res.code === '000000') {
          ElMessage.success('字典项更新成功')
          showItemDialog.value = false
          await loadItems()
        } else {
          ElMessage.error(res.message || '字典项更新失败')
        }
      } else {
        // 创建
        const res = await dictApi.createItem(data)
        if (res.code === '000000') {
          ElMessage.success('字典项创建成功')
          showItemDialog.value = false
          await loadItems()
        } else {
          ElMessage.error(res.message || '字典项创建失败')
        }
      }
    } catch (error: any) {
      console.error('提交字典项失败:', error)
      ElMessage.error('操作失败')
    } finally {
      submitting.value = false
    }
  })
}

// 删除字典项
const deleteItem = (row: DictItem) => {
  ElMessageBox.confirm(
    `确定要删除字典项"${row.dict_name}"吗？`,
    '删除确认',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(async () => {
    try {
      const res = await dictApi.deleteItem(row.dict_id)
      if (res.code === '000000') {
        ElMessage.success('字典项删除成功')
        await loadItems()
      } else {
        ElMessage.error(res.message || '字典项删除失败')
      }
    } catch (error: any) {
      console.error('删除字典项失败:', error)
      ElMessage.error('删除失败')
    }
  }).catch(() => {
    // 取消删除
  })
}

// 批量删除字典项
const batchDeleteItems = () => {
  if (selectedItems.value.length === 0) {
    ElMessage.warning('请先选择要删除的字典项')
    return
  }
  
  ElMessageBox.confirm(
    `确定要删除选中的 ${selectedItems.value.length} 个字典项吗？`,
    '批量删除确认',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    }
  ).then(async () => {
    try {
      const dictIds = selectedItems.value.map(item => item.dict_id)
      const res = await dictApi.batchDeleteItems(dictIds)
      if (res.code === '000000') {
        ElMessage.success(res.message || '批量删除成功')
        selectedItems.value = []
        await loadItems()
      } else {
        ElMessage.error(res.message || '批量删除失败')
      }
    } catch (error: any) {
      console.error('批量删除字典项失败:', error)
      ElMessage.error('批量删除失败')
    }
  }).catch(() => {
    // 取消删除
  })
}

// 切换字典项状态
const handleStatusChange = async (row: DictItem) => {
  try {
    const res = await dictApi.toggleItemStatus(row.dict_id, row.enable_flag)
    if (res.code === '000000') {
      ElMessage.success(res.message || '状态更新成功')
    } else {
      ElMessage.error(res.message || '状态更新失败')
      // 恢复原状态
      row.enable_flag = row.enable_flag === '1' ? '0' : '1'
    }
  } catch (error: any) {
    console.error('切换字典项状态失败:', error)
    ElMessage.error('状态更新失败')
    // 恢复原状态
    row.enable_flag = row.enable_flag === '1' ? '0' : '1'
  }
}

// 格式化日期
const formatDate = (dateStr: string | undefined) => {
  if (!dateStr) return '-'
  const date = new Date(dateStr)
  return date.toLocaleString('zh-CN', {
    year: 'numeric',
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
  })
}

// 初始化
onMounted(() => {
  loadCategoryTree()
})
</script>

<style scoped>
.dictionary-management {
  padding: 20px;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.page-header {
  margin-bottom: 20px;
}

.page-header h2 {
  margin: 0 0 8px 0;
  font-size: 24px;
  font-weight: 600;
  color: #303133;
}

.page-header p {
  margin: 0;
  font-size: 14px;
  color: #909399;
}

.content-container {
  flex: 1;
  display: flex;
  gap: 20px;
  overflow: hidden;
}

.tree-panel {
  width: 300px;
  background: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.tree-header {
  padding: 16px;
  border-bottom: 1px solid #ebeef5;
}

.tree-header h3 {
  margin: 0 0 12px 0;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.tree-actions {
  display: flex;
  gap: 8px;
}

.tree-actions .el-button {
  flex: 1;
}

.el-tree {
  flex: 1;
  overflow-y: auto;
  padding: 16px;
}

.list-panel {
  flex: 1;
  background: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.list-header {
  padding: 16px;
  border-bottom: 1px solid #ebeef5;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.list-header h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.list-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.el-table {
  flex: 1;
}

.empty-state {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.pagination {
  padding: 16px;
  border-top: 1px solid #ebeef5;
  display: flex;
  justify-content: flex-end;
}
</style>
