<script setup lang="ts">
import { reactive, onMounted, ref, nextTick } from "vue";
import { http } from "@/utils/http";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { ElMessage } from "element-plus";

defineOptions({ name: "AdminDict" });

const queryRef = ref();

interface DictItem {
  id?: number;
  name: string;
  value: string;
  weight: number;
  code?: string;
  remark?: string;
}

const state = reactive({
  formQuery: {
    code: ""
  },
  tableData: {
    height: 500,
    data: [] as Array<any>,
    loading: false
  },
  columns: [
    { label: "编码", prop: "code", width: 250 },
    { label: "备注", prop: "remark", width: 160 },
    { label: "操作时间", prop: "updateTime", width: 180 }
  ],
  dictForm: {
    id: 0,
    code: "",
    remark: "",
    list: [] as DictItem[]
  },
  visible: false,
  saveVisible: false,
  dictList: [] as any[]
});

onMounted(() => {
  loadData();
  nextTick(() => {
    const bodyHeight = document.body.clientHeight;
    const queryHeight = queryRef.value?.$el?.clientHeight || 0;
    state.tableData.height = bodyHeight - queryHeight - 230;
  });
});

const loadData = (refresh: boolean = false) => {
  if (refresh) {
    state.formQuery.code = "";
  }
  state.tableData.loading = true;
  http.request<any>("post", "dataDict/list", { data: state.formQuery })
    .then((res: any) => {
      state.dictList = res || [];
      // 去重
      const seen = new Set();
      state.tableData.data = (res || []).filter((item: any) => {
        if (seen.has(item.code)) {
          return false;
        }
        seen.add(item.code);
        return true;
      });
      state.tableData.loading = false;
    })
    .catch(() => {
      state.tableData.loading = false;
    });
};

const handleDictRowClick = (row: any) => {
  const list = state.dictList.filter((k: any) => k.code === row.code);
  if (list.length === 0) {
    state.dictForm = {
      id: 0,
      code: "",
      remark: "",
      list: []
    };
    return;
  }

  // 按 weight 排序
  list.sort((a: any, b: any) => (a.weight || 0) - (b.weight || 0));

  state.dictForm = {
    id: list[0].id,
    code: list[0].code,
    remark: list[0].remark,
    list: list
  };
  state.visible = true;
};

const handleDeleteDictItem = (idx: number) => {
  state.saveVisible = true;
  state.dictForm.list.splice(idx, 1);
};

const handleAddDict = () => {
  state.saveVisible = true;
  state.visible = true;
  state.dictForm = {
    code: "字典码值",
    remark: "备注",
    list: [{ name: "", value: "", weight: 0 }]
  };
};

const handleAddDictItem = () => {
  state.saveVisible = true;
  state.dictForm.list.push({
    code: "",
    name: "",
    value: "",
    remark: "",
    weight: 0
  });
};

const handleSaveDict = () => {
  try {
    const params = state.dictForm.list.map((k) => {
      const { id, name, value, weight } = k;
      if (!name) {
        throw new Error("字典项名称不能为空");
      }
      if (!value) {
        throw new Error("字典项码值不能为空");
      }
      return {
        id,
        name,
        value,
        weight,
        code: state.dictForm.code,
        remark: state.dictForm.remark
      };
    });

    http.request<any>("post", "dataDict/saveOrUpdate", { data: params })
      .then(() => {
        ElMessage.success("保存成功");
        state.saveVisible = false;
        state.dictForm = {
          id: 0,
          code: "",
          remark: "",
          list: []
        };
        loadData();
      });
  } catch (e: any) {
    ElMessage.error(e.message);
  }
};

const handleSearch = () => {
  loadData();
};

const handleReset = () => {
  state.formQuery.code = "";
  loadData();
};
</script>

<template>
  <div class="page-container">
    <el-card shadow="hover">
      <template #header>
        <span class="card-header">数据字典</span>
      </template>
      <el-form ref="queryRef" :model="state.formQuery" inline class="search-form">
        <el-form-item>
          <el-input
            v-model="state.formQuery.code"
            placeholder="字典编码"
            clearable
            style="width: 150px"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :icon="useRenderIcon('ri/search-line')" @click="handleSearch">查询</el-button>
          <el-button :icon="useRenderIcon('ri/refresh-line')" @click="handleReset">重置</el-button>
          <el-button type="success" :icon="useRenderIcon('ri/add-line')" @click="handleAddDict">创建</el-button>
        </el-form-item>
      </el-form>

      <div class="dict-container">
        <el-table
          v-loading="state.tableData.loading"
          :data="state.tableData.data"
          :height="state.tableData.height"
          border
          stripe
          style="width: 400px"
          row-key="id"
          highlight-current-row
          @row-click="handleDictRowClick"
        >
          <template #empty>
            <el-empty description="暂无数据" />
          </template>
          <el-table-column
            v-for="field in state.columns"
            :key="field.prop"
            :label="field.label"
            :prop="field.prop"
            :width="field.width"
            show-overflow-tooltip
          />
        </el-table>

        <div v-if="state.visible" class="dict-content-box">
          <el-input
            v-model="state.dictForm.code"
            :readonly="!!state.dictForm.id"
            placeholder="字典编码"
            clearable
            class="w100"
          />

          <el-input
            v-model="state.dictForm.remark"
            placeholder="备注"
            clearable
            type="textarea"
            :rows="2"
            class="w100 mt10"
          />

          <el-row :gutter="10" class="mt20">
            <el-col :span="8">字典项名称</el-col>
            <el-col :span="8">字典项码值</el-col>
            <el-col :span="4">排序权重</el-col>
          </el-row>

          <div v-for="(item, idx) in state.dictForm.list" :key="idx" class="mt10">
            <el-row :gutter="10">
              <el-col :span="8">
                <el-input v-model="item.name" placeholder="显示名称" @change="state.saveVisible = true" />
              </el-col>
              <el-col :span="8">
                <el-input v-model="item.value" :readonly="!!item.id" placeholder="数据码值" />
              </el-col>
              <el-col :span="8">
                <el-input-number
                  v-model="item.weight"
                  :min="1"
                  controls-position="right"
                  placeholder="排序权重"
                />
                <el-icon
                  class="ml3 cursor-pointer"
                  color="var(--el-color-danger)"
                  style="margin-left: 5px; cursor: pointer"
                  @click="handleDeleteDictItem(idx)"
                >
                  <ele-RemoveFilled />
                </el-icon>
              </el-col>
            </el-row>
          </div>

          <el-button size="small" class="mt10 mr5" type="primary" @click="handleAddDictItem">
            新增
          </el-button>
          <el-button v-if="state.saveVisible" size="small" class="mt10" type="success" @click="handleSaveDict">
            保存
          </el-button>
        </div>
      </div>
    </el-card>
  </div>
</template>

<style scoped lang="scss">
.page-container {
  padding: 15px;
}

.card-header { font-size: 16px; font-weight: 600; }

.search-form {
  margin-bottom: 15px;
}

.dict-container {
  display: flex;
  gap: 10px;
}

.dict-content-box {
  flex: 1;
  margin-left: 10px;
  padding: 0 5px;
}

.w100 {
  width: 100%;
}

.mt10 {
  margin-top: 10px;
}

.mt20 {
  margin-top: 20px;
}

.ml3 {
  margin-left: 3px;
}

.cursor-pointer {
  cursor: pointer;
}
</style>
