<script setup lang="ts">
import { ref, onMounted, watch } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import {
  getDictTypeList,
  getDictDataPage,
  addDictType,
  updateDictType,
  deleteDictType,
  addDictData,
  updateDictData,
  deleteDictData,
  batchDeleteDictData,
  importDictData,
  type DictType,
  type DictData
} from "@/api/dict";
import { useDictStore } from "@/store/modules/dict";
import Refresh from "~icons/ep/refresh";
import Plus from "~icons/ep/plus";
import Edit from "~icons/ep/edit";
import Delete from "~icons/ep/delete";
import Search from "~icons/ep/search";
import Download from "~icons/ep/download";
import Upload from "~icons/ep/upload";

defineOptions({
  name: "SystemDict"
});

const loading = ref(false);
const dictTypeList = ref<DictType[]>([]);
const dictTypeTotal = ref(0);
const currentDictType = ref<DictType | null>(null);
const dictDataList = ref<DictData[]>([]);
const dictDataTotal = ref(0);
const selectedDataIds = ref<number[]>([]);
const dictStore = useDictStore();

const typeSearchForm = ref({
  dictCode: "",
  dictName: "",
  status: null as number | null
});

const dataSearchForm = ref({
  itemLabel: "",
  status: null as number | null
});

const typePagination = ref({
  page: 1,
  pageSize: 20
});

const dataPagination = ref({
  page: 1,
  pageSize: 10
});

const typeDialogVisible = ref(false);
const dataDialogVisible = ref(false);
const typeForm = ref<DictType>({
  dictCode: "",
  dictName: "",
  dictDesc: "",
  status: 1,
  sortOrder: 0,
  remark: ""
});
const dataForm = ref<DictData>({
  dictCode: "",
  itemValue: "",
  itemLabel: "",
  itemDesc: "",
  listClass: "",
  isDefault: 0,
  status: 1,
  sortOrder: 0,
  remark: ""
});
const isEdit = ref(false);

const statusOptions = [
  { value: 1, label: "启用" },
  { value: 0, label: "禁用" }
];

const listClassOptions = [
  { value: "", label: "默认" },
  { value: "primary", label: "主要" },
  { value: "success", label: "成功" },
  { value: "info", label: "信息" },
  { value: "warning", label: "警告" },
  { value: "danger", label: "危险" }
];

const loadDictTypes = async () => {
  loading.value = true;
  try {
    const { data } = await getDictTypeList({
      ...typeSearchForm.value,
      ...typePagination.value
    });
    if (data) {
      dictTypeList.value = data.list || [];
      dictTypeTotal.value = data.total || 0;
      if (dictTypeList.value.length > 0 && !currentDictType.value) {
        currentDictType.value = dictTypeList.value[0];
      }
    }
  } catch (error) {
    console.error("加载字典类型失败:", error);
  } finally {
    loading.value = false;
  }
};

const loadDictData = async () => {
  if (!currentDictType.value) {
    dictDataList.value = [];
    dictDataTotal.value = 0;
    return;
  }
  loading.value = true;
  try {
    const { data } = await getDictDataPage({
      dictCode: currentDictType.value.dictCode,
      ...dataSearchForm.value,
      ...dataPagination.value
    });
    if (data) {
      dictDataList.value = data.list || [];
      dictDataTotal.value = data.total || 0;
    }
  } catch (error) {
    console.error("加载字典数据失败:", error);
  } finally {
    loading.value = false;
  }
};

const handleTypeSearch = () => {
  typePagination.value.page = 1;
  loadDictTypes();
};

const handleTypeReset = () => {
  typeSearchForm.value = {
    dictCode: "",
    dictName: "",
    status: null
  };
  handleTypeSearch();
};

const handleDataSearch = () => {
  dataPagination.value.page = 1;
  loadDictData();
};

const handleDataReset = () => {
  dataSearchForm.value = {
    itemLabel: "",
    status: null
  };
  handleDataSearch();
};

const handleTypeSizeChange = (size: number) => {
  typePagination.value.pageSize = size;
  loadDictTypes();
};

const handleTypeCurrentChange = (page: number) => {
  typePagination.value.page = page;
  loadDictTypes();
};

const handleDataSizeChange = (size: number) => {
  dataPagination.value.pageSize = size;
  loadDictData();
};

const handleDataCurrentChange = (page: number) => {
  dataPagination.value.page = page;
  loadDictData();
};

const handleSelectType = (type: DictType) => {
  currentDictType.value = type;
  dataPagination.value.page = 1;
  selectedDataIds.value = [];
  loadDictData();
};

const handleAddType = () => {
  isEdit.value = false;
  typeForm.value = {
    dictCode: "",
    dictName: "",
    dictDesc: "",
    status: 1,
    sortOrder: 0,
    remark: ""
  };
  typeDialogVisible.value = true;
};

const handleEditType = (row: DictType) => {
  isEdit.value = true;
  typeForm.value = { ...row };
  typeDialogVisible.value = true;
};

const handleDeleteType = async (row: DictType) => {
  if (row.isSystem === 1) {
    ElMessage.warning("系统内置字典不允许删除");
    return;
  }
  try {
    await ElMessageBox.confirm(`确定要删除字典类型【${row.dictName}】吗？删除后将同时删除该字典下的所有数据项！`, "提示", {
      type: "warning"
    });
    await deleteDictType(row.id!);
    ElMessage.success("删除成功");
    if (currentDictType.value?.id === row.id) {
      currentDictType.value = null;
    }
    loadDictTypes();
  } catch (error) {
    if (error !== "cancel") {
      console.error("删除失败:", error);
    }
  }
};

const handleTypeSubmit = async () => {
  try {
    if (isEdit.value) {
      await updateDictType(typeForm.value);
      ElMessage.success("修改成功");
    } else {
      await addDictType(typeForm.value);
      ElMessage.success("添加成功");
    }
    typeDialogVisible.value = false;
    loadDictTypes();
  } catch (error) {
    console.error("保存失败:", error);
  }
};

const handleAddData = () => {
  if (!currentDictType.value) {
    ElMessage.warning("请先选择字典类型");
    return;
  }
  isEdit.value = false;
  dataForm.value = {
    dictCode: currentDictType.value.dictCode,
    itemValue: "",
    itemLabel: "",
    itemDesc: "",
    listClass: "",
    isDefault: 0,
    status: 1,
    sortOrder: 0,
    remark: ""
  };
  dataDialogVisible.value = true;
};

const handleEditData = (row: DictData) => {
  isEdit.value = true;
  dataForm.value = { ...row };
  dataDialogVisible.value = true;
};

const handleDeleteData = async (row: DictData) => {
  try {
    await ElMessageBox.confirm(`确定要删除字典项【${row.itemLabel}】吗？`, "提示", {
      type: "warning"
    });
    await deleteDictData(row.id!);
    ElMessage.success("删除成功");
    loadDictData();
  } catch (error) {
    if (error !== "cancel") {
      console.error("删除失败:", error);
    }
  }
};

const handleBatchDelete = async () => {
  if (selectedDataIds.value.length === 0) {
    ElMessage.warning("请选择要删除的数据");
    return;
  }
  try {
    await ElMessageBox.confirm(`确定要删除选中的 ${selectedDataIds.value.length} 条数据吗？`, "提示", {
      type: "warning"
    });
    await batchDeleteDictData(selectedDataIds.value);
    ElMessage.success("删除成功");
    selectedDataIds.value = [];
    loadDictData();
  } catch (error) {
    if (error !== "cancel") {
      console.error("批量删除失败:", error);
    }
  }
};

const handleDataSubmit = async () => {
  try {
    if (isEdit.value) {
      await updateDictData(dataForm.value);
      ElMessage.success("修改成功");
    } else {
      await addDictData(dataForm.value);
      ElMessage.success("添加成功");
    }
    dataDialogVisible.value = false;
    loadDictData();
  } catch (error) {
    console.error("保存失败:", error);
  }
};

const handleSelectionChange = (selection: DictData[]) => {
  selectedDataIds.value = selection.map(item => item.id!);
};

const handleExport = () => {
  if (!currentDictType.value) {
    ElMessage.warning("请先选择字典类型");
    return;
  }
  if (dictDataList.value.length === 0) {
    ElMessage.warning("暂无数据可导出");
    return;
  }
  const exportData = dictDataList.value.map(item => ({
    字典编码: item.dictCode,
    字典值: item.itemValue,
    字典标签: item.itemLabel,
    描述: item.itemDesc || "",
    样式类型: item.listClass || "",
    是否默认: item.isDefault === 1 ? "是" : "否",
    状态: item.status === 1 ? "启用" : "禁用",
    排序: item.sortOrder || 0,
    备注: item.remark || ""
  }));
  const headers = Object.keys(exportData[0] || {});
  const csvContent = [
    headers.join(","),
    ...exportData.map(row => headers.map(h => `"${row[h as keyof typeof row] || ""}"`).join(","))
  ].join("\n");
  const blob = new Blob(["\ufeff" + csvContent], { type: "text/csv;charset=utf-8;" });
  const link = document.createElement("a");
  link.href = URL.createObjectURL(blob);
  link.download = `字典数据_${currentDictType.value.dictCode}_${new Date().toISOString().split("T")[0]}.csv`;
  link.click();
  URL.revokeObjectURL(link.href);
  ElMessage.success("导出成功");
};

const importInputRef = ref<HTMLInputElement | null>(null);

const handleImportClick = () => {
  if (!currentDictType.value) {
    ElMessage.warning("请先选择字典类型");
    return;
  }
  importInputRef.value?.click();
};

const handleImportFile = async (event: Event) => {
  const input = event.target as HTMLInputElement;
  const file = input.files?.[0];
  if (!file) return;
  try {
    const text = await file.text();
    const lines = text.split("\n").filter(line => line.trim());
    if (lines.length < 2) {
      ElMessage.error("文件内容为空或格式不正确");
      return;
    }
    const headers = lines[0].split(",").map(h => h.replace(/"/g, "").trim());
    const dataList: DictData[] = [];
    for (let i = 1; i < lines.length; i++) {
      const values = lines[i].split(",").map(v => v.replace(/"/g, "").trim());
      if (values.length >= 3) {
        dataList.push({
          dictCode: currentDictType.value!.dictCode,
          itemValue: values[headers.indexOf("字典值")] || values[1] || "",
          itemLabel: values[headers.indexOf("字典标签")] || values[2] || "",
          itemDesc: values[headers.indexOf("描述")] || "",
          listClass: values[headers.indexOf("样式类型")] || "",
          isDefault: values[headers.indexOf("是否默认")] === "是" ? 1 : 0,
          status: values[headers.indexOf("状态")] === "禁用" ? 0 : 1,
          sortOrder: parseInt(values[headers.indexOf("排序")]) || 0,
          remark: values[headers.indexOf("备注")] || ""
        });
      }
    }
    if (dataList.length === 0) {
      ElMessage.error("未解析到有效数据");
      return;
    }
    await ElMessageBox.confirm(`将导入 ${dataList.length} 条数据，是否继续？`, "导入确认", {
      type: "warning"
    });
    await importDictData(dataList);
    ElMessage.success("导入成功");
    dictStore.refresh();
    loadDictData();
  } catch (error) {
    if (error !== "cancel") {
      console.error("导入失败:", error);
      ElMessage.error("导入失败");
    }
  } finally {
    input.value = "";
  }
};

watch(currentDictType, () => {
  loadDictData();
});

onMounted(() => {
  loadDictTypes();
});
</script>

<template>
  <div class="dict-container">
    <div class="dict-left">
      <div class="panel-header">
        <span class="title">字典类型</span>
        <el-button type="primary" size="small" @click="handleAddType">
          <el-icon><IconifyIconOffline :icon="Plus" /></el-icon>
          新增
        </el-button>
      </div>
      
      <div class="search-box">
        <el-input
          v-model="typeSearchForm.dictName"
          placeholder="字典名称"
          clearable
          size="small"
          @keyup.enter="handleTypeSearch"
        >
          <template #prefix>
            <el-icon><IconifyIconOffline :icon="Search" /></el-icon>
          </template>
        </el-input>
        <div class="search-btns">
          <el-button type="primary" size="small" @click="handleTypeSearch">查询</el-button>
          <el-button size="small" @click="handleTypeReset">重置</el-button>
        </div>
      </div>
      
      <div class="type-list">
        <div
          v-for="item in dictTypeList"
          :key="item.id"
          :class="['type-item', { active: currentDictType?.id === item.id }]"
          @click="handleSelectType(item)"
        >
          <div class="type-info">
            <span class="type-name">{{ item.dictName }}</span>
            <span class="type-code">{{ item.dictCode }}</span>
          </div>
          <div class="type-actions">
            <el-tag :type="item.status === 1 ? 'success' : 'danger'" size="small">
              {{ item.status === 1 ? '启用' : '禁用' }}
            </el-tag>
          </div>
        </div>
        <el-empty v-if="dictTypeList.length === 0" description="暂无数据" :image-size="60" />
      </div>
      
      <div class="pagination-box">
        <el-pagination
          v-model:current-page="typePagination.page"
          v-model:page-size="typePagination.pageSize"
          :total="dictTypeTotal"
          :page-sizes="[20, 50, 100]"
          layout="total, prev, pager, next"
          small
          @size-change="handleTypeSizeChange"
          @current-change="handleTypeCurrentChange"
        />
      </div>
    </div>
    
    <div class="dict-right">
      <div class="panel-header">
        <span class="title">字典数据</span>
        <div class="header-actions">
          <el-button type="primary" size="small" :disabled="!currentDictType" @click="handleAddData">
            <el-icon><IconifyIconOffline :icon="Plus" /></el-icon>
            新增
          </el-button>
          <el-button type="danger" size="small" :disabled="selectedDataIds.length === 0" @click="handleBatchDelete">
            <el-icon><IconifyIconOffline :icon="Delete" /></el-icon>
            批量删除
          </el-button>
          <el-button size="small" :disabled="!currentDictType" @click="handleExport">
            <el-icon><IconifyIconOffline :icon="Download" /></el-icon>
            导出
          </el-button>
          <el-button size="small" :disabled="!currentDictType" @click="handleImportClick">
            <el-icon><IconifyIconOffline :icon="Upload" /></el-icon>
            导入
          </el-button>
          <input
            ref="importInputRef"
            type="file"
            accept=".csv"
            style="display: none"
            @change="handleImportFile"
          />
          <el-button size="small" @click="loadDictData">
            <el-icon><IconifyIconOffline :icon="Refresh" /></el-icon>
            刷新
          </el-button>
        </div>
      </div>
      
      <div v-if="currentDictType" class="current-type-info">
        <span>当前字典：{{ currentDictType.dictName }}（{{ currentDictType.dictCode }}）</span>
        <span class="type-desc" v-if="currentDictType.dictDesc">{{ currentDictType.dictDesc }}</span>
      </div>
      
      <div class="search-box">
        <el-input
          v-model="dataSearchForm.itemLabel"
          placeholder="字典标签"
          clearable
          size="small"
          style="width: 150px"
          @keyup.enter="handleDataSearch"
        />
        <el-select
          v-model="dataSearchForm.status"
          placeholder="状态"
          clearable
          size="small"
          style="width: 100px"
        >
          <el-option
            v-for="item in statusOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
        <el-button type="primary" size="small" @click="handleDataSearch">查询</el-button>
        <el-button size="small" @click="handleDataReset">重置</el-button>
      </div>
      
      <el-table
        v-loading="loading"
        :data="dictDataList"
        border
        size="small"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="50" />
        <el-table-column prop="itemValue" label="字典值" width="100" />
        <el-table-column prop="itemLabel" label="字典标签" width="120">
          <template #default="{ row }">
            <el-tag v-if="row.listClass" :type="row.listClass as any">{{ row.itemLabel }}</el-tag>
            <span v-else>{{ row.itemLabel }}</span>
          </template>
        </el-table-column>
        <el-table-column prop="itemDesc" label="描述" min-width="150" show-overflow-tooltip />
        <el-table-column prop="sortOrder" label="排序" width="70" />
        <el-table-column prop="isDefault" label="默认" width="70">
          <template #default="{ row }">
            <el-tag v-if="row.isDefault === 1" type="success" size="small">是</el-tag>
            <span v-else>否</span>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" width="80">
          <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="createTime" label="创建时间" width="160" />
        <el-table-column label="操作" width="120" fixed="right">
          <template #default="{ row }">
            <el-button type="primary" link size="small" @click="handleEditData(row)">
              <el-icon><IconifyIconOffline :icon="Edit" /></el-icon>
              编辑
            </el-button>
            <el-button type="danger" link size="small" @click="handleDeleteData(row)">
              <el-icon><IconifyIconOffline :icon="Delete" /></el-icon>
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      
      <div class="pagination-box">
        <el-pagination
          v-model:current-page="dataPagination.page"
          v-model:page-size="dataPagination.pageSize"
          :total="dictDataTotal"
          :page-sizes="[10, 20, 50, 100]"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleDataSizeChange"
          @current-change="handleDataCurrentChange"
        />
      </div>
    </div>
    
    <el-dialog
      v-model="typeDialogVisible"
      :title="isEdit ? '编辑字典类型' : '新增字典类型'"
      width="500px"
      destroy-on-close
    >
      <el-form :model="typeForm" label-width="100px">
        <el-form-item label="字典编码" required>
          <el-input v-model="typeForm.dictCode" :disabled="isEdit" placeholder="请输入字典编码" />
        </el-form-item>
        <el-form-item label="字典名称" required>
          <el-input v-model="typeForm.dictName" placeholder="请输入字典名称" />
        </el-form-item>
        <el-form-item label="字典描述">
          <el-input v-model="typeForm.dictDesc" type="textarea" :rows="2" placeholder="请输入字典描述" />
        </el-form-item>
        <el-form-item label="状态">
          <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-item label="排序">
          <el-input-number v-model="typeForm.sortOrder" :min="0" />
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="typeForm.remark" type="textarea" :rows="2" placeholder="请输入备注" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="typeDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleTypeSubmit">确定</el-button>
      </template>
    </el-dialog>
    
    <el-dialog
      v-model="dataDialogVisible"
      :title="isEdit ? '编辑字典数据' : '新增字典数据'"
      width="500px"
      destroy-on-close
    >
      <el-form :model="dataForm" label-width="100px">
        <el-form-item label="字典值" required>
          <el-input v-model="dataForm.itemValue" placeholder="请输入字典值" />
        </el-form-item>
        <el-form-item label="字典标签" required>
          <el-input v-model="dataForm.itemLabel" placeholder="请输入字典标签" />
        </el-form-item>
        <el-form-item label="样式类型">
          <el-select v-model="dataForm.listClass" placeholder="请选择样式类型">
            <el-option
              v-for="item in listClassOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="dataForm.itemDesc" type="textarea" :rows="2" placeholder="请输入描述" />
        </el-form-item>
        <el-form-item label="是否默认">
          <el-radio-group v-model="dataForm.isDefault">
            <el-radio :value="1">是</el-radio>
            <el-radio :value="0">否</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="状态">
          <el-radio-group v-model="dataForm.status">
            <el-radio :value="1">启用</el-radio>
            <el-radio :value="0">禁用</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="排序">
          <el-input-number v-model="dataForm.sortOrder" :min="0" />
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="dataForm.remark" type="textarea" :rows="2" placeholder="请输入备注" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dataDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleDataSubmit">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<style lang="scss" scoped>
.dict-container {
  display: flex;
  gap: 16px;
  padding: 16px;
  height: calc(100vh - 120px);
  background: #f5f7fa;
}

.dict-left {
  width: 320px;
  background: #fff;
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.dict-right {
  flex: 1;
  background: #fff;
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px;
  border-bottom: 1px solid #ebeef5;
  
  .title {
    font-size: 16px;
    font-weight: 600;
    color: #303133;
  }
  
  .header-actions {
    display: flex;
    gap: 8px;
  }
}

.search-box {
  padding: 12px 16px;
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  border-bottom: 1px solid #ebeef5;
  
  .search-btns {
    display: flex;
    gap: 8px;
  }
}

.type-list {
  flex: 1;
  overflow-y: auto;
  padding: 8px;
}

.type-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s;
  margin-bottom: 4px;
  
  &:hover {
    background: #f5f7fa;
  }
  
  &.active {
    background: #ecf5ff;
    border: 1px solid #409eff;
  }
  
  .type-info {
    display: flex;
    flex-direction: column;
    gap: 4px;
    
    .type-name {
      font-size: 14px;
      color: #303133;
    }
    
    .type-code {
      font-size: 12px;
      color: #909399;
    }
  }
}

.current-type-info {
  padding: 12px 16px;
  background: #f5f7fa;
  font-size: 13px;
  color: #606266;
  
  .type-desc {
    margin-left: 12px;
    color: #909399;
  }
}

.pagination-box {
  padding: 12px 16px;
  border-top: 1px solid #ebeef5;
  display: flex;
  justify-content: flex-end;
}

:deep(.el-table) {
  flex: 1;
  overflow: auto;
}
</style>
