<template>
  <div>
    <a-modal
      v-model="visible"
      destroy-on-close
      title="按钮设置"
      :width="700"
      ok-text="保存"
      cancel-text="退出"
      :confirm-loading="confirmLoading"
      @ok="save"
      @cancel="() => (visible = false)"
    >
      <sd-form ref="form" :init-values="initValues">
        <template v-slot="{ model }">
          <template v-for="field in initValues">
            <!-- 满足条件时显示：不使用sd-form-item避免校验进行数据校验(公式保存的是对象，字段为string) -->
            <a-form-model-item
              v-if="field.name === 'displayFormula'"
              v-show="model.buttonType === 'inline'"
              :key="field.name"
              :label="field.caption"
            >
              <sd-formula-exps
                v-model="model[field.name]"
                :fields="formFields"
                :class="$style.formula"
              />
            </a-form-model-item>
            <sd-form-item
              v-else
              :key="field.name"
              :name="field.name"
              :hidden="!!field.sdHidden"
              @change="
                (value) => {
                  if (field.name === 'buttonType') {
                    $refs.form.setFieldValue('displayFormula', undefined)
                    $refs.form.setFieldValue('triggerEvent', undefined)
                  }
                }
              "
            >
              <!-- 触发事件 -->
              <sd-list-picker
                v-if="field.name === 'triggerEvent'"
                v-model="model[field.name]"
                single
                :load-list-data="loadFrontEvents"
              />
              <sd-tree-picker
                v-if="field.name === 'actionPerm'"
                v-model="model[field.name]"
                single
                :render="treeNodeRender"
                :default-expanded-keys="[formId]"
                :load-tree-data="loadPermTreeData"
                :search-tree-data="searchTreeData"
              />
            </sd-form-item>
          </template>
        </template>
      </sd-form>
    </a-modal>
  </div>
</template>

<script>
import axios from '@/common/services/axios-instance'
import { Message } from 'ant-design-vue'
import PageService from '@/common/services/page-service'
import ApplicationService from './application-service'
import components from './_import-components/sd-list-buttons-config-modal-import'

export default {
  name: 'SdListButtonsConfigModal',
  components,
  props: {
    formId: {
      type: String,
      default: '',
    },
    formFields: {
      type: Array,
      default: () => [],
    },
    checkButton: {
      type: Function,
      default: () => Promise.resolve({ code: 1 }),
    },
  },
  data() {
    return {
      visible: false,
      initValues: [
        {
          name: 'buttonName',
          caption: '按钮名称',
          dataType: 'string',
          required: true,
          attr: {},
        },
        {
          name: 'buttonId',
          caption: '按钮编码',
          dataType: 'string',
          required: true,
          attr: {
            regex: /^[a-zA-Z][A-Za-z0-9]*$/,
            regexMessage: '请以字母开头，输入字母或数字',
          },
        },
        {
          name: 'buttonDesc',
          caption: '按钮说明',
          dataType: 'string',
          attr: {},
        },
        {
          name: 'buttonType',
          caption: '按钮类型',
          dataType: 'selectlist',
          attr: {
            defaultValue: 'inline',
            selectListItem: [
              { label: '一般', value: '' },
              { label: '批量', value: 'batch' },
              { label: '行内', value: 'inline' },
            ],
          },
        },
        {
          name: 'isWarn',
          caption: '预警弹窗',
          dataType: 'selectlist',
          attr: {
            defaultValue: '0',
            selectListItem: [
              { label: '是', value: '1' },
              { label: '否', value: '0' },
            ],
          },
        },
        {
          name: 'warnContent',
          caption: '预警内容',
          dataType: 'string',
          attr: {
            displayExpr: '#bean.isWarn == "1"',
          },
        },
        {
          name: 'displayFormula',
          caption: '满足条件时显示',
          dataType: 'string',
          attr: {},
          attrFD: {},
        },
        {
          name: 'triggerEvent',
          caption: '触发事件',
          dataType: 'string',
          required: true,
          attr: {},
        },
        {
          name: 'actionPerm',
          caption: '操作权限',
          dataType: 'string',
        },
      ],
      button: undefined,
      confirmLoading: false,
    }
  },
  methods: {
    show(data) {
      this.button = data
      if (data) {
        ApplicationService.getEventInfo('frontend', { id: data.triggerEvent }).then((res) => {
          const eventName = res.data.methodName
          this.initValues.forEach((f) => {
            if (f.name === 'triggerEvent') {
              f.value = JSON.stringify([{ id: data[f.name], name: eventName }])
            } else {
              f.value = data?.[f.name]
            }
          })
          this.visible = true
        })
      } else {
        this.initValues.forEach((f) => delete f.value)
        this.visible = true
      }
    },
    save() {
      const form = this.$refs.form
      form.validateFields().then((flag) => {
        if (flag) {
          const formData = this.button || {}
          form.getBackendValues().forEach((item) => {
            if (item.name === 'triggerEvent') {
              formData[item.name] = JSON.parse(item.value || '[]')[0]?.id
            } else {
              formData[item.name] = item.value
            }
          })
          this.confirmLoading = true
          // 继续校验按钮配置是否有效
          this.checkButton(formData)
            .then((data) => {
              if (data.code === 1) {
                this.$emit('saved', formData)
                this.visible = false
              } else {
                Message.error(data.message)
              }
            })
            .finally(() => {
              this.confirmLoading = false
            })
        }
      })
    },
    loadFrontEvents() {
      const btnType = this.$refs.form.getFieldValue('buttonType')
      // 行内按钮，选择关联单个数据的事件；批量按钮，选择关联多个数据的事件；普通或主按钮，选择无数据关联的事件
      const associateData =
        btnType === 'inline' ? 'single' : btnType === 'batch' ? 'multiple' : 'none'
      const params = {
        startPosition: 0,
        maxResults: -1,
        expressions: [
          {
            dataType: 'str',
            name: 'associateData',
            op: 'eq',
            stringValue: associateData,
          },
          {
            dataType: 'str',
            name: 'formId',
            op: 'eq',
            stringValue: this.formId,
          },
        ],
        formId: 'onlFormFrontMethod',
        orderBy: 'sortNumber asc,creationTime desc',
        columns: 'id,methodName',
      }
      return PageService.getList(params).then((res) => {
        return (res.data.data || []).map((d) => ({
          id: d.id,
          name: d.methodName,
        }))
      })
    },
    loadPermTreeData(parentId, pNode) {
      // 第一级加载表单
      if (!parentId) {
        return this.loadFormListData()
      } else {
        // 表单下加载表单的权限点
        const params = {
          columns: 'permName,creationTime',
          expressions: [
            {
              name: 'formId',
              op: 'eq',
              dataType: 'str',
              stringValue: parentId,
            },
          ],
          maxResults: -1,
          startPosition: 0,
        }
        const namePrefix = pNode.name + '-'
        return axios.post('api/framework/v1/sec-perm-manage/permList', params).then((res) => {
          return res.data.data.map((item) => {
            return {
              id: item.permCode,
              name: namePrefix + item.permName,
              checkable: true,
              isLeaf: true,
              props: {
                namePrefix,
              },
            }
          })
        })
      }
    },
    loadFormListData(name) {
      const expressions = [
        {
          dataType: 'str',
          name: 'appId',
          op: 'eq',
          stringValue: this.$route.query.appId,
        },
      ]
      if (name) {
        expressions.push({
          dataType: 'str',
          name: 'name',
          op: 'like',
          stringValue: `%${name}%`,
        })
      }
      const params = {
        startPosition: 0,
        maxResults: -1,
        expressions,
        formId: 'weAppModule',
        columns: 'id,name,formId',
      }
      return PageService.getList(params).then((res) => {
        return res.data.data.map((f) => {
          return {
            id: f.formId,
            name: f.name,
            checkable: false,
            isLeaf: false,
          }
        })
      })
    },
    searchTreeData(text) {
      return this.loadFormListData(text)
    },
    treeNodeRender(item) {
      if (item.props?.namePrefix) {
        return item.name.substring(item.props.namePrefix.length)
      }
      return item.name
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;
.formula {
  line-height: 1;
  > span {
    padding: 2px 0;
  }
  > button {
    margin: 5px 0;
  }
}
</style>
