<template>
  <div class="menu-index">
    <n-card :bordered="false" class="pt-3 mb-3 proCard">
      <div>
        <n-button type="primary" @click="handleAdd()" v-perm="['sys:city:add']">
          <template #icon>
            <PlusOutlined />
          </template>
          新增
        </n-button>
      </div>
    </n-card>
    <n-card :bordered="false" class="pt-3 mb-3 proCard">
      <n-spin :show="!showTable">
        <n-data-table
          :columns="columns"
          @load="getChild"
          :paginate-single-page="false"
          :data="lists"
          v-if="showTable"
          :row-key="(row) => row.areaCode"
        >
          <template #description> 加载中 </template>
        </n-data-table>
      </n-spin>
    </n-card>
    <editDialog
      ref="createModalRef"
      v-if="editVisible"
      :cityId="cityId"
      :parentData="parentData"
      :itemData="itemData"
      v-model:visible="editVisible"
      @success="refreshDataList"
    />
  </div>
</template>

<script lang="ts" setup name="menu">
  import { defineAsyncComponent, nextTick, onMounted, ref, reactive, h } from 'vue';
  import { PlusOutlined, EditOutlined, DeleteOutlined, FormOutlined } from '@vicons/antd';
  import { cityDelete } from '@/api/data/city';
  import { getCityByList } from '@/api/system/user';
  import editDialog from './edit.vue';
  import { TableAction } from '@/components/Table';
  import { renderIcon } from '@/utils';
  import { useMessage, useDialog } from 'naive-ui';

  /**
   * 定义参数变量
   */
  const columns = [
    {
      title: '城市名称',
      key: 'name',
      width: 100,
      align: 'left',
    },
    {
      title: '城市拼音',
      key: 'pinyin',
      width: 100,
    },
    {
      title: '城市级别',
      key: 'level',
      width: 100,
      customRender({ record }) {
        let levelText = '';
        switch (record.level) {
          case 0:
            levelText = '省份';
            break;
          case 1:
            levelText = '城市';
            break;
          case 2:
            levelText = '县区';
            break;
          case 3:
            levelText = '街道';
            break;
          case 4:
            levelText = '居委会';
            break;
          default:
            break;
        }
        return h('span', levelText || '-');
      },
    },
    {
      title: '城市区号',
      key: 'cityCode',
      width: 100,
    },
    {
      title: '行政编码',
      key: 'areaCode',
      width: 100,
    },
    {
      title: '城市邮编',
      key: 'zipCode',
      width: 100,
    },
    {
      title: '操作',
      fixed: 'right',
      key: 'action',
      width: 100,
      render(record) {
        return h(TableAction as any, {
          style: 'button',
          actions: [
            {
              label: '新增',
              type: 'info',
              icon: renderIcon(PlusOutlined),
              auth: ['sys:city:add'],
              onclick: handleAdd.bind(null, record),
            },
            {
              label: '编辑',
              type: 'warning',
              icon: renderIcon(FormOutlined),
              auth: ['sys:city:update'],
              onclick: handleEdit.bind(null, record),
            },
            {
              label: '删除',
              type: 'error',
              icon: renderIcon(DeleteOutlined),
              auth: ['sys:city:delete'],
              onclick: handleDelete.bind(null, record),
            },
          ],
        });
      },
    },
  ];
  const message = useMessage();
  const dialog = useDialog();
  const fwbHeight = document.body.clientHeight - 350;
  const loading = ref(false);
  const createModalRef = ref();
  const editVisible = ref(false);
  const showTable = ref(true);
  const cityId = ref(0);
  const parentData = ref();
  const itemData = ref({});
  const lists = ref([]);
  const expandKeys = ref([]);

  /**
   * 获取行政区划列表
   * @param code 参数
   */
  const loadDataTable = async (code: any) => {
    let res = await getCityByList(0);
    let data = res.length > 0 ? res : [];
    data.map((item) => {
      item.isLeaf = false;
    });
    lists.value = data;
  };
  /**
   * 刷新数据列表
   */
  const refreshDataList = async (code) => {
    showTable.value = false;
    let res = await getCityByList(0);
    let data = res.length > 0 ? res : [];
    data.map((item) => {
      item.isLeaf = false;
    });
    lists.value = data;

    showTable.value = true;
  };
  const actionColumn = reactive({
    width: 220,
    title: '操作',
    align: 'center',
    key: 'action',
    fixed: 'right',
    render(record) {
      return h(TableAction as any, {
        style: 'button',
        actions: [
          {
            label: '新增',
            type: 'info',
            icon: renderIcon(PlusOutlined),
            auth: ['sys:city:add'],
            onclick: handleAdd.bind(null, record),
          },
          {
            label: '编辑',
            type: 'warning',
            icon: renderIcon(FormOutlined),
            auth: ['sys:city:update'],
            onclick: handleEdit.bind(null, record),
          },
          {
            label: '删除',
            type: 'error',
            icon: renderIcon(DeleteOutlined),
            auth: ['sys:city:delete'],
            onclick: handleDelete.bind(null, record),
          },
        ],
      });
    },
  });

  /**
   * 执行添加
   * @param data 参数
   */
  const handleAdd = async (data: any) => {
    cityId.value = 0;
    if (data) {
      itemData.value = data;
      let datas = findParentNode(lists.value, data.pid);
      if (datas) {
        parentData.value = datas;
      } else {
        parentData.value = data;
      }
    } else {
      parentData.value = {};
    }
    editVisible.value = true;
    await nextTick();
    createModalRef.value.openModal();
  };

  /**
   * 执行编辑
   * @param data 参数
   */
  const handleEdit = async (data: any) => {
    cityId.value = data.id;
    parentData.value = findParentNode(lists.value, data.pid);
    editVisible.value = true;
    await nextTick();
    createModalRef.value.openModal();
  };

  /**
   * 执行删除
   * @param row 参数
   */
  const handleDelete = async (row: any) => {
    dialog.warning({
      title: '提示',
      content: '确定要删除？',
      positiveText: '确定',
      negativeText: '取消',
      onPositiveClick: async () => {
        await cityDelete(row.id);
        message.success('删除成功');
        refreshDataList();
      },
    });
  };

  const getChild = async (row: Record<string, unknown>) => {
    expandKeys.value.push(row.areaCode);
    return new Promise<void>(async (resolve) => {
      const data = await getCityByList(row.areaCode);
      data.map((item) => {
        item.isLeaf = item.level == 3 ? true : false;
      });
      row.children = data;
      resolve();
    });
  };

  /**
   * 根据子节点找到父节点
   * @param nodes 节点
   * @param targetId 目标节点ID
   */
  const findParentNode = (nodes, targetId) => {
    for (let node of nodes) {
      if (node.id == targetId) {
        return node;
      }
      if (node.children && node.children.length > 0) {
        const result = findParentNode(node.children, targetId);
        if (result) {
          return node;
        }
      }
    }
  };

  /**
   * 钩子函数
   */
  onMounted(() => {
    loadDataTable();
  });
</script>

<style scoped></style>
