<template>
  <div class="form_sd-form_common">
    <sd-form-item name="businessTypeName" />
    <sd-form-item name="businessTypeDesc" />
    <a-form-item label="所属分类">
      <sd-tree-picker
        v-model="selectedclassify"
        single
        :load-tree-data="loadTreeData"
        @change="classifyChange"
      />
    </a-form-item>
    <sd-form-item v-if="redHead" name="belongLevel" />
    <sd-form-item name="flowField" :input-props="{ defaultValue: defaultFlow }">
      <sd-flow-picker
        v-model="model.flowField"
        single
        :belonged-org-id="belongedOrg && belongedOrg.id"
        @change="updateFlowFormModelRelationInfoId"
      />
    </sd-form-item>
    <sd-form-item name="flowFormModelRelationInfoId">
      <a-select v-if="formOpts.length === 0" />
      <a-select v-else v-model="model.flowFormModelRelationInfoId" :options="formOpts"></a-select>
    </sd-form-item>
    <sd-form-item name="manuscriptTitle">
      <a-button
        v-for="(item, index) in organizeLevel"
        :key="index"
        size="small"
        :class="$style.titleBtnstyle"
        @click="titleSetStyle(item.code)"
        >{{ item.name }}</a-button
      >
      <a-textarea id="manuscriptTitle" v-model="model.manuscriptTitle" auto-size />
    </sd-form-item>
    <sd-form-item name="flowTitleType">
      <a-radio-group v-model="model.flowTitleType">
        <a-radio value="0">
          由用户填写
        </a-radio>
        <a-radio value="1">
          按规则生成
          <a-tooltip
            title="使用该选项时，建议隐藏表单上的标题字段，否则标题数据会显示在表单上且为只读状态"
          >
            <a-icon type="exclamation-circle" :class="$style.icon" />
          </a-tooltip>
        </a-radio>
      </a-radio-group>
    </sd-form-item>
    <sd-form-item name="flowTitle" :to-backend-value="toName" :label="null">
      <div :class="[$style.deptcontent, $style.flowtitle]">
        <a-textarea
          id="flowTitle"
          v-model="model.flowTitle"
          :auto-size="{ minRows: 2, maxRows: 4 }"
        />
        <a-button type="link" size="small" @click="select">设置 </a-button>
      </div>
    </sd-form-item>
    <sd-form-item v-if="redHead" name="redHeadField">
      <sd-select v-model="model.redHeadField" mode="multiple" :options="redheadOpts" />
    </sd-form-item>
    <sd-form-item name="printTemplateField">
      <sd-select v-model="model.printTemplateField" mode="multiple" :options="printOpts" />
    </sd-form-item>
    <sd-form-item name="sortNumber" />
    <sd-form-item name="authRange">
      <a-radio-group v-model="model.authRange">
        <a-radio value="all">
          全部
        </a-radio>
        <a-radio value="range">
          按范围
        </a-radio>
      </a-radio-group>
    </sd-form-item>
    <sd-form-item v-if="model.authRange === 'range'" name="rangeDeptMember">
      <div :class="$style.deptcontent">
        <sd-group-picker
          v-model="model.rangeDeptMember"
          v-bind="getFieldProps(fields.rangeDeptMember)"
        />
        <a-checkbox :checked="model.authSubIncluded === '1'" @change="setAuthSub">
          含下级</a-checkbox
        >
      </div>
    </sd-form-item>
    <sd-form-item
      name="rangeUserMember"
      :input-props="{ rootNode: getRootNode(fields.rangeUserMember) }"
    />
    <sd-form-item
      name="rangeRoleMember"
      :input-props="{ belongedOrgId: belongedOrg && belongedOrg.id }"
    />
    <sd-form-item name="isShow" />
    <sd-form-item name="mobileStatus" />
    <sd-form-item
      name="status"
      :input-props="{ defaultValue: defaultStatus || fields.status.attr.defaultValue }"
    />
    <a-modal
      :visible="visible"
      width="700px"
      title="标题设置"
      @cancel="visible = false"
      @ok="
        visible = false
        model.flowTitle = flowTitleTemp
      "
    >
      <a-textarea v-model="flowTitleTemp" placeholder="请从下方选择字段或文字" />
      <p />
      <a-list
        bordered
        :data-source="Object.keys(flowFieldsByCaption).filter((v) => v.includes(searchValue))"
        size="small"
        class="ant-transfer-list-content"
        :class="$style.fieldPicker"
      >
        <a-list-item
          slot="renderItem"
          slot-scope="item"
          class="ant-transfer-list-content-item"
          @click="flowTitleTemp = flowTitleTemp + `{${item}}`"
        >
          {{ item }}
        </a-list-item>
        <div slot="header">
          <a-input-search v-model="searchValue" placeholder="请输入搜索内容" />
        </div>
      </a-list>
    </a-modal>
  </div>
</template>

<script>
import PageService from '@/common/services/page-service'
import booleanUtil from '@/common/services/boolean-util'
import axios from '@/common/services/axios-instance'
import { message } from 'ant-design-vue'
import BusinesstypeService from './businesstype-service'
import components from './_import-components/sd-ywlx-form-import'

export default {
  name: 'SdYwlxForm',
  components,
  props: {
    model: {
      type: Object,
      required: true,
    },
    fields: {
      type: Object,
      required: true,
    },
    // 显示选择模板
    redHead: {
      type: Boolean,
      default: false,
    },
    // 业务类型ID
    categoryId: {
      type: [Number, String],
      default: 0,
    },
    // 业务类型名称
    categoryName: {
      type: String,
      default: '',
    },
    // 默认流程
    defaultFlow: {
      type: Array,
      default: () => [],
    },
    // 默认状态
    defaultStatus: {
      type: String,
      default: '',
    },
    // 指定的分级机构
    belongedOrg: {
      type: Object,
      default: null,
    },
  },
  data() {
    return {
      booleanUtil,
      formOpts: [],
      organizeLevel: [], // 级别
      redheadOpts: [], // 红头的列表
      printOpts: [], // 打印模板配置选项
      visible: false,
      flowFieldsByName: {},
      flowFieldsByCaption: {},
      flowTitleTemp: '',
      searchValue: '',
      selectedclassify: [],
    }
  },
  created() {
    // 非新建时，获取流程可用表单列表
    if (this.model.id) {
      this.getFlowFormModelRelationInfo()
    } else {
      // 新建：有默认流程，获取流程可用表单列表
      if (this.defaultFlow && this.defaultFlow.length > 0) {
        this.updateFlowFormModelRelationInfoId(this.defaultFlow)
      }
    }
    this.getLevel()
    this.getRedHeadList()
    this.getPrintTemplateList()
    // 如果flowTitle有值，用汉字更新下
    if (this.model.flowTitle) {
      this.getFlowFields().then(() => {
        Object.keys(this.flowFieldsByName).forEach((key) => {
          this.model.flowTitle = this.model.flowTitle.replace(
            new RegExp(`{${key}}`, 'g'),
            `{${this.flowFieldsByName[key]}}`
          )
        })
      })
    }
    this.selectedclassify = [{ id: String(this.categoryId), name: this.categoryName }]
    this.classifyChange(this.selectedclassify)
  },
  methods: {
    loadTreeData(id) {
      const params = {}
      if (this.belongedOrg) {
        params.belongedOrgId = this.belongedOrg.id
      }
      if (id) {
        return BusinesstypeService.getCategoryTree({ ...params, parentId: id }).then((res) => {
          return res.data.map((item) => ({
            id: item.id,
            name: item.text,
            checkable: true,
            isLeaf: item.isLeaf,
          }))
        })
      } else {
        return BusinesstypeService.getCategoryTree(params).then((res) => {
          const treeNode = [
            {
              id: '0',
              name: '业务类型',
              leaf: false,
              children: res.data.map((item) => ({
                id: item.id,
                name: item.text,
                checkable: true,
                isLeaf: item.isLeaf,
              })),
            },
          ]
          return treeNode
        })
      }
    },
    classifyChange(value) {
      this.model.categoryId = value.length ? value[0].id : ''
      this.model.categoryName = value.length ? value[0].name : ''
    },
    getFieldProps(field) {
      let hierarchical = field.attr.hierarchical
      if (field.attr.hierarchical !== undefined) {
        hierarchical = booleanUtil.isTruthy(field.attr.hierarchical)
      }
      return {
        hierarchical,
        single: field.attr?.multiple === 'false',
        rootNode: this.belongedOrg
          ? [{ code: this.belongedOrg.id, ...this.belongedOrg }]
          : field.attr?.roots?.map((root) => {
              return { code: root.id, ...root }
            }),
      }
    },
    getRootNode(field) {
      // 页面上有选择分级，返回当前分级
      if (this.belongedOrg) {
        return [{ code: this.belongedOrg.id, ...this.belongedOrg }]
      } else {
        // 以接口返回的roots为准
        return field.attr?.roots?.map((root) => {
          return { code: root.id, ...root }
        })
      }
    },
    // 编辑时，获取流程可用表单列表
    getFlowFormModelRelationInfo() {
      const flowField = this.model.flowField
      const oFlowField = typeof flowField === 'string' ? JSON.parse(flowField) : flowField
      if (oFlowField?.[0]?.id) {
        BusinesstypeService.getFlowFormModelRelationInfoId(oFlowField[0].id).then((data) => {
          // 判断表单列表中是否包含了当前存储的表单
          const formId = this.model.flowFormModelRelationInfoId
          if (formId) {
            // 当前存储的表单在备选列表中不存在，则提示该表单已被删除
            if (!data.some((item) => item.id === formId)) {
              data.unshift({ label: '--此业务单已被删除，请重新选择--', value: formId })
            }
          }
          this.formOpts = data
        })
      }
    },
    // 选择完流程后，获取可用表单列表
    updateFlowFormModelRelationInfoId(item) {
      if (item?.[0]) {
        BusinesstypeService.getFlowFormModelRelationInfoId(item[0].id).then((data) => {
          data.forEach((item) => {
            if (item.defaultRelation) {
              this.model.flowFormModelRelationInfoId = item.value
            }
          })
          this.formOpts = data
        })
      } else {
        this.model.flowFormModelRelationInfoId = undefined
        this.formOpts = []
      }
    },
    getLevel() {
      BusinesstypeService.getOrganizeLevel().then((res) => {
        this.organizeLevel = res.datas
      })
    },
    titleSetStyle(item) {
      const manuscriptTitle = document.getElementById('manuscriptTitle')
      let strStyle = '{'
      strStyle = strStyle + item + '}'
      let value = this.model.manuscriptTitle
      if (
        value !== undefined &&
        (manuscriptTitle.selectionStart || manuscriptTitle.selectionStart === 0)
      ) {
        const startPos = manuscriptTitle.selectionStart
        const endPos = manuscriptTitle.selectionEnd
        value = value.substring(0, startPos) + strStyle + value.substring(endPos, value.length)
        this.$nextTick()
        manuscriptTitle.focus()
        manuscriptTitle.setSelectionRange(endPos + value.length, endPos + value.length)
      } else {
        value = strStyle
      }
      this.model.manuscriptTitle = value
    },
    setAuthSub(e) {
      this.model.authSubIncluded = e.target.checked ? '1' : '0'
    },
    getRedHeadList() {
      const params = {
        startPosition: 0,
        maxResults: -1,
        expressions: [
          {
            dataType: 'str',
            name: 'status',
            op: 'eq',
            stringValue: '1',
          },
        ],
        formId: 'oaRedhead',
        orderBy: 'sortNum asc,creationTime desc',
        columns: 'id,redheadName,status,',
      }
      if (this.belongedOrg) {
        params.expressions.push({
          dataType: 'long',
          name: 'belongedOrgId',
          op: 'eq',
          longValue: Number(this.belongedOrg.id),
        })
      }

      PageService.getList(params).then((res) => {
        this.redheadOpts = res.data.data.map((val) => {
          return {
            id: val.id,
            name: val.redheadName,
          }
        })
      })
    },
    getPrintTemplateList() {
      const params = {
        startPosition: 0,
        maxResults: -1,
        expressions: [
          {
            dataType: 'str',
            name: 'status',
            op: 'eq',
            stringValue: '1',
          },
        ],
        formId: 'oaDocPrintTemplate',
        orderBy: 'creationTime asc',
        columns: 'id,templateName,status,',
      }
      if (this.belongedOrg) {
        params.expressions.push({
          dataType: 'long',
          name: 'belongedOrgId',
          op: 'eq',
          longValue: Number(this.belongedOrg.id),
        })
      }
      PageService.getList(params).then((res) => {
        this.printOpts = res.data.data.map((val) => {
          return {
            id: val.id,
            name: val.templateName,
          }
        })
      })
    },
    getFlowFields() {
      if (!this.model.flowField || !this.model.flowFormModelRelationInfoId) {
        message.warn('请先选择使用的流程和表单')
        return Promise.resolve(false)
      }
      let flowField = this.model.flowField
      flowField = typeof flowField === 'string' ? JSON.parse(flowField) : flowField
      return axios
        .get(
          `api/framework/v1/businesstype-manage/findFieldsByRelationInfoId?flowId=${flowField[0].id}&flowFormModelRelationInfoId=${this.model.flowFormModelRelationInfoId}`
        )
        .then((res) => {
          res.data.forEach((item) => {
            Object.keys(item).forEach((key) => {
              this.flowFieldsByName[key] = item[key]
              this.flowFieldsByCaption[item[key]] = key
            })
          })
          return true
        })
    },
    toName(value) {
      if (value) {
        Object.keys(this.flowFieldsByCaption).forEach((key) => {
          value = value.replace(new RegExp(`{${key}}`, 'g'), `{${this.flowFieldsByCaption[key]}}`)
        })
      }
      return value
    },
    select() {
      this.getFlowFields().then((flag) => {
        if (!flag) return
        this.visible = true
        this.flowTitleTemp = this.model.flowTitle || ''
      })
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;
$titlemargin: 8px;
.title-btnstyle {
  margin-right: $titlemargin;
  background-color: $btn-disable-bg;
}
.deptcontent {
  display: flex;
  justify-content: space-between;
  :global(.ant-checkbox-wrapper) {
    width: 21%;
    text-align: right;
  }
}
.flowtitle {
  float: right;
  width: 81%;
}
.field-picker {
  height: 550px;
  overflow: hidden;
  > div:nth-child(2) {
    height: 500px;
    overflow: scroll;
  }
}
</style>
