<!-- 编辑弹窗 -->
<template>
  <a-form
    :label-col="{ md: { span: 6 }, sm: { span: 4 }, xs: { span: 24 } }"
    :wrapper-col="{ md: { span: 18 }, sm: { span: 20 }, xs: { span: 24 } }"
  >
    <a-row :gutter="16">
      <a-col :md="12" :sm="24" :xs="24">
        <a-form-item label="应用分类" v-bind="validateInfos.appType">
          <a-select
            optionFilterProp="label"
            placeholder="请选择应用分类"
            allow-clear
            v-model:value="form.appType"
          >
            <template v-for="item in appTypeDict">
              <a-select-option :value="item.value">{{ item.label }}</a-select-option>
            </template>
          </a-select>
        </a-form-item>
        <a-form-item label="应用名称" v-bind="validateInfos.appName">
          <a-input
            allow-clear
            placeholder="请输入应用名称"
            v-model:value="form.appName"
          />
        </a-form-item>
        <a-form-item label="应用入口" v-bind="validateInfos.component">
          <a-input
            allow-clear
            placeholder="/dashboard/workplace"
            v-model:value="form.component"
          />
        </a-form-item>
      </a-col>
      <a-col :md="12" :sm="24" :xs="24">
        <a-form-item label="应用标识" v-bind="validateInfos.appCode">
          <a-input
            allow-clear
            placeholder="goods"
            v-model:value="form.appCode"
          />
        </a-form-item>
        <a-form-item label="授权价格" v-bind="validateInfos.price">
          <a-input
            allow-clear
            placeholder="授权价格"
            v-model:value="form.price"
          />
        </a-form-item>
        <a-form-item label="排序号" v-role="'superAdmin'" v-bind="validateInfos.sortNumber">
          <a-input-number
            :min="0"
            :max="99999"
            class="ele-fluid"
            placeholder="请输入排序号"
            v-model:value="form.sortNumber"
          />
        </a-form-item>
      </a-col>
    </a-row>
    <a-form-item
      label="应用简介"
      v-bind="validateInfos.comments"
      :label-col="{ md: { span: 3 }, sm: { span: 4 }, xs: { span: 24 } }"
      :wrapper-col="{ md: { span: 21 }, sm: { span: 20 }, xs: { span: 24 } }"
    >
      <a-textarea
        :rows="4"
        :maxlength="200"
        placeholder="请输入应用简介"
        v-model:value="form.comments"
      />
    </a-form-item>
    <div style="margin-bottom: 22px">
      <a-divider />
    </div>
    <a-row :gutter="16">
      <a-col :md="12" :sm="24" :xs="24">
        <a-form-item label="应用图标" v-bind="validateInfos.appIcon">
          <ele-icon-picker
            v-model:value="form.appIcon"
            allow-clear
            placeholder="请选择图标"
            :disabled="form.appType === 1"
            :data="iconData"
          >
            <template #icon="{ icon }">
              <component :is="icon"/>
            </template>
          </ele-icon-picker>
        </a-form-item>
        <a-form-item label="下载地址" v-bind="validateInfos.downUrl">
          <a-input
            allow-clear
            placeholder="模块代码下载地址"
            v-model:value="form.downUrl"
          />
        </a-form-item>
      </a-col>
      <a-col :md="12" :sm="24" :xs="24">
        <a-form-item label="当前版本" v-bind="validateInfos.edition">
          <a-select
            optionFilterProp="label"
            placeholder="请选择版本"
            allow-clear
            v-model:value="form.edition"
          >
            <a-select-option value="正式版">正式版</a-select-option>
            <a-select-option value="开发版">开发版</a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item label="应用状态">
          <a-switch
            checked-children="启用"
            un-checked-children="禁用"
            :checked="form.status === 0"
            @update:checked="updateHideValue"
          />
          <a-tooltip
            title="禁用后提示：模块维护中"
          >
            <question-circle-outlined
              style="vertical-align: -4px; margin-left: 16px"
            />
          </a-tooltip>
        </a-form-item>
      </a-col>
    </a-row>
    <div style="margin-bottom: 22px">
      <a-divider />
    </div>
    <a-button
      type="primary"
      class="ele-btn-icon"
      @click="save"
    >
      <span>保存</span>
    </a-button>
  </a-form>
</template>

<script lang="ts" setup>
import {ref, reactive, watch} from 'vue';
import {Form, message} from 'ant-design-vue';
import type {RuleObject} from 'ant-design-vue/es/form';
import iconData from 'ele-admin-pro/es/ele-icon-picker/icons';
import {assignObject, isExternalLink} from 'ele-admin-pro';
import {addApp, updateApp} from '@/api/dashboard/appstore';
import type {App} from '@/api/dashboard/appstore/model';
import {ItemType} from "ele-admin-pro/es/ele-image-upload/types";
import {uploadFile} from "@/api/system/file";
import {getDictionaryOptions} from "@/utils/common";

const useForm = Form.useForm;

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

const props = defineProps<{
  // 修改回显的数据
  data?: App | null;
  // 应用id
  appId?: number | 0;
}>();

// 是否是修改
const isUpdate = ref(false);
// 提交状态
const loading = ref(false);
const icon = ref('');
const appTypeDict = getDictionaryOptions('appstoreType');
// 编辑器内容，双向绑定
const content = ref('');

// 表单数据
const form = reactive<App>({
  // 应用id
  appId: undefined,
  // 应用名称
  appName: '',
  // 上级id, 0是顶级
  parentId: 0,
  // 应用编号
  appCode: '',
  // 应用图标
  appIcon: '',
  // 应用类型
  appType: undefined,
  // 应用地址
  appUrl: '',
  // 下载地址
  downUrl: '',
  // 应用包名
  packageName: '',
  // 点击次数
  clicks: '',
  // 安装次数
  installs: '',
  // 应用介绍
  content: '',
  // 开发者(个人)
  developer: '官方',
  // 页面路径
  component: undefined,
  // 软件授权价格
  price: '',
  // 评分
  score: '',
  // 星级
  star: '',
  // 排序
  sortNumber: 100,
  // 备注
  comments: '',
  // 权限标识
  authority: '',
  // 打开位置
  target: '',
  // 是否隐藏, 0否, 1是(仅注册路由不显示在左侧菜单)
  hide: undefined,
  // 菜单侧栏选中的path
  active: '',
  // 其它路由元信息
  meta: '',
  // 版本
  edition: '开发版',
  // 版本号
  version: 'v1.0',
  // 创建时间
  createTime: '',
  // 状态
  status: 1,
  // 发布者
  userId: undefined,
  // 发布者昵称
  nickname: ''
});

// 表单验证规则
const rules = reactive({
  appName: [
    {
      required: true,
      type: 'string',
      message: '请输入应用名称',
      trigger: 'blur'
    }
  ],
  component: [
    {
      required: true,
      type: 'string',
      message: '请输入组件路径',
      trigger: 'blur'
    }
  ],
  appType: [
    {
      required: true,
      type: 'string',
      message: '请选择应用分类',
      trigger: 'blur'
    }
  ],
  appCode: [
    {
      required: true,
      type: 'string',
      message: '请输入应用标识(英文)',
      trigger: 'blur'
    }
  ],
  comments: [
    {
      required: true,
      type: 'string',
      message: '请输入应用简介',
    }
  ],
  sortNumber: [
    {
      required: true,
      type: 'number',
      message: '请输入排序号',
    }
  ],
  price: [
    {
      required: true,
      message: '请输入软件授权价格',
      trigger: 'blur'
    }
  ],
  meta: [
    {
      type: 'string',
      trigger: 'blur',
      validator: async (_rule: RuleObject, value: string) => {
        if (value) {
          const msg = '请输入正确的JSON格式';
          try {
            const obj = JSON.parse(value);
            if (typeof obj !== 'object' || obj === null) {
              return Promise.reject(msg);
            }
          } catch (_e) {
            return Promise.reject(msg);
          }
        }
        return Promise.resolve();
      }
    }
  ]
});

const {resetFields, validate, validateInfos} = useForm(form, rules);

/* 保存编辑 */
const save = () => {
  validate()
    .then(() => {
      loading.value = true;
      const appForm = {
        ...form,
        parentId: form.parentId || 0,
        content: content.value
      };
      const saveOrUpdate = isUpdate.value ? updateApp : addApp;
      saveOrUpdate(appForm)
        .then((msg) => {
          loading.value = false;
          message.success(msg);
          updateVisible(false);
          emit('done');
        })
        .catch((e) => {
          loading.value = false;
          message.error(e.message);
        });
    })
    .catch(() => {
    });
};

const onUpload = (d: ItemType) => {
  uploadFile(<File>d.file)
    .then((result) => {
      form.appIcon = result.path;
      message.success('上传成功');
    })
    .catch((e) => {
      message.error(e.message);
    });
};

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

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

const reload = () => {
  if (props.data) {
    const isExternal = isExternalLink(props.data.path);
    const isInner = isExternalLink(props.data.component);
    content.value = String(props.data.content);
    form.price = props.data.price;
    assignObject(form, {
      ...props.data,
      openType: isExternal ? 2 : isInner ? 1 : 0
    });
    isUpdate.value = true;
  } else {
    isUpdate.value = false;
  }
}

if( props.appId ) {
  reload();
}

watch(
  () => props.data?.appId,
  (data) => {
    if (data) {
      reload();
    } else {
      resetFields();
    }
  }
);
</script>
<script lang="ts">
import * as icons from '@ant-design/icons-vue';

export default {
  components: icons
};
</script>
