<template>
  <div>
    <n-grid
      class="mt-4"
      cols="1 s:1 m:1 l:3 xl:3 2xl:3"
      responsive="screen"
      :x-gap="12"
    >
      <n-gi span="1">
        <n-card :segmented="{ content: true }" :bordered="false" size="small">
          <template #header>
            <n-space>
              <n-dropdown
                trigger="hover"
                @select="selectAddMenu"
                :options="addMenuOptions"
              >
                <n-button type="info" ghost icon-placement="right">
                  添加菜单
                  <template #icon>
                    <div class="flex items-center">
                      <n-icon size="14">
                        <DownOutlined />
                      </n-icon>
                    </div>
                  </template>
                </n-button>
              </n-dropdown>
              <n-button
                type="info"
                ghost
                icon-placement="left"
                @click="packHandle"
              >
                全部{{ expandedKeys.length ? "收起" : "展开" }}
                <template #icon>
                  <div class="flex items-center">
                    <n-icon size="14">
                      <AlignLeftOutlined />
                    </n-icon>
                  </div>
                </template>
              </n-button>
            </n-space>
          </template>
          <div class="w-full menu">
            <n-input
              type="input"
              v-model:value="pattern"
              placeholder="输入菜单名称搜索"
            >
              <template #suffix>
                <n-icon size="18" class="cursor-pointer">
                  <SearchOutlined />
                </n-icon>
              </template>
            </n-input>
            <div class="py-3 menu-list">
              <template v-if="loading">
                <div class="flex items-center justify-center py-4">
                  <n-spin size="medium" />
                </div>
              </template>
              <template v-else>
                <!--   label-field="name"
                  key-field="path" -->
                <n-tree
                  block-line
                  cascade
                  checkable
                  :virtual-scroll="true"
                  :pattern="pattern"
                  :data="treeData"
                  :expandedKeys="expandedKeys"
                  style="max-height: 650px; overflow: hidden"
                  @update:selected-keys="selectedTree"
                  @update:expanded-keys="onExpandedKeys"
                />
              </template>
            </div>
          </div>
        </n-card>
      </n-gi>
      <n-gi span="2">
        <n-card :segmented="{ content: true }" :bordered="false" size="small">
          <template #header>
            <n-space>
              <n-icon size="18">
                <FormOutlined />
              </n-icon>
              <span
                >编辑菜单{{ treeItemTitle ? `：${treeItemTitle}` : "" }}</span
              >
            </n-space>
          </template>
          <n-alert type="info" closable>
            从菜单列表选择一项后，进行编辑</n-alert
          >
          <n-form
            :model="formParams"
            :rules="rules"
            ref="formRef"
            label-placement="left"
            :label-width="100"
            v-if="isEditMenu"
            class="py-4"
          >
            <n-form-item label="路径" path="path">
              <n-input
                placeholder="请输入路径"
                v-model:value="formParams.path"
              />
            </n-form-item>
            <n-form-item label="标题" path="label">
              <n-input
                placeholder="请输入标题"
                v-model:value="formParams.meta.title"
              />
            </n-form-item>
            <n-form-item label="组件" path="path">
              <n-input
                placeholder="请输入组件"
                v-model:value="formParams.component"
              />
            </n-form-item>
            <n-form-item label="组件名称" path="subtitle">
              <n-input
                placeholder="请输入组件名称"
                v-model:value="formParams.name"
              />
            </n-form-item>
            <n-form-item label="菜单图标" path="subtitle">
              <n-input
                placeholder="请输入组件名称"
                v-model:value="formParams.meta.icon"
              />
            </n-form-item>
            <n-form-item label="嵌套地址" path="subtitle">
              <n-input
                placeholder="请输入组件名称"
                v-model:value="formParams.meta.frameSrc"
              />
            </n-form-item>
            <n-form-item label="固定" path="subtitle">
              <n-input
                placeholder="请输入组件名称"
                v-model:value="formParams.meta.affix"
              />
            </n-form-item>
            <n-form-item label="是否根路由" path="subtitle">
              <n-input
                placeholder="请输入组件名称"
                v-model:value="formParams.meta.isRoot"
              />
            </n-form-item>
            <n-form-item label="是否缓存" path="subtitle">
              <n-input
                placeholder="请输入组件名称"
                v-model:value="formParams.meta.keepAlive"
              />
            </n-form-item>
            <n-form-item label="是否禁用" path="subtitle">
              <n-input
                placeholder="请输入组件名称"
                v-model:value="formParams.meta.disabled"
              />
            </n-form-item>
            <n-form-item label="计算根路由" path="subtitle">
              <n-input
                placeholder="请输入组件名称"
                v-model:value="formParams.meta.alwaysShow"
              />
            </n-form-item>
            <n-form-item label="是否隐藏" path="subtitle">
              <n-input
                placeholder="请输入组件名称"
                v-model:value="formParams.meta.hidden"
              />
            </n-form-item>
            <n-form-item label="高亮菜单" path="subtitle">
              <n-input
                placeholder="请输入组件名称"
                v-model:value="formParams.meta.activeMenu"
              />
            </n-form-item>

            <n-form-item label="菜单权限" path="auth">
              <n-input
                placeholder="请输入权限，多个权限用，分割"
                v-model:value="formParams.meta.permissions"
              />
            </n-form-item>

            <n-form-item label="排序" path="auth">
              <n-input
                placeholder="请输入权限，多个权限用，分割"
                v-model:value="formParams.meta.sort"
              />
            </n-form-item>
            <n-form-item path="auth" style="margin-left: 100px">
              <n-space>
                <n-button
                  type="primary"
                  :loading="subLoading"
                  @click="formSubmit"
                  >保存修改</n-button
                >
                <n-button @click="handleReset">重置</n-button>
                <n-button @click="handleDel">删除</n-button>
              </n-space>
            </n-form-item>
          </n-form>
        </n-card>
      </n-gi>
    </n-grid>
    <CreateDrawer
      ref="createDrawerRef"
      :title="drawerTitle"
      :parentId="parentId"
    />
  </div>
</template>
<script lang="ts" setup>
import {
  DownOutlined,
  AlignLeftOutlined,
  SearchOutlined,
  FormOutlined,
} from "@vicons/antd";
import { getTreeItem } from "@/utils";
import CreateDrawer from "./CreateDrawer.vue";
import { getTree } from "@/api/system/menu";
interface TreeNode {
  key: string;
  children?: TreeNode[];
}

const rules = {
  label: {
    required: true,
    message: "请输入标题",
    trigger: "blur",
  },
  path: {
    required: true,
    message: "请输入路径",
    trigger: "blur",
  },
};

const formRef: any = ref(null);
const createDrawerRef = ref();

let treeItemKey = ref([]);
let parentId = ref(0);

let expandedKeys = ref([]);

const treeData = ref([]);

const loading = ref(false);
const subLoading = ref(false);
const isEditMenu = ref(false);
const treeItemTitle = ref("");
const pattern = ref("");
const drawerTitle = ref("");

const isAddSon = computed(() => {
  return !treeItemKey.value.length;
});

const addMenuOptions = ref([
  {
    label: "添加顶级菜单",
    key: "home",
    disabled: false,
  },
  {
    label: "添加子菜单",
    key: "son",
    disabled: isAddSon,
  },
]);

const formParams = reactive({
  id: null,
  parentId: null,
  name: "",
  path: "",
  component: "",
  redirect: "",
  meta: {
    title: "",
    sort: null,
    icon: "",
    keepAlive: false,
    hidden: false,
    disabled: false,
    alwaysShow: false,
    activeMenu: "",
    isRoot: false,
    affix: false,
    frameSrc: "",
    permissions: null,
  },
});

function selectAddMenu(key: string) {
  drawerTitle.value =
    key === "home" ? "添加顶栏菜单" : `添加子菜单：${treeItemTitle.value}`;
  openCreateDrawer();
}

function openCreateDrawer() {
  createDrawerRef.value.openDrawer();
}

function selectedTree(keys) {
  if (keys.length) {
    const treeItem = getTreeItem(unref(treeData), keys[0]);

    treeItemKey.value = keys;
    treeItemTitle.value = treeItem.label;
    parentId.value = treeItem.id;
    Object.assign(formParams, treeItem);
    console.log(formParams);

    isEditMenu.value = true;
  } else {
    isEditMenu.value = false;
    treeItemKey.value = [];
    treeItemTitle.value = "";
    formParams.parentId = null;
  }
}

function handleDel() {}

function handleReset() {
  const treeItem = getTreeItem(unref(treeData), treeItemKey.value[0]);
  Object.assign(formParams, treeItem);
}

function formSubmit() {
  formRef.value.validate((errors: boolean) => {
    if (!errors) {
      console.log(formParams);
    } else {
    }
  });
}

function packHandle() {
  if (expandedKeys.value.length) {
    expandedKeys.value = [];
  } else {
    expandedKeys.value = unref(treeData).map(
      (item: any) => item.key as string
    ) as [];
  }
}

function mapTreeData(data) {
  return data.map((ele) => ({
    ...ele,
    key: ele.name,
    label: ele.meta.title,
    children: ele.children ? mapTreeData(ele.children) : undefined,
  }));
}

function getKeys(data: TreeNode[]): string[] {
  const keys: string[] = [];

  function extractKeys(node: TreeNode) {
    keys.push(node.key);
    if (node.children) {
      node.children.forEach(extractKeys);
    }
  }

  data.forEach(extractKeys);
  return keys;
}

onMounted(async () => {
  try {
    loading.value = true;
    const treeMenuList = await getTree();
    const res = mapTreeData(treeMenuList.data);

    Object.assign(formParams, getKeys(res));
    treeData.value = res;

    console.log(treeData.value);
  } finally {
    loading.value = false;
  }
});

function onExpandedKeys(keys) {
  expandedKeys.value = keys;
}
</script>
