<template>
  <el-dialog
      v-model="props.visible"
      :title="props.menuId?'编辑':'新增'"
      width="600"
      :close-on-click-modal="false"
      :before-close="dialogClose"
  >
    <el-form
        ref="formRef"
        :model="formData"
        label-width="80px"
    >
      <el-form-item label="菜单类型" prop="type" required>
        <el-radio-group v-model="formData.type">
          <el-radio :label="0">菜单</el-radio>
          <el-radio :label="1">按钮</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item
          label="父级菜单"
          prop="parentId"
          :rules="{ required: true, message: '请选择父级菜单', trigger: 'change' }"
      >
        <el-tree-select
            class="flex-1"
            v-model="formData.parentId"
            :data="menuOptions"
            clearable
            node-key="id"
            :props="{
              label: 'name',
            }"
            :default-expand-all="true"
            placeholder="请选择父级菜单"
            check-strictly
        />
      </el-form-item>
      <el-form-item
          label="菜单名称"
          prop="name"
          :rules="{ required: true, message: '请输入菜单名称', trigger: 'blur' }"
      >
        <el-input
            v-model="formData.name"
            placeholder="请输入菜单名称"
            clearable
        />
      </el-form-item>
      <el-form-item
          v-if="formData.type ==0"
          label="菜单图标"
          prop="icon"
      >
        <IconPicker class="flex-1" v-model="formData.icon"/>
      </el-form-item>
      <el-form-item
          label="打开方式"
          prop="target"
          v-if="formData.type==0"
      >
        <div>
          <el-radio-group v-model="formData.target">
            <el-radio :label="0">组件</el-radio>
            <el-radio :label="1">内链</el-radio>
            <el-radio :label="2">外链</el-radio>
          </el-radio-group>
          <div class="form-tips">
            选择外链，则新窗口打开页面
          </div>
        </div>
      </el-form-item>
      <el-form-item
          v-if="formData.type == 0 && (formData.target ==0 || formData.target ==1)"
          label="路由路径"
          prop="path"
          :rules="{ required: true, message: '请输入路由路径', trigger: 'blur' }"
      >
        <div class="flex-1">
          <el-input
              v-model="formData.path"
              placeholder="请输入路由路径"
              clearable
          />
          <div class="form-tips">
            访问的路由地址
          </div>
        </div>
      </el-form-item>
      <el-form-item
          v-if="formData.type==0"
          label="组件路径"
          prop="component"
          :rules="{ required: true, message: '请输入组件路径', trigger: 'blur' }"
      >
        <div class="flex-1">
          <el-autocomplete
              style="width: 100%"
              v-model="formData.component"
              :fetch-suggestions="querySearch"
              clearable
              placeholder="请输入组件路径"
          />
          <div class="form-tips">
            访问的组件路径，如：`permission/admin/index`，默认在`views`目录下，如外网地址需内链访问则以`http(s)://`开头
          </div>
        </div>
      </el-form-item>
      <el-form-item
      v-if="formData.target ==0"
          label="权限字符"
          prop="permission"
      >
        <div class="flex-1">
          <el-input
              v-model="formData.permission"
              placeholder="请输入权限字符"
              clearable
          />
          <div class="form-tips">
            将作为server端API验权使用，如`system:admin:list`，请谨慎修改
          </div>
        </div>
      </el-form-item>
      <el-form-item
          v-if="formData.type ==0"
          label="是否显示"
          prop="hide"
          required
      >
        <div>
          <el-radio-group v-model="formData.hide">
            <el-radio :label="0">显示</el-radio>
            <el-radio :label="1">隐藏</el-radio>
          </el-radio-group>
          <div class="form-tips">
            选择隐藏则路由将不会出现在侧边栏，但仍然可以访问
          </div>
        </div>
      </el-form-item>
      <el-form-item
          v-if="formData.type ==0"
          label="菜单状态"
          prop="status"
          required
      >
        <div>
          <el-radio-group v-model="formData.status">
            <el-radio :label="0">正常</el-radio>
            <el-radio :label="1">停用</el-radio>
          </el-radio-group>
          <div class="form-tips">
            选择停用则路由将不会出现在侧边栏，也不能被访问
          </div>
        </div>
      </el-form-item>
      <el-form-item label="菜单排序" prop="sort">
        <div>
          <el-input-number v-model="formData.sort" :max="9999"/>
          <div class="form-tips">数值越小越排前</div>
        </div>
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogClose">取消</el-button>
        <el-button :loading="subLoading" type="primary" @click="submit">
          确定
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>
<script lang="ts" setup>
import type {FormInstance} from "element-plus";
import { menuAdd,menuUpdate,getMenuList,getMenuDetail } from '@/api/system/menu';
import {onMounted, reactive, ref, shallowRef} from "vue";
import {getModulesKey} from "@/router";
import {arrayToTree, treeToArray,message,buildTree} from "@/utils/auth";
import {useLockFn} from "@/utils/useLockFn";
import IconPicker from "@/components/icon/picker.vue";
const props = defineProps({
  visible: {
    type: Boolean,
    required: true,
    default: false
  },
  menuId: {
    type: Number,
    required: true,
    default: 0
  },
  pid: {
    type: Number,
    default: 0
  }
});
const emit = defineEmits(["success","update:visible"]);
const formRef = shallowRef<FormInstance>();

const componentsOptions = ref(getModulesKey());
const querySearch = (queryString: string, cb: any) => {
  const results = queryString
      ? componentsOptions.value.filter((item) =>
          item.toLowerCase().includes(queryString.toLowerCase())
      )
      : componentsOptions.value;
  cb(results.map((item) => ({value: item})));
};

const formData = reactive({
  id: "",
  //父级id
  parentId: 0,
  //类型
  type: 0,
  //图标
  icon: "",
  //名称
  name: "",
  //排序号
  sort: 0,
  // 路由路径
  path: "",
  //权限链接
  permission: "",
  //前端组件
  component: "",
  //是否显示 0=显示， 1=不显示
  hide: 0,
  //是否外链 0=不是， 1=是
  target:0,
  status:0
});

const dialogClose = () => {
  emit("update:visible", false);
};

const menuOptions = ref<any[]>([]);

const getMenu = async () => {
  const data: any = await getMenuList();
  const menu: any = {id: 0, name: "顶级", children: []};
  const lists = buildTree(data)
  menu.children = arrayToTree(
    treeToArray(lists).filter((item) => item.type ==0)
  );
  menuOptions.value.push(menu);
};

const handleSubmit = async () => {
    await formRef.value?.validate();
    props.menuId ? await menuUpdate(formData) : await menuAdd(formData);
    message("操作成功");
    emit("update:visible", false);
    emit("success");
};

const { isLock:subLoading,lockFn: submit } = useLockFn(handleSubmit);


const setFormData = (data: Record<any, any>) => {
  for (const key in formData) {
    if (data[key] != null && data[key] != undefined) {
      formData[key] = data[key];
    }
  }
};

const getDetail = async () => {
  const data = await getMenuDetail(
    props.menuId
  );
  setFormData(data);
};

const handleClose = () => {
  emit("close");
};



onMounted(() => {
  getMenu()
  if (props.menuId) {
    getDetail()
  }else{
    formData.parentId=props.pid
  }
});
</script>
