<template>
  <div :class="$style.warp">
    <sd-form ref="form" :key="updateKey" :init-values="values">
      <template v-slot="{ model }">
        <table>
          <tr v-for="(value, index) in values" :key="index">
            <sd-form-item-td
              :name="value.name"
              :input-props="{
                readOnly: ['code'].indexOf(value.name) > -1 ? true : false,
              }"
            >
              <template v-if="value.name === 'code'">
                <a-input
                  v-model="model.code"
                  :read-only="unid && ['code'].indexOf(value.name) > -1 ? true : false"
                />
              </template>
              <template v-if="value.name === 'parentId'">
                <sd-value-picker
                  v-model="model.parentId"
                  single
                  option-value="key"
                  option-label="title"
                >
                  <template v-slot="scope">
                    <sd-picker-source-tree :load-tree-data="onLoadTreeData" v-bind="scope" />
                  </template>
                </sd-value-picker>
              </template>

              <template v-if="value.name === 'props'" v-slot:read-and-edit="{ editable }">
                <template v-if="!editable">
                  <sd-table
                    :columns="propColumns"
                    sortable
                    :data-source.sync="propsModify"
                    :pagination="false"
                    row-key="id"
                  >
                  </sd-table>
                </template>
                <template v-else>
                  <div :class="$style.operationWrapper">
                    <a-space>
                      <a-button class="editable-add-btn" @click="addProp">
                        添加
                      </a-button>
                      <a-button
                        class="editable-delete-btn"
                        :disabled="propSelectedRowKeys.length === 0"
                        @click="deleteProp"
                      >
                        删除
                      </a-button>
                    </a-space>
                  </div>
                  <sd-table
                    ref="propTable"
                    :columns="propColumns"
                    sortable
                    :data-source.sync="propsModify"
                    :pagination="false"
                    row-key="id"
                    :row-selection="{
                      selectedRowKeys: propSelectedRowKeys,
                      onChange: propSelectedChange,
                    }"
                    :custom-row="
                      (record, index) => {
                        return {
                          on: {
                            click: (event) => {
                              rowClickProp(record)
                            },
                          },
                        }
                      }
                    "
                  >
                  </sd-table>
                </template>
              </template>
            </sd-form-item-td>
          </tr>
        </table>
      </template>
    </sd-form>
    <a-modal
      v-model="propVisible"
      title="增加属性"
      destroy-on-close
      v-bind="{ width: 800 }"
      :mask-closable="false"
      @ok="saveProp"
      @cancel="$emit('closed')"
    >
      <sd-form ref="propForm" :init-values="propValues">
        <template>
          <sd-form-item name="tagName" />
          <sd-form-item name="tagValue" />
        </template>
      </sd-form>
    </a-modal>
  </div>
</template>

<script>
import moment from 'moment'
import { message } from 'ant-design-vue'
import NavService from './nav-service'
import components from './_import-components/sd-nav-import'

export default {
  name: 'SdNav',
  metaInfo: {
    title: 'SdNav',
  },
  components,
  props: {
    unid: {
      type: String,
      default: function() {
        return null
      },
    },
    curNav: {
      type: Object,
      default: function() {
        return null
      },
    },
    curParent: {
      type: Object,
      default: function() {
        return null
      },
    },
  },
  data() {
    return {
      parentInfo: null,
      updateKey: 0,
      values: [
        {
          name: 'parentId',
          caption: '上级菜单',
          dataType: 'string',
          required: true,
        },
        {
          name: 'code',
          caption: '编码',
          dataType: 'string',
          // readonly: !!this.unid,
        },
        {
          name: 'text',
          caption: '显示文字',
          required: true,
          dataType: 'string',
        },

        {
          name: 'url',
          caption: '链接',
          dataType: 'string',
          attr: {
            // eslint-disable-next-line no-useless-escape
            regex: /[^'‘"“”,，。\\、`!！]+[^\.]$/,
            regexMessage: '格式有误',
          },
        },
        {
          name: 'target',
          caption: '目标框架',
          dataType: 'string',
        },
        {
          name: 'index',
          caption: '序号',
          dataType: 'number',
        },
        {
          name: 'enabled',
          caption: '状态',
          dataType: 'selectlist',
          attr: {
            defaultValue: '1',
            selectListItem: [
              {
                value: '1',
                label: '启用',
              },
              {
                value: '0',
                label: '禁用',
              },
            ],
          },
        },
        {
          name: 'icon',
          caption: '图标',
          dataType: 'string',
        },
        {
          name: 'tooltip',
          caption: '提示文字',
          dataType: 'string',
        },
        {
          name: 'appId',
          caption: '徽标服务ID',
          dataType: 'string',
        },
        {
          name: 'show',
          caption: '显示模式',
          dataType: 'selectlist',
          attr: {
            defaultValue: '1',
            selectListItem: [
              {
                value: '1',
                label: '仅在PC端显示',
              },
              {
                value: '2',
                label: '仅在移动端显示',
              },
              {
                value: '4',
                label: '仅在前后端分离显',
              },
              {
                value: '3',
                label: 'PC端和移动端均显示',
              },
              {
                value: '5',
                label: 'PC端和前后端分离均显示',
              },
              {
                value: '6',
                label: '移动端和前后端分离均显示',
              },
              {
                value: '7',
                label: 'PC端、移动端和前后端分离均显示',
              },
            ],
          },
        },
        {
          name: 'props',
          caption: '附加属性',
          dataType: 'string',
        },
      ],
      propsModify: [],
      propVisible: false,
      propColumns: [
        {
          title: '属性名称',
          dataIndex: 'tagName',
        },
        {
          title: '属性值',
          dataIndex: 'tagValue',
        },
      ],
      propSelectedRowKeys: [],
      propValues: [
        {
          name: 'id',
          caption: 'id',
          required: true,
          dataType: 'string',
        },
        {
          name: 'tagName',
          caption: '属性名称',
          required: true,
          dataType: 'string',
        },
        {
          name: 'tagValue',
          caption: '属性值',
          dataType: 'string',
          required: true,
        },
      ],
      loadingMsg: null,
    }
  },
  watch: {
    unid: {
      handler(newVal, oldVal) {
        this.getDefaultValue()
      },
      immediate: true,
    },
  },
  methods: {
    propSelectedChange(selectedRowKeys) {
      this.propSelectedRowKeys = selectedRowKeys
    },
    deleteProp() {
      const ids = this.propSelectedRowKeys
      this.propsModify = this.propsModify.filter((item) => {
        return ids.indexOf(item.id) === -1
      })
      this.propSelectedRowKeys = []
    },
    addProp() {
      this.propVisible = true
      this.propValues.forEach((item) => {
        item.value = ''
        if (item.name === 'id') {
          item.value = parseInt('-' + moment().format('YYYYMMDDhhmmss'), 10)
        }
      })
    },

    rowClickProp(record) {
      this.propVisible = true
      this.propValues.forEach((item) => {
        item.value = record[item.name]
      })
    },
    saveProp() {
      return new Promise((resolve) => {
        this.$refs.propForm.validateFields().then((success) => {
          if (success) {
            const values = this.$refs.propForm.getFieldsValue()

            if (values.id < 0) {
              values.id = Math.abs(values.id)
              this.propsModify.push({
                ...values,
              })
            } else {
              const sso = this.propsModify.filter((item) => {
                return item.id === values.id
              })[0]
              for (const v in values) sso[v] = values[v]
            }

            this.propVisible = false
          }
        })
      })
    },
    getDefaultValue() {
      if (this.unid) {
        Promise.all([]).then(() => {
          this.values.forEach((item) => {
            if (['parentId', 'show', 'enabled', 'props'].indexOf(item.name) > -1) {
            } else {
              this.$refs.form.setFieldValue(item.name, this.curNav[item.name])
            }
          })
          if (this.curNav.enabled === true) {
            this.$refs.form.setFieldValue('enabled', '1')
          } else {
            this.$refs.form.setFieldValue('enabled', '0')
          }
          if (this.curNav.props?.show) {
            this.$refs.form.setFieldValue('show', this.curNav.props.show)
          }
          this.$refs.form.setFieldValue('parentId', [
            { key: this.curNav.parentId, title: this.curNav.parentName },
          ])

          const curProp = this.curNav.props
          const props = []
          for (const item in curProp) {
            if (item !== 'show') {
              props.push({
                id: item,
                tagName: item,
                tagValue: curProp[item],
              })
            }
          }
          this.propsModify = props
        })
      } else {
        Promise.all([]).then(() => {
          this.values.forEach((item) => {
            if (['parentId', 'show', 'enabled', 'props'].indexOf(item.name) > -1) {
            } else {
              this.$refs.form.setFieldValue(item.name, undefined)
            }
          })
          this.$refs.form.setFieldValue('parentId', [
            { key: this.curParent.id, title: this.curParent.text },
          ])
          this.propsModify = []
        })
      }
    },
    save() {
      return new Promise((resolve) => {
        this.$refs.form.validateFields().then((success) => {
          if (success) {
            let params = {
              props: {},
            }
            if (this.unid) {
              params = {
                ...this.curNav,
                props: {},
              }
            }
            const values = this.$refs.form.getFieldsValue()
            this.$refs.form.getBackendValues().forEach((item) => {
              params[item.name] = item.value
              if (item.name === 'parentId') params[item.name] = JSON.parse(item.value)[0].key
              if (item.name === 'enabled') params[item.name] = item.value === '1'
              if (item.name === 'props') {
                params.props = {
                  show: values.show,
                }
                this.propsModify.forEach((prop) => {
                  params.props[prop.tagName] = prop.tagValue
                })
              }
            })

            this.loadingMsg = message.loading({
              key: this.msgKey,
              content: '处理中...',
              duration: 0,
            })
            if (this.unid) {
              params.id = this.unid
              return NavService.saveNav(params)
                .then((res) => {
                  if (res.status === 200) {
                    message.success('保存成功')
                    resolve(true)
                  } else {
                    message.error(res.data?.message || '保存失败')
                  }
                })
                .catch((e) => message.error(e.response?.data?.message || '保存失败'))
                .finally(() => {
                  this.loadingMsg?.()
                })
            } else {
              return NavService.createNav({
                data: params,
                params: {
                  groupId: this.curParent.groupId,
                },
              })
                .then((res) => {
                  if (res.status === 200) {
                    message.success('新建成功')
                    resolve(true)
                  } else {
                    message.error(res.data?.message || '新建失败')
                  }
                })
                .catch((e) => message.error(e.response?.data?.message || '新建失败'))
                .finally(() => {
                  this.loadingMsg?.()
                })
            }
          }
        })
      })
    },
    changeParentId(oNode) {
      if (oNode[0]) {
        this.$refs.form.setFieldValue('parentId', [parseInt(oNode[0].key, 10)])
      } else {
        this.$refs.form.setFieldValue('parentId', [])
      }
    },
    onLoadTreeData(parentCatId) {
      return new Promise((resolve) => {
        if (parentCatId) {
          return NavService.getTreeChild({
            parentId: parentCatId,
          }).then((deps) => {
            resolve(this.parseTreeData(deps.data))
          })
        } else {
          const oNodes = [
            {
              key: '-1',
              title: '可管理机构菜单',
              isLeaf: false,
              backendAttr: {},
              showAction: false,
              scopedSlots: {
                title: 'root',
              },
            },
          ]
          return this.loadExpand(oNodes, 1).then((ids) => {
            this.treeData = oNodes
            this.defaultExpandedKeys = ids
            this.spinning = false
            resolve(oNodes)
          })
        }
      })
    },
    loadExpand(oNodes, level) {
      // 默认加载并展开对应层的树
      return new Promise((resolve) => {
        let ids = []
        Promise.all(
          oNodes.map((oNode) => {
            return NavService.getTreeChild({
              parentId: oNode.key,
            })
          })
        ).then((resAll) => {
          let childNodes = []
          resAll.forEach((res, index) => {
            oNodes[index].children = this.parseTreeData(res.data)
            ids = ids.concat(
              res.data.map((item) => {
                return item.id
              })
            )
            childNodes = childNodes.concat(oNodes[index].children)
          })
          if (level > 0) {
            this.loadExpand(childNodes, level - 1).then((childIds) => {
              resolve(ids.concat(childIds))
            })
          } else {
            resolve(ids)
          }
        })
      })
    },
    parseTreeData(deps) {
      return deps.map((dep) => {
        return {
          key: dep.id,
          title: dep.text,
          name: dep.text,
          isLeaf: dep.leaf,
          scopedSlots: {
            title: 'title',
          },
        }
      })
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;
.operation-wrapper {
  width: 100%;
  overflow: hidden;
  :global(.ant-space) {
    float: right;
  }
}
</style>
