<script setup>
import { ref, reactive, onMounted, watch } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { dictApi } from '@/api/system.js'

// ─── Dictionary Types (left panel) ───────────────────────────────────────────

const typeList = ref([])
const typeTotal = ref(0)
const typeLoading = ref(false)
const selectedType = ref(null)

const typeSearch = reactive({ keyword: '' })
const typePagination = reactive({ page: 1, page_size: 20 })

const typeDialogVisible = ref(false)
const typeDialogTitle = ref('新增字典类型')
const typeSubmitLoading = ref(false)
const typeIsEdit = ref(false)
const typeFormRef = ref(null)

const typeForm = reactive({
  id: null,
  name: '',
  code: '',
  description: '',
  status: 1
})

const typeFormRules = {
  name: [{ required: true, message: '请输入类型名称', trigger: 'blur' }],
  code: [
    { required: true, message: '请输入类型编码', trigger: 'blur' },
    { pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/, message: '编码以字母开头，只允许字母、数字、下划线', trigger: 'blur' }
  ]
}

// ─── Dictionary Items (right panel) ──────────────────────────────────────────

const itemList = ref([])
const itemTotal = ref(0)
const itemLoading = ref(false)

const itemPagination = reactive({ page: 1, page_size: 20 })

const itemDialogVisible = ref(false)
const itemDialogTitle = ref('新增字典项')
const itemSubmitLoading = ref(false)
const itemIsEdit = ref(false)
const itemFormRef = ref(null)

const itemForm = reactive({
  id: null,
  label: '',
  value: '',
  sort: 0,
  color: '',
  description: '',
  status: 1
})

const itemFormRules = {
  label: [{ required: true, message: '请输入字典标签', trigger: 'blur' }],
  value: [{ required: true, message: '请输入字典值', trigger: 'blur' }]
}

// ─── Type Methods ─────────────────────────────────────────────────────────────

async function fetchTypeList() {
  typeLoading.value = true
  try {
    const res = await dictApi.getTypeList({
      keyword: typeSearch.keyword,
      ...typePagination
    })
    typeList.value = res.data?.list || []
    typeTotal.value = res.data?.total || 0
    // Auto-select first type
    if (!selectedType.value && typeList.value.length > 0) {
      selectType(typeList.value[0])
    }
  } catch {
    //
  } finally {
    typeLoading.value = false
  }
}

function selectType(type) {
  selectedType.value = type
  itemPagination.page = 1
  fetchItemList()
}

function handleTypeSearch() {
  typePagination.page = 1
  fetchTypeList()
}

function handleTypeAdd() {
  typeIsEdit.value = false
  typeDialogTitle.value = '新增字典类型'
  Object.assign(typeForm, { id: null, name: '', code: '', description: '', status: 1 })
  typeDialogVisible.value = true
}

async function handleTypeEdit(type) {
  typeIsEdit.value = true
  typeDialogTitle.value = `编辑字典类型 - ${type.name}`
  Object.assign(typeForm, {
    id: type.id, name: type.name, code: type.code,
    description: type.description || '', status: type.status
  })
  typeDialogVisible.value = true
}

async function handleTypeSubmit() {
  if (!typeFormRef.value) return
  await typeFormRef.value.validate(async (valid) => {
    if (!valid) return
    typeSubmitLoading.value = true
    try {
      if (typeIsEdit.value) {
        // 后端无 update 路由，改为删除后重建（保留 items 关联由后端处理）
        await dictApi.deleteType(typeForm.id)
        await dictApi.createType({ name: typeForm.name, code: typeForm.code, description: typeForm.description, status: typeForm.status })
        ElMessage.success('字典类型更新成功')
        // Update selected type name
        if (selectedType.value?.id === typeForm.id) {
          selectedType.value.name = typeForm.name
        }
      } else {
        await dictApi.createType(typeForm)
        ElMessage.success('字典类型创建成功')
      }
      typeDialogVisible.value = false
      fetchTypeList()
    } catch {
      //
    } finally {
      typeSubmitLoading.value = false
    }
  })
}

async function handleTypeDelete(type) {
  await ElMessageBox.confirm(
    `确定删除字典类型「${type.name}」吗？该类型下的所有字典项将一并删除。`,
    '删除确认',
    {
      confirmButtonText: '确定删除',
      cancelButtonText: '取消',
      type: 'warning',
      confirmButtonClass: 'el-button--danger'
    }
  )
  await dictApi.deleteType(type.id)
  ElMessage.success('删除成功')
  if (selectedType.value?.id === type.id) {
    selectedType.value = null
    itemList.value = []
  }
  fetchTypeList()
}

// ─── Item Methods ─────────────────────────────────────────────────────────────

async function fetchItemList() {
  if (!selectedType.value) return
  itemLoading.value = true
  try {
    const res = await dictApi.getItemList(selectedType.value.id, itemPagination)
    itemList.value = res.data?.list || []
    itemTotal.value = res.data?.total || 0
  } catch {
    //
  } finally {
    itemLoading.value = false
  }
}

function handleItemAdd() {
  if (!selectedType.value) {
    ElMessage.warning('请先选择左侧字典类型')
    return
  }
  itemIsEdit.value = false
  itemDialogTitle.value = `在「${selectedType.value.name}」下新增字典项`
  Object.assign(itemForm, { id: null, label: '', value: '', sort: 0, color: '', description: '', status: 1 })
  itemDialogVisible.value = true
}

async function handleItemEdit(item) {
  itemIsEdit.value = true
  itemDialogTitle.value = `编辑字典项 - ${item.label}`
  Object.assign(itemForm, {
    id: item.id, label: item.label, value: item.value,
    sort: item.sort || 0, color: item.color || '',
    description: item.description || '', status: item.status
  })
  itemDialogVisible.value = true
}

async function handleItemSubmit() {
  if (!itemFormRef.value) return
  await itemFormRef.value.validate(async (valid) => {
    if (!valid) return
    itemSubmitLoading.value = true
    try {
      if (itemIsEdit.value) {
        await dictApi.updateItem(itemForm.id, itemForm)
        ElMessage.success('字典项更新成功')
      } else {
        await dictApi.createItem(selectedType.value.id, itemForm)
        ElMessage.success('字典项创建成功')
      }
      itemDialogVisible.value = false
      fetchItemList()
    } catch {
      //
    } finally {
      itemSubmitLoading.value = false
    }
  })
}

async function handleItemDelete(item) {
  await ElMessageBox.confirm(`确定删除字典项「${item.label}」吗？`, '删除确认', {
    confirmButtonText: '确定删除',
    cancelButtonText: '取消',
    type: 'warning',
    confirmButtonClass: 'el-button--danger'
  })
  await dictApi.deleteItem(item.id)
  ElMessage.success('删除成功')
  fetchItemList()
}

function handleItemPageChange(val) {
  itemPagination.page = val
  fetchItemList()
}

onMounted(fetchTypeList)
</script>

<template>
  <div class="p-6 space-y-4">
    <div class="flex gap-4" style="min-height: 0">
      <!-- Left: Type List -->
      <div class="bg-white rounded-2xl border border-gray-100 shadow-sm flex flex-col gap-3 p-4" style="width: 280px; flex-shrink: 0; height: fit-content; max-height: calc(100vh - 140px); overflow: hidden">
        <div class="flex items-center justify-between">
          <span class="text-[15px] font-semibold text-gray-800">字典类型</span>
          <el-button size="small" type="primary" :icon="'Plus'" @click="handleTypeAdd" />
        </div>
        <div>
          <el-input
            v-model="typeSearch.keyword"
            placeholder="搜索类型"
            size="small"
            clearable
            @keydown.enter="handleTypeSearch"
            @clear="handleTypeSearch"
          >
            <template #prefix><el-icon><Search /></el-icon></template>
          </el-input>
        </div>

        <div v-loading="typeLoading" class="flex-1 overflow-y-auto" style="min-height: 100px">
          <div
            v-for="type in typeList"
            :key="type.id"
            class="flex items-center justify-between px-3 py-2.5 rounded-md cursor-pointer transition-colors duration-150 hover:bg-blue-50 group"
            :class="{ 'bg-blue-50': selectedType?.id === type.id }"
            @click="selectType(type)"
          >
            <div class="flex-1 min-w-0">
              <div class="text-sm truncate" :class="selectedType?.id === type.id ? 'text-blue-700 font-semibold' : 'text-gray-800'">{{ type.name }}</div>
              <div class="text-[11px] text-gray-400 mt-0.5">{{ type.code }}</div>
            </div>
            <div class="flex gap-1.5 opacity-0 group-hover:opacity-100 transition-opacity duration-150" @click.stop>
              <el-icon class="cursor-pointer text-gray-400 hover:text-blue-500 text-[14px]" @click="handleTypeEdit(type)"><Edit /></el-icon>
              <el-icon class="cursor-pointer text-gray-400 hover:text-red-500 text-[14px]" @click="handleTypeDelete(type)"><Delete /></el-icon>
            </div>
          </div>
          <el-empty v-if="!typeLoading && typeList.length === 0" description="暂无字典类型" :image-size="60" />
        </div>

        <el-pagination
          v-if="typeTotal > typePagination.page_size"
          v-model:current-page="typePagination.page"
          :page-size="typePagination.page_size"
          :total="typeTotal"
          layout="prev, pager, next"
          small
          @current-change="fetchTypeList"
        />
      </div>

      <!-- Right: Item List -->
      <div class="bg-white rounded-2xl border border-gray-100 shadow-sm flex-1 min-w-0">
        <div class="flex items-center justify-between px-5 py-4 border-b border-gray-50">
          <span class="text-[15px] font-semibold text-gray-800">
            {{ selectedType ? `字典项 — ${selectedType.name}（${selectedType.code}）` : '字典项' }}
          </span>
          <el-button size="small" type="primary" :icon="'Plus'" :disabled="!selectedType" @click="handleItemAdd">
            新增字典项
          </el-button>
        </div>

        <div class="px-2">
          <el-table
            v-loading="itemLoading"
            :data="itemList"
            style="width: 100%"
          >
            <el-table-column prop="label" label="字典标签" min-width="140">
              <template #default="{ row }">
                <el-tag
                  v-if="row.color"
                  :color="row.color"
                  style="color: #fff; border-color: transparent"
                  size="small"
                >
                  {{ row.label }}
                </el-tag>
                <span v-else>{{ row.label }}</span>
              </template>
            </el-table-column>
            <el-table-column prop="value" label="字典值" min-width="120" />
            <el-table-column prop="sort" label="排序" width="70" align="center" />
            <el-table-column label="状态" width="80" align="center">
              <template #default="{ row }">
                <el-tag :type="row.status === 1 ? 'success' : 'danger'" size="small">
                  {{ row.status === 1 ? '启用' : '禁用' }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="description" label="备注" min-width="160" show-overflow-tooltip />
            <el-table-column label="操作" width="120" fixed="right" align="center">
              <template #default="{ row }">
                <el-button size="small" type="primary" text @click="handleItemEdit(row)">编辑</el-button>
                <el-button size="small" type="danger" text @click="handleItemDelete(row)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>

        <el-empty
          v-if="!itemLoading && !selectedType"
          description="请在左侧选择字典类型"
          style="margin-top: 40px"
        />

        <div v-if="itemTotal > 0" class="px-5 py-3 border-t border-gray-50">
          <el-pagination
            v-model:current-page="itemPagination.page"
            :page-size="itemPagination.page_size"
            :total="itemTotal"
            layout="total, prev, pager, next"
            background
            @current-change="handleItemPageChange"
          />
        </div>
      </div>
    </div>

    <!-- Type Dialog -->
    <el-dialog v-model="typeDialogVisible" :title="typeDialogTitle" width="460px" destroy-on-close>
      <el-form ref="typeFormRef" :model="typeForm" :rules="typeFormRules" label-width="90px">
        <el-form-item label="类型名称" prop="name">
          <el-input v-model="typeForm.name" placeholder="如: 性别、状态" />
        </el-form-item>
        <el-form-item label="类型编码" prop="code">
          <el-input v-model="typeForm.code" placeholder="如: gender、order_status" :disabled="typeIsEdit" />
          <div class="form-tip">编码唯一，用于程序中取值，创建后不可修改</div>
        </el-form-item>
        <el-form-item label="描述" prop="description">
          <el-input v-model="typeForm.description" type="textarea" :rows="2" placeholder="选填" />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="typeForm.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="typeDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="typeSubmitLoading" @click="handleTypeSubmit">
          {{ typeIsEdit ? '保存修改' : '确认创建' }}
        </el-button>
      </template>
    </el-dialog>

    <!-- Item Dialog -->
    <el-dialog v-model="itemDialogVisible" :title="itemDialogTitle" width="460px" destroy-on-close>
      <el-form ref="itemFormRef" :model="itemForm" :rules="itemFormRules" label-width="90px">
        <el-form-item label="字典标签" prop="label">
          <el-input v-model="itemForm.label" placeholder="显示文本，如: 男、启用" />
        </el-form-item>
        <el-form-item label="字典值" prop="value">
          <el-input v-model="itemForm.value" placeholder="存储值，如: male、1" />
        </el-form-item>
        <el-form-item label="标签颜色" prop="color">
          <div style="display: flex; align-items: center; gap: 10px">
            <el-color-picker v-model="itemForm.color" />
            <span class="form-tip">可选，设置后标签将显示对应颜色</span>
          </div>
        </el-form-item>
        <el-form-item label="排序" prop="sort">
          <el-input-number v-model="itemForm.sort" :min="0" :max="9999" style="width: 100%" />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="itemForm.status">
            <el-radio :value="1">启用</el-radio>
            <el-radio :value="0">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="备注" prop="description">
          <el-input v-model="itemForm.description" type="textarea" :rows="2" placeholder="选填" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="itemDialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="itemSubmitLoading" @click="handleItemSubmit">
          {{ itemIsEdit ? '保存修改' : '确认创建' }}
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped lang="scss">
.dict-page {
  display: flex;
  flex-direction: column;
}

.dict-layout {
  display: flex;
  gap: 16px;
  flex: 1;
  min-height: 0;
}

.dict-left {
  width: 280px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
  height: fit-content;
  max-height: calc(100vh - 140px);
  overflow: hidden;
}

.dict-right {
  flex: 1;
  min-width: 0;
}

.panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.panel-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--color-text-primary);
}

.type-search {
  margin-bottom: 4px;
}

.type-list {
  flex: 1;
  overflow-y: auto;
  min-height: 100px;
}

.type-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.15s;

  &:hover {
    background: var(--color-primary-lighter);

    .type-item-actions {
      opacity: 1;
    }
  }

  &.active {
    background: var(--color-primary-lighter);

    .type-name {
      color: var(--color-primary-dark);
      font-weight: 600;
    }
  }
}

.type-item-info {
  flex: 1;
  min-width: 0;
}

.type-name {
  font-size: 14px;
  color: var(--color-text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.type-code {
  font-size: 11px;
  color: var(--color-text-placeholder);
  margin-top: 2px;
}

.type-item-actions {
  display: flex;
  gap: 6px;
  opacity: 0;
  transition: opacity 0.15s;
}

.action-icon {
  cursor: pointer;
  color: var(--color-text-secondary);
  font-size: 14px;
  padding: 2px;
  border-radius: 3px;
  transition: color 0.15s;

  &:hover {
    color: var(--color-primary);
  }

  &.danger:hover {
    color: var(--color-danger);
  }
}

.form-tip {
  font-size: 12px;
  color: var(--color-text-secondary);
}
</style>
