<!-- 编辑弹窗 -->
<template>
  <ele-modal
    :width="740"
    :visible="visible"
    :confirm-loading="loading"
    :title="isUpdate ? '修改导航' : '新建导航'"
    :body-style="{ paddingBottom: '8px' }"
    @update:visible="updateVisible"
    @ok="save"
  >
    <a-form
      ref="formRef"
      :model="form"
      :rules="rules"
      :label-col="styleResponsive ? { md: 6, sm: 4, xs: 24 } : { flex: '90px' }"
      :wrapper-col="
        styleResponsive ? { md: 18, sm: 20, xs: 24 } : { flex: '1' }
      "
    >
      <a-row :gutter="16">
        <a-col
          v-bind="styleResponsive ? { md: 12, sm: 24, xs: 24 } : { span: 12 }"
        >
          <a-form-item label="上级分类" name="parentId">
            <a-tree-select
              allow-clear
              :tree-data="navigationList"
              tree-default-expand-all
              placeholder="请选择上级分类"
              :value="form.parentId || undefined"
              :dropdown-style="{ maxHeight: '360px', overflow: 'auto' }"
              @update:value="(value?: number) => (form.parentId = value)"
            />
          </a-form-item>
          <a-form-item label="模型" name="type">
            <a-select
              ref="select"
              v-model:value="form.type"
              style="width: 253px"
              @change="onType"
            >
              <a-select-option :value="1">单页内容</a-select-option>
              <a-select-option :value="2">新闻分类</a-select-option>
              <a-select-option :value="3">新闻详情</a-select-option>
              <a-select-option :value="4">表单设计</a-select-option>
              <a-select-option :value="5">知识文档</a-select-option>
              <a-select-option :value="6">商品分类</a-select-option>
              <a-select-option :value="7">商品详情</a-select-option>
              <a-select-option :value="9">外部链接</a-select-option>
              <a-select-option :value="0">通用模型</a-select-option>
            </a-select>
          </a-form-item>
          <a-form-item label="选择页面" v-if="form.type == 1">
            <SelectDesign
              :placeholder="`请选择页面`"
              v-model:value="form.pageName"
              @done="choosePageId"
            />
          </a-form-item>
          <a-form-item label="选择列表" v-if="form.type == 2">
            <SelectArticleCategory
              :placeholder="`请选择列表`"
              v-model:value="form.pageName"
              @done="chooseArticleCategoryId"
            />
          </a-form-item>
          <a-form-item label="选择文章" v-if="form.type == 3">
            <SelectArticle
              :placeholder="`请选择文章`"
              v-model:value="form.pageName"
              @done="chooseArticle"
            />
          </a-form-item>
          <a-form-item label="选择表单" v-if="form.type == 4">
            <SelectForm
              :placeholder="`请选择表单`"
              v-model:value="form.pageName"
              @done="chooseForm"
            />
          </a-form-item>
          <a-form-item label="选择文档" v-if="form.type == 5">
            <SelectDocsBook
              :placeholder="`请选择知识文档`"
              v-model:value="form.title"
              @done="chooseDocsBook"
            />
          </a-form-item>
          <a-form-item label="选择分类" v-if="form.type == 6">
            <SelectGoodsCategory
              :placeholder="`请选择商品分类`"
              v-model:value="form.title"
              @done="chooseGoodsCategory"
            />
          </a-form-item>
          <a-form-item label="选择商品详情" v-if="form.type == 7">
            <SelectDocsBook
              :placeholder="`请选择商品详情`"
              v-model:value="form.title"
              @done="chooseGoods"
            />
          </a-form-item>
          <a-form-item
            v-if="form.type == 9 || form.type == 0"
            :label="form.type == 9 ? '链接地址' : '路由地址'"
            name="path"
            :extra="form.path ? `${form.path}` : ''"
          >
            <a-input
              allow-clear
              :placeholder="form.type == 9 ? '请输入链接地址' : '/about'"
              v-model:value="form.path"
              @pressEnter="save"
            />
          </a-form-item>
          <a-form-item
            label="组件路径"
            name="component"
            v-if="form.type == 0"
            :extra="form.component ? `@/views${form.component}` : ''"
          >
            <a-input
              allow-clear
              placeholder="/about/index"
              v-model:value="form.component"
              @pressEnter="save"
            />
          </a-form-item>
          <a-form-item label="菜单图标" name="icon">
            <SelectFile
              :placeholder="`请选择图片`"
              :limit="1"
              :data="images"
              :width="40"
              @done="chooseFile"
              @del="onDeleteItem"
            />
          </a-form-item>
        </a-col>
        <a-col
          v-bind="styleResponsive ? { md: 12, sm: 24, xs: 24 } : { span: 12 }"
        >
          <a-form-item label="菜单名称" name="title">
            <a-input
              allow-clear
              placeholder="请输入菜单名称"
              v-model:value="form.title"
              @pressEnter="save"
            />
          </a-form-item>
          <a-form-item label="排序号" name="sortNumber">
            <a-input-number
              :min="0"
              :max="99999"
              class="ele-fluid"
              placeholder="请输入排序号"
              v-model:value="form.sortNumber"
              @pressEnter="save"
            />
          </a-form-item>
          <a-form-item label="位置" name="position">
            <a-select
              ref="select"
              v-model:value="form.position"
              style="width: 253px"
            >
              <a-select-option :value="1">顶部</a-select-option>
              <a-select-option :value="2">底部</a-select-option>
            </a-select>
          </a-form-item>
          <a-form-item label="是否展示" name="hide">
            <a-switch
              checked-children="是"
              un-checked-children="否"
              :checked="form.hide === 0"
              @update:checked="updateHideValue"
            />
          </a-form-item>
        </a-col>
      </a-row>
      <div style="margin-bottom: 22px">
        <a-divider />
      </div>
      <a-form-item
        label="备注"
        name="comments"
        :label-col="
          styleResponsive ? { md: 3, sm: 4, xs: 24 } : { flex: '90px' }
        "
        :wrapper-col="
          styleResponsive ? { md: 21, sm: 20, xs: 24 } : { flex: '1' }
        "
      >
        <a-textarea
          :rows="4"
          :maxlength="200"
          placeholder="请输入备注信息"
          v-model:value="form.comments"
        />
      </a-form-item>
    </a-form>
  </ele-modal>
</template>

<script lang="ts" setup>
  import { ref, reactive, watch } from 'vue';
  import { message } from 'ant-design-vue/es';
  import type { FormInstance, Rule } from 'ant-design-vue/es/form';
  import { storeToRefs } from 'pinia';
  import { useThemeStore } from '@/store/modules/theme';
  import useFormData from '@/utils/use-form-data';
  import { Navigation } from '@/api/cms/navigation/model';
  import {
    addNavigation,
    updateNavigation,
    checkExistence
  } from '@/api/cms/navigation';
  import { Design } from '@/api/cms/design/model';
  import { removeSiteInfoCache } from '@/api/cms/website';
  import { isChinese, isUrl } from 'ele-admin-pro';
  import { ArticleCategory } from '@/api/cms/category/model';
  import { Article } from '@/api/cms/article/model';
  import { Form } from '@/api/cms/form/model';
  import { DocsBook } from '@/api/cms/docs-book/model';
  import { Goods } from '@/api/shop/goods/model';
  import {GoodsCategory} from "@/api/shop/goodsCategory/model";
  import {ItemType} from "ele-admin-pro/es/ele-image-upload/types";
  import {FileRecord} from "@/api/system/file/model";

  // 是否开启响应式布局
  const themeStore = useThemeStore();
  const { styleResponsive } = storeToRefs(themeStore);

  const emit = defineEmits<{
    (e: 'done'): void;
    (e: 'update:visible', visible: boolean): void;
  }>();

  const props = defineProps<{
    // 弹窗是否打开
    visible: boolean;
    // 修改回显的数据
    data?: Navigation | null;
    // 上级分类id
    parentId?: number;
    // 位置
    position?: number;
    // 全部导航数据
    navigationList: Navigation[];
  }>();

  //
  const formRef = ref<FormInstance | null>(null);
  // 是否是修改
  const isUpdate = ref(false);
  // 提交状态
  const loading = ref(false);
  // 已上传数据
  const images = ref<ItemType[]>([]);

  // 表单数据
  const { form, resetFields, assignFields } = useFormData<Navigation>({
    navigationId: undefined,
    type: 1,
    title: '',
    parentId: 0,
    path: '',
    component: '',
    sortNumber: 100,
    hide: 0,
    position: 1,
    status: 0,
    pageId: 0,
    articleCategoryId: 0,
    articleId: 0,
    pageName: '',
    isMpWeixin: false
  });

  // 表单验证规则
  const rules = reactive<Record<string, Rule[]>>({
    type: [
      {
        required: true,
        message: '请选择导航类型',
        type: 'number',
        trigger: 'blur'
      }
    ],
    title: [
      {
        required: true,
        message: '请输入菜单名称',
        type: 'string',
        trigger: 'blur'
      }
    ],
    path: [
      {
        required: true,
        type: 'string',
        trigger: 'blur',
        validator: (_rule: Rule, value: string) => {
          return new Promise<void>((resolve, reject) => {
            if (!value) {
              return reject('请填写路由地址');
            }
            if (form.type == 9) {
              if (!isUrl(value)) {
                return reject('请输入正确的网址');
              }
              resolve();
            }
            if (form.type == 1) {
              if (form.pageId == 0) {
                return reject('请选择页面');
              }
            }
            if (value.charAt(0) != '/') {
              return reject('请填写路由地址，必须是以"/"开头的英文字母+数字');
            }
            if (isChinese(value)) {
              return reject('不支持中文');
            }
            // let zg = /^[0-9a-zA-Z]*$/;
            // if (!zg.test(value)) {
            //   return reject('仅支持字母和数字');
            // }
            checkExistence('path', value, form.navigationId)
              .then((msg) => {
                return reject(msg);
              })
              .catch(() => {
                resolve();
              });
          });
        }
      }
    ],
    sortNumber: [
      {
        required: true,
        message: '请输入排序号',
        type: 'number',
        trigger: 'blur'
      }
    ],
    status: [
      {
        required: true,
        message: '请设置是否展示',
        type: 'number',
        trigger: 'blur'
      }
    ]
  });

  const onType = (index: number) => {
    if (index == 0) {
      form.path = '/';
      form.component = '';
    }
    if (index == 1) {
      form.path = '';
      form.component = '';
    }
    if (index == 2) {
      form.path = '';
      form.component = '';
    }
    if (index == 9) {
      form.path = undefined;
      form.component = '';
    }
  };

  const choosePageId = (data: Design) => {
    form.pageId = data.pageId;
    form.pageName = data.name;
    form.title = data.name;
    form.path = data.path;
    form.component = data.component;
  };

  const chooseArticleCategoryId = (data: ArticleCategory) => {
    form.articleCategoryId = data.categoryId;
    form.pageName = data.title;
    form.title = data.title;
    form.path = '/article/' + data.categoryId;
    form.component = '/article/index';
  };

  const chooseArticle = (data: Article) => {
    form.articleId = data.articleId;
    form.title = data.title;
    form.pageName = data.title;
    form.path = '/a/' + data.articleId;
    form.component = '/article/detail';
  };

  const chooseForm = (data: Form) => {
    form.formId = data.formId;
    form.title = data.name;
    form.pageName = data.name;
    form.path = '/form/' + data.formId;
    form.component = '/form/detail';
  };

  const chooseDocsBook = (data: DocsBook) => {
    form.bookCode = data.code;
    form.title = data.name;
    form.pageName = data.name;
    form.path = '/docs/' + data.code;
    form.component = '/docs/index';
  };

  const chooseGoodsCategory = (data: GoodsCategory) => {
    form.goodsCategoryId = data.categoryId;
    form.title = data.title;
    form.pageName = data.title;
    form.path = '/goods/search?categoryId=' + data.categoryId;
    form.component = '/goods/search';
  };

  const chooseGoods = (data: Goods) => {
    form.goodsId = data.goodsId;
    form.title = data.title;
    form.pageName = data.title;
    form.path = '/goods/detail/' + data.goodsId;
    form.component = '/goods/search';
  };

  const chooseFile = (data: FileRecord) => {
    images.value.push({
      uid: data.id,
      url: data.path,
      status: 'done'
    });
    form.icon = data.path;
  }

  const onDeleteItem = (index: number) => {
    images.value.splice(index,1)
    form.icon = '';
  }


  /* 保存编辑 */
  const save = () => {
    if (!formRef.value) {
      return;
    }
    formRef.value
      .validate()
      .then(() => {
        const navigationForm = {
          ...form
        };
        const saveOrUpdate = isUpdate.value ? updateNavigation : addNavigation;
        saveOrUpdate(navigationForm)
          .then((msg) => {
            message.success(msg);
            updateVisible(false);
            // 清除缓存
            removeSiteInfoCache('SiteInfo:' + localStorage.getItem('TenantId'));
            emit('done');
          })
          .catch((e) => {
            message.error(e.message);
          });
      })
      .catch(() => {});
  };

  /* 更新visible */
  const updateVisible = (value: boolean) => {
    emit('update:visible', value);
  };

  const updateHideValue = (value: boolean) => {
    form.hide = value ? 0 : 1;
  };

  watch(
    () => props.visible,
    (visible) => {
      if (visible) {
        form.position = props.position;
        if (props.data) {
          assignFields({
            ...props.data,
            parentId:
              props.data.parentId === 0 ? undefined : props.data.parentId,
            tempPath: props.data.path
          });
          if (props.data.type == 2) {
            form.pageName = props.data.title;
          }
          isUpdate.value = true;
        } else {
          form.parentId = props.parentId;
          isUpdate.value = false;
        }
      } else {
        resetFields();
        formRef.value?.clearValidate();
      }
    }
  );
</script>

<script lang="ts">
  import * as icons from '@/layout/menu-icons';

  export default {
    components: icons,
    data() {
      return {
        iconData: [
          {
            title: '已引入的图标',
            icons: Object.keys(icons)
          }
        ]
      };
    }
  };
</script>
