<template>
  <div class="menu-form">
    <div class="form">
      <el-form
        v-form
        :model="menu"
        data-vv-scope="appMenuForm"
        label-position="left"
      >
        <ht-form-item label="菜单类型">
          <ht-radio
            v-model="menu.menuType"
            validate="required"
            :options="menuOptions"
            @change="handleChange"
            :disabled="menuTypeDisabled"
          >
          </ht-radio>
        </ht-form-item>
        <ht-card-radio
          v-if="menu.menuType === 'page'"
          v-model="firstType"
          :options="jumpOptions"
          @change="typeChange"
        ></ht-card-radio>
        <template v-if="menu.menuType === 'category' || !!firstType">
          <div class="form-title">菜单基础信息</div>
          <el-row>
            <el-col :span="12">
              <ht-form-item label="上级菜单" class="is-required">
                <tree-select
                  :normalizer="normalizer"
                  v-model="menu.parentId"
                  :multiple="false"
                  :options="appMenus"
                  noOptionsText="暂无数据"
                  placeholder="请选择上级菜单"
                  style="width: 90%"
                  :clearable="false"
                  class="tree-select-radio"
                  :disabled="!appMenus[0].children"
                ></tree-select>
              </ht-form-item>
            </el-col>
            <el-col :span="12">
              <ht-form-item label="菜单名称"
                ><ht-input
                  v-model="menu.name"
                  validate="required"
                  style="width: 90%"
                  :maxlength="20"
                  show-word-limit
                >
                  <template slot="append">
                    <el-button
                      icon="icon-guojihua"
                      class="international-btn"
                      size="small"
                      @click="editI18nMessage()"
                    ></el-button
                  ></template> </ht-input
              ></ht-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <ht-form-item label="菜单别名">
                <ht-input
                  v-model="menu.alias"
                  validate="required"
                  v-pinyin="menu.name"
                  :disabled="!!menu.id"
                  style="width: 90%"
                  :maxlength="50"
                  show-word-limit
                ></ht-input>
              </ht-form-item>
            </el-col>

            <el-col :span="12" v-if="menu.type && secondTypeOptions.length > 1">
              <ht-form-item label="页面类型">
                <el-radio-group v-model="menu.type">
                  <el-radio
                    v-for="item in secondTypeOptions"
                    :key="item.type"
                    :label="item.type"
                    @change="menuTypeChange"
                  >
                    {{ item.name }}
                  </el-radio>
                </el-radio-group>
              </ht-form-item>
            </el-col>
            <el-col :span="12" v-if="menu.type === 1">
              <ht-form-item label="门户" class="is-required">
                <eip-portal-selector
                  class="select-list"
                  v-model="portalData"
                  placeholder="请选择门户"
                  title="选择门户"
                  :single="true"
                  input-width="90%"
                  :default-querys="[
                    {
                      property: 'layout_type',
                      value: '2',
                      group: 'layout_type',
                      operation: 'EQUAL',
                      relation: 'AND',
                    },
                    {
                      property: 'type_',
                      value: 'column',
                      group: 'layout_type',
                      operation: 'EQUAL',
                      relation: 'AND',
                    },
                  ]"
                />
              </ht-form-item>
            </el-col>
            <el-col :span="12" v-if="menu.type === 2">
              <ht-form-item label="表单列表" class="is-required">
                <eip-data-template-selector
                  class="select-list"
                  v-model="templateData"
                  placeholder="请选择表单列表"
                  :single="true"
                  input-width="90%"
                />
              </ht-form-item>
            </el-col>
            <el-col :span="12" v-if="menu.type === 3">
              <ht-form-item label="数据列表" class="is-required">
                <eip-custom-view-selector
                  validate="required"
                  v-model="customQueryData"
                  :single="true"
                  class="select-list"
                  input-width="90%"
                  placeholder="请选择数据列表"
                />
              </ht-form-item>
            </el-col>
            <el-col :span="12" v-if="menu.type === 4">
              <ht-form-item label="图表" class="is-required">
                <eip-chart-selector
                  validate="required"
                  :dataParam.sync="menu.content"
                  :chartType="2"
                  class="select-list"
                  input-width="90%"
                  placeholder="请选择图表"
                ></eip-chart-selector>
              </ht-form-item>
            </el-col>
            <el-col :span="12" v-if="menu.type === 5">
              <ht-form-item label="网页跳转" class="is-required">
                <ht-input
                  v-model="menu.content"
                  :validate="{required: true}"
                  style="width: 90%"
                  placeholder="请输入网址"
                ></ht-input>
              </ht-form-item>
            </el-col>
            <el-col :span="12" v-if="menu.type === 6">
              <ht-form-item label="表单" class="is-required">
                <eip-form-selector
                  validate="required"
                  v-model="formData"
                  :single="true"
                  class="select-list"
                  input-width="90%"
                  placeholder="请选择表单"
                />
              </ht-form-item>
            </el-col>
            <el-col :span="12" v-if="menu.type === 7">
              <ht-form-item label="流程模块" class="is-required">
                <eip-module-selector
                  class="select-list"
                  validate="required"
                  v-model="moduleData"
                  :single="true"
                  style="width: 90%"
                  placeholder="请选择流程模块"
                />
              </ht-form-item>
            </el-col>
            <el-col :span="12" v-if="menu.type === 8">
              <ht-form-item label="流程" class="is-required">
                <eip-flow-selector
                  validate="required"
                  v-model="flowData"
                  :single="true"
                  class="select-list"
                  style="width: 90%"
                  placeholder="请选择流程"
                >
                </eip-flow-selector>
              </ht-form-item>
            </el-col>
            <el-col :span="12" v-if="menu.type === 9">
              <ht-form-item label="datav大屏" class="is-required">
                <eip-portal-selector
                  class="select-list"
                  v-model="datavData"
                  placeholder="请选择大屏"
                  title="选择大屏"
                  :single="true"
                  input-width="90%"
                  :default-querys="[
                    {
                      property: 'layout_type',
                      value: '2',
                      group: 'layout_type',
                      operation: 'EQUAL',
                      relation: 'AND',
                    },
                    {
                      property: 'type_',
                      value: 'datav',
                      group: 'layout_type',
                      operation: 'EQUAL',
                      relation: 'AND',
                    },
                  ]"
                ></eip-portal-selector>
              </ht-form-item>
            </el-col>
            <el-col :span="12" v-if="menu.parentId === '0'">
              <ht-form-item label="菜单图标">
                <div class="menu-icon__wrap">
                  <div
                    class="menu-icon"
                    :class="menu.icon"
                    v-show="menu.icon"
                  ></div>
                  <div class="btn-group">
                    <IconDialog
                      @selected="selectIcon"
                      style="display: inherit"
                    />
                    <el-button
                      v-if="menu.icon"
                      plain
                      size="small"
                      style="margin-left: 16px"
                      @click="deleteIcon"
                      >删除图标</el-button
                    >
                  </div>
                </div>
              </ht-form-item>
            </el-col>
          </el-row>

          <template
            v-if="menu.menuType === 'page' && designIntros.length !== 0"
          >
            <el-row>设计指引:</el-row>
            <design-intro :data="designIntros" />
          </template>
        </template>
      </el-form>
    </div>
    <div class="button-wrap" v-if="showSave">
      <el-button type="primary" @click="save()" class="button">保存</el-button>
    </div>

    <i18n-message-edit
      ref="i18nMessageEdit"
      :messageKey="i18nMessageKey"
      @after-save="afterSaveI18n"
    />
  </div>
</template>

<script>
import {mapState} from 'vuex'
import portal from '@/api/portal'
import {
  DESIGN_INTROS,
  JUMP_TYPE_OPTIONS,
  MENU_TYPE_OPTIONS,
  TYPE_MAP_ARRAY,
} from './const'

const HtCardRadio = () => import('@/components/common/HtCardRadio')
const DesignIntro = () => import('@/views/portal/appcenter/DesignIntro')
const TreeSelect = () => import('@riophae/vue-treeselect')
const IconDialog = () => import('@/components/dialog/IconDialog.vue')
const EipDataTemplateSelector = () =>
  import('@/components/selector/EipDataTemplateSelector.vue')
const EipCustomViewSelector = () =>
  import('@/components/selector/EipCustomViewSelector.vue')
const EipChartSelector = () =>
  import('@/components/selector/EipChartSelector.vue')
const EipFormSelector = () =>
  import('@/components/selector/EipFormSelector.vue')
const EipModuleSelector = () =>
  import('@/components/selector/EipModuleSelector.vue')
const EipFlowSelector = () =>
  import('@/components/selector/EipFlowSelector.vue')
const EipPortalSelector = () =>
  import('@/components/selector/EipPortalSelector')
const I18nMessageEdit = () => import('@/components/system/I18nMessageEdit.vue')
const EMPTY_IMAGE = require('@/assets/nodata_images/no-data.png')
import _ from 'lodash'
import utils from '@/hotent-ui-util'

export default {
  name: 'AppForm',
  props: {
    data: {
      type: Object,
    },
    appAlias: {
      type: String,
    },
    appName: {
      type: String,
    },
    showSave: {
      type: Boolean,
      default: false,
    },
    level: {
      type: Number,
      default: 1,
    },
  },
  components: {
    HtCardRadio,
    DesignIntro,
    TreeSelect,
    EipDataTemplateSelector,
    EipCustomViewSelector,
    EipChartSelector,
    EipFormSelector,
    EipModuleSelector,
    EipFlowSelector,
    EipPortalSelector,
    IconDialog,
    I18nMessageEdit,
  },
  data() {
    return {
      menu: {
        type: 0,
      },
      menuOptions: MENU_TYPE_OPTIONS,
      jumpOptions: JUMP_TYPE_OPTIONS,
      emptyImage: EMPTY_IMAGE,
      templateData: {},
      portalData: {},
      customQueryData: {},
      formData: {},
      moduleData: {},
      flowData: {},
      datavData: {},
      firstType: null,
      typeMapArray: TYPE_MAP_ARRAY,
      secondTypeOptions: [],
      i18nMessageKey: '',
      cache: {
        icon: '',
        type: '',
      },
    }
  },
  computed: mapState({
    appMenus(state) {
      // 去除当前菜单，避免菜单绑定自身
      let children = _.cloneDeep(state.menu.appMenus).filter((item) => {
        if (item.menuType !== 'category' || item.id === this.menu.id) {
          return false
        }
        item.children = item.children.filter((child) => {
          if (child.menuType !== 'category' || child.id === this.menu.id) {
            return false
          }
          delete child.children
          return true
        })
        if (item.children.length === 0) {
          delete item.children
        }
        return true
      })

      if (children.length === 0) {
        return [
          {
            id: '0',
            alias: 'menu',
            name: this.appName,
          },
        ]
      }
      return [
        {
          id: '0',
          alias: 'menu',
          name: this.appName,
          children,
        },
      ]
    },
    designIntros() {
      if (this.firstType) {
        return DESIGN_INTROS[this.firstType].filter(
          (item) => item.type === this.menu.type
        )
      }
      return []
    },
    menuTypeDisabled() {
      if (this.level >= 3) {
        return true
      }
      return !!this.menu.children && this.menu.children.length > 0
    },
  }),
  watch: {
    data: {
      handler(newVal) {
        this.$set(this, 'menu', {...newVal})
        if (newVal) {
          if (newVal.type) {
            this.initConfig()
            let map = this.typeMapArray.find(
              (item) => item.type === newVal.type
            )
            this.firstType = map.firstType
            if (newVal.type === 1) {
              this.portalData = JSON.parse(newVal.content)
            } else if (newVal.type === 2) {
              this.templateData = JSON.parse(newVal.content)
            } else if (newVal.type === 3) {
              this.customQueryData = JSON.parse(newVal.content)
            } else if (newVal.type === 6) {
              this.formData = JSON.parse(newVal.content)
            } else if (newVal.type === 8) {
              this.flowData = JSON.parse(newVal.content)
            } else if (newVal.type === 7) {
              this.moduleData = JSON.parse(newVal.content)
            } else if (newVal.type === 9) {
              this.datavData = JSON.parse(newVal.content)
            }
            this.cacheConfig(newVal)
          } else {
            this.firstType = null
          }
        }
      },
      deep: true,
      immediate: true,
    },
  },
  methods: {
    handleChange() {
      this.menu.type = 0
    },
    typeChange() {
      this.$set(
        this,
        'secondTypeOptions',
        this.typeMapArray.filter((item) => item.firstType === this.firstType)
      )
      this.menu &&
        this.$set(
          this.menu,
          'type',
          this.secondTypeOptions.length === 0
            ? null
            : this.secondTypeOptions[0].type
        )

      if (this.cache.type === this.menu.type) {
        this.$set(this.menu, 'icon', this.cache.icon)
      } else {
        this.$set(this.menu, 'icon', '')
      }
      this.initContent()
    },
    menuTypeChange() {
      this.initContent()
    },
    initContent() {
      this.$set(this.menu, 'content', '')
    },
    normalizer(node) {
      return {
        id: node.id,
        label: node.name,
        children: node.children,
        isDefaultExpanded: false,
      }
    },
    editI18nMessage() {
      if (!this.menu.alias) {
        this.$message.error('请先填写菜单别名')
        return
      }
      this.i18nMessageKey = `app.${this.appAlias}.menu.${this.menu.alias}`
      this.$refs.i18nMessageEdit.handleOpen()
    },
    save(cb) {
      this.beforeSave()
      if (!this.validate()) {
        return
      }
      this.$root.$validator.validateAll('appMenuForm').then((result) => {
        if (result) {
          portal
            .saveAppMenu(this.menu)
            .then((data) => {
              this.$message.success('保存成功')
              cb && cb(data)
            })
            .finally(() => {
              this.$emit('after-save')
              this.cacheConfig(this.menu)
            })
        } else {
          return this.$message.error('有必填的内容未填写。')
        }
      })
    },
    validate() {
      if (
        this.menu.menuType === 'page' &&
        (this.menu.content === '{}' || !this.menu.content)
      ) {
        this.$message.error('配置内容为必填')
        return false
      }
      if (!this.menu.parentId) {
        this.$message.error('上级菜单为必填')
        return false
      }
      return true
    },
    beforeSave() {
      if (this.menu.type === 1) {
        let data = {
          id: this.portalData.id,
          alias: this.portalData.alias,
          name: this.portalData.name,
        }
        this.menu.content = JSON.stringify(data)
      } else if (this.menu.type === 2) {
        let data = {
          id: this.templateData.id,
          alias: this.templateData.alias,
          name: this.templateData.name,
        }
        this.menu.content = JSON.stringify(data)
      } else if (this.menu.type === 3) {
        let data = {
          id: this.customQueryData.id,
          alias: this.customQueryData.alias,
          sqlAlias: this.customQueryData.sqlAlias,
          name: this.customQueryData.name,
        }
        this.menu.content = JSON.stringify(data)
      } else if (this.menu.type === 6) {
        let data = {
          id: this.formData.id,
          name: this.formData.name,
          key: this.formData.formKey,
        }
        this.menu.content = JSON.stringify(data)
      } else if (this.menu.type === 7) {
        let data = {
          id: this.moduleData.id,
          name: this.moduleData.name,
        }
        this.menu.content = JSON.stringify(data)
      } else if (this.menu.type === 8) {
        let data = {
          id: this.flowData.id,
          name: this.flowData.name,
          key: this.flowData.defKey,
        }
        this.menu.content = JSON.stringify(data)
      } else if (this.menu.type === 9) {
        let data = {
          id: this.datavData.id,
          name: this.datavData.name,
          alias: this.datavData.alias,
        }
        this.menu.content = JSON.stringify(data)
      }
    },
    selectIcon(icon) {
      this.$set(this.menu, 'icon', icon)
      if (this.cache.type === this.menu.type) {
        this.cache.icon = icon
      }
    },
    deleteIcon() {
      this.$set(this.menu, 'icon', '')
    },
    afterSaveI18n(data) {},
    initConfig() {
      this.portalData = {}
      this.templateData = {}
      this.customQueryData = {}
      this.formData = {}
      this.flowData = {}
      this.moduleData = {}
      this.datavData = {}
    },
    cacheConfig(val) {
      this.cache = {
        icon: val.icon || '',
        type: val.type,
      }
    },
  },
}
</script>

<style lang="scss" scoped>
.menu-form {
  .form {
    margin: auto;
    width: 960px;
    padding: 0;
    .form-title {
      font-size: 16px;
      margin: 24px 0 22px 0;
    }

    .menu-icon__wrap {
      display: flex;
      align-items: center;

      .menu-icon {
        height: 48px;
        text-align: center;
        line-height: 48px;
        background: #eeeeee;
        border-radius: 2px;
        color: #409eff;
        font-size: 32px;
        margin-right: 16px;
        padding: 0 8px;
      }

      .btn-group {
        display: flex;
        height: 32px;
      }
    }
  }

  .button-wrap {
    display: flex;
    justify-content: center;

    .button {
      margin-top: 100px;
      width: 108px;
      height: 40px;
    }
  }
}

.inputs.ht-form-inputs__inline {
  width: auto;
}
.el-col {
  height: 60px;
}
::v-deep {
  .el-input-group__append {
    .el-button {
      font-size: 16px;
    }
  }

  .tree-select-radio .vue-treeselect__control {
    border-radius: 2px;
    height: 32px;
  }
}
</style>
