import commonDeclare from "./commonDeclare"
import commonApi from "./commonApi"
import SettleEvent from "~/components/business/setmod/event"
import LiaccvEvent from "~/components/business/ccvpan/event"
import LiaallEvent from "~/components/business/engp/event"
import GletnryEvent from "~/components/business/glentry/event"
import DocpanEvent from "~/components/business/docpan/event"
import commonGlobalSearch from "./commonGlobalSearch";
import Utils from "~/utils"
import _ from "~/utils/Lodash.js";

const tabNameToRulePathMapping = {
  "setpan": "setmod.setpan",
  "glepan": "setmod.glemod.glepan",
  "docpan": "trnmod.trndoc.docpan",
  "doctre": "trnmod.trndoc.doctre",
  "cips": "trnmod.cipmod.cips",
  "cips2": "trnmod.cipmod.cips",
  "engp": "liaall.engp",
  "limitbody": "liaall.limmod.limitbody",
  "ccvpan": "liaall.liaccv.ccvpan",
  "detp1": "setmod.setpan",
  "actinf": "recpan.actinf",
  "libp": "cnybop.libp",
  "basp": "bopmod.dbap.basp",
  "basp1": "bopmod.dbdp.basp",
  "basp2": "bopmod.dbdp.basp",
  "basp3": "bopmod.dbap.basp",
  "incp": "cnybop.incp",
  "outp": "cnybop.Outp",
  "dbb": "bopmod.dbbp.basp",
  "dbe": "bopmod.dbep.basp",
  "dclpp":"recp.dclp(1).dclpp",
  "conp":"cfabpt.recp.conp",
  "cfactlp":"cfactlp",//资本项目标签页切换触发点击切换标签页事件
  "cnyp1":"cnybop.cnyp1"//跨境人民申报标签页切换触发点击切换标签页事件
}

export default {
  mixins: [commonApi, commonDeclare, commonGlobalSearch],
  data: function () {
    return {
      // 弹框回填
      promptData: {
        title: '',
        columnStr: '',
        data: [],
        rulePath: ''
      },
      isChecking: false
    }
  },
  created() {
  },
  mounted() {
    if (!this.isInDisplay && !['gitopn'].includes(this.trnName)) {
      // this.generateFormRules()
    }
  },
  methods: {
    ...SettleEvent,
    ...LiaallEvent,
    ...GletnryEvent,
    ...DocpanEvent,
    ...LiaccvEvent,
    /**
     * 表单校验 rules 的赋值
     * @returns void
     */
    generateFormRules() {
      if (this.root) {
        if (!this.root.rules) {
          return;
        } else {
          // 新添加的表单项,需要重新确定下 validator 的触发 trigger
          this.updateRulesTrigger();
          return
        }
      }
      if (!this.pattern)
        return
      // const keySet = new Set(Object.keys(this.pattern).concat(Object.keys(this.checkRules).concat(Object.keys(this.defaultRules))))
      const keySet = new Set(Object.keys(this.pattern).concat(Object.keys(this.defaultRules)))
      const res = {};
      const that = this;
      for (let key of keySet.keys()) {
        const rule = []
        if (that.pattern[key]) {
          rule.push(...that.pattern[key])
        }
        const triggerType = that.getTriggerType(key)
        // if(that.checkRules[key]){
        //   if (Array.isArray(that.checkRules[key])) {
        //     for (let j = 0; j < that.checkRules[key].length; j++) {
        //       const check = that.checkRules[key][j];
        //       rule.push({
        //         validator: check.bind(that),
        //         trigger: triggerType
        //       })
        //     }
        //   } else {
        //     rule.push({
        //       validator: that.checkRules[key].bind(that),
        //       trigger: triggerType
        //     })
        //   }
        // }
        if (that.defaultRules[key]) {
          rule.push({
            validator: that.defaultRules[key].bind(that),
            trigger: triggerType
          })
        }
        if (rule.length > 0) {
          res[key] = rule;
        }
      }
      that.rules = res;
    },
    /**
     * 触发方式
     * @param {String} prop item属性
     * @returns 
     */
    getTriggerType(prop) {
      const modelForm = this.root ? this.root.$refs.modelForm : this.$refs.modelForm
      const fields = modelForm.fields;
      for (let i = 0; i < fields.length; i++) {
        const field = fields[i];
        if (field.prop === prop) {
          // select、checkbox使用change触发
          const ele = field.$children[1] ? field.$children[1].$children[0] : field.$children[0].$children[0]
          if (ele.$el.className.startsWith("el-select") || ele.$el.className.startsWith("el-checkbox")) {
            return "change";
          }
          return "blur";
        }
      }
      return "blur";
    },
    /**
     * 表单有些 tab 是通过 v-if 控制的,这些表单项初始时的 trigger 均为 blur,需要手动更新
     */
    updateRulesTrigger() {
      const rules = this.root.rules
      for (const key in rules) {
        if (Object.hasOwnProperty.call(rules, key)) {
          const rule = rules[key];
          const triggerType = this.getTriggerType(key)
          for (let i = 0; i < rule.length; i++) {
            const r = rule[i];
            if (r.validator && r.trigger !== triggerType) {
              r.trigger = triggerType;
            }
          }
        }
      }
    },
    /**
     * Tabs切换事件
     * @param {VM} tab  
     */
    async tabClick(tab) {
      if (this.isInDisplay) {
        return
      }
      let name = tab.name;
      if (name === "ccvpan") {
        this.processLiaccv();
        return;
     }
      if (name === "engp") {
         this.processLiaall();
         return;
      }
      if (name === "setpan") {
         this.processSetpan();
         return;
      }
      if (name === "docpan") {
        this.processTrndoc();
        return;
     }
      if (name === "glepan") {
        this.processGlentry();
        return;
      }
      const nms = name.split(",")
      const arr = []
      for (let i = 0; i < nms.length; i++) {
        const n = nms[i];
        const path = tabNameToRulePathMapping[n]
        if (path) {
          arr.push(path)
        }
      }

      let rulePath = arr.join(",");
      // if (name.indexOf("setpan") > -1) {
      //   name = name.replace("setpan", "setmod.setpan");
      // }
      // if (name.indexOf("glepan") > -1) {
      //   name = name.replace("glepan", "setmod.glemod.glepan");
      // }
      // if (name === "docpan") {
      //   rulePath = "trnmod.trndoc.docpan"
      // }
      // if (name === "doctre") {
      //   rulePath = "trnmod.trndoc.doctre"
      // }
      // if (name === "cips" || name === "cips2") {
      //   rulePath = "trnmod.cipmod.cips"
      // }
      // if (name.indexOf("engp") > -1) {
      //   name = name.replace("engp", "liaall.engp")
      // }
      // if (name === "limitbody") {
      //   rulePath = "liaall.limmod.limitbody"
      // }
      // if (name === "ccvpan") {
      //   rulePath = "liaall.liaccv.ccvpan"
      // }
      // if (name === "detp1") {
      //   rulePath = "setmod.setpan"
      // }
      // if (name === "actinf") {
      //   rulePath = "recpan.actinf"
      // }
      // if (name === "libp") {
      //   rulePath = "cnybop.libp"
      // }
      // if (name === 'basp') {
      //   rulePath = "bopmod.dbap.basp"
      // }
      // if (name === 'basp1') {
      //   rulePath = "bopmod.dbdp.basp"
      // }
      // if (name === 'basp2') {
      //   rulePath = "bopmod.dbdp.basp"
      // }
      // if (name === 'basp3') {
      //   rulePath = "bopmod.dbap.basp"
      // }
      // if (name === 'incp') {
      //   rulePath = "cnybop.incp"
      // }
      // if (name === 'outp') {
      //   rulePath = "cnybop.Outp"
      // }
      // if (name === 'dbb') {
      //   rulePath = "bopmod.dbbp.basp"
      // } if (name === 'dbe') {
      //   rulePath = "bopmod.dbep.basp"
      // }
      if (!!rulePath) {
        // if(rulePath == "setmod.setpan"){
        //     this.executeCustomRule(rulePath).then(res => {
        //         if (res.respCode == SUCCESS) {
        //             this.updateModel(res.data)
        //         }
        //     })
        // }else{
        this.executeRule(rulePath).then(res => {
          if (res.respCode == SUCCESS) {
            this.updateModel(res.data);
          }
        })
        // }
      }
    },
    /**
     * 以函数形式获取model(请求参数),保证取到的是最新赋值的
     * @param {any} params 参数
     * @param {any} selfCb 允许延时组数 参数
     * @returns 
     */
    wrapper(params, delayCb) {
      params = params || {}
      const fn = async () => {
        const that = this;
        const data = await new Promise(resolve => {
          // 保证前一次请求结果赋值VO完成
          setTimeout(() => {
            delayCb && delayCb()
            const d = Utils.flatObject(that.model)
            resolve(d)
          }, 0)
        })
        return { ...data, params }
      }
      return fn;
    },
    wrapperCustom(params, delayCb) {
      params = params || {}
      params['isCustom'] = true
      const fn = async () => {
        const that = this;
        const data = await new Promise(resolve => {
          // 保证前一次请求结果赋值VO完成
          setTimeout(() => {
            delayCb && delayCb()
            const d = Utils.flatObject(that.customModel)
            resolve(d)
          }, 0)
        })
        params['keys'] = Object.keys(data)
        return { ...data, params }
      }
      return fn;
    },
    /**
     * 用于手动的触发model里属性的 executeDefault 
     * @param {string} rule 执行的 rule path
     * @param {any} value   更改的值
     */
    defaultFunction(rule, value) {
      Utils.defaultFunction.call(this, rule, value)
    },
    /**
 * 用于手动的触发model里属性的 event
 * @param {string} rule 执行的 rule path
 * @param {any} value   更改的值
 */
    eventFunction(rulePath) {
      this.executeRule(rulePath).then((res) => {
        if (res.respCode == SUCCESS) {
          Utils.copyValueFromVO(this.model, res.data);
        }
      })
    },
    /**
     * 更新Model
     * @param {any} data model数据
     */
    updateModel(data) {
      Utils.copyValueFromVO(this.model, data);
    },
    /**
     * 弹出机构选择框
     * @param {String} rulePath 
     * @param {String} columns 自定义需要展示列
     * @param {String} shadow 自定义列后需要保留的影藏字段
     * @param {String} modelUrl 非机构双击后需要回填的字段路劲,k:对应列,value:应用model路劲,如{TXT:'ledgrp.blk.lcrgod'}
     * @param {String} isCover 非机构双击后需要回填的字段值是覆盖还是叠加,部分覆盖值为对象,false为叠加,如{TXT:false},k值为modelUrl的k,如全部覆盖则isCover='T',如全部叠加则isCover='',默认全部覆盖
     * @param {String} defaultColumn 选中列,默认第0列
     */
    showGridPromptDialog(rulePath, columns, shadow, modelUrl, isCover = "T", Dialog = 'etyDialog', defaultColumn = 0) {
      this.executeRule(rulePath, { 'EventType': 4 }).then((res) => {
        if (res.respCode == SUCCESS) {
          if (res.data.params) {
            Utils.copyValueFromVO(this.model, res.data);
          } else {
            this.root.$refs[Dialog].show = true
            this.root.promptData = {
              title: res.data.title,
              columnStr: columns ? columns : res.data.columns,
              shadow: shadow,
              data: res.data.vals.rows,
              rulePath: rulePath,
              modelUrl: modelUrl,
              isCover: isCover,
              defaultColumn: defaultColumn
            }
          }
        }
        this.$el.querySelectorAll('input').forEach(input => input.blur())
      })
    },
    /**
     * 下拉框/多选框 改变时执行rule
     * @param {String} rulePath 路径
     */
    selectOrCheckboxRule(rulePath) {
      this.executeRule(rulePath).then((res) => {
        if (res.respCode == SUCCESS) {
          Utils.copyValueFromVO(this.model, res.data);
        }
      })
    },
    /**
     * 机构回填
     * @param {String} val 选种行的值(一般是首列)
     * @param {String} rulePath 路径
     */
    selectEty(val, rulePath) {
      // const props = rulePath.replaceAll(".", "_")
      // const obj = {}
      // obj[props] = val;
      // Utils.copyValueFromVO(this.model, obj);
      if (rulePath.indexOf("(") > 0) {//请求地址有"()"下标时,如setmod.setglg.setgll(2).setgrp.snd756.pts.extkey
        let tempRulePath = rulePath
        let rulePath = ""
        const reg = /\((\d+)\)/
        while (reg.test(tempRulePath)) {
          const match = tempRulePath.match(reg)
          rulePath += tempRulePath.substring(0, match.index) + "[" + (parseInt(match[1]) - 1) + "]"
          tempRulePath = tempRulePath.substring(match.index + match[0].length)
        }
        rulePath += tempRulePath
      }
      _.set(this.model, rulePath, val)
      this.executeRule(rulePath, { "selectStatus": 1,'EventType': 1}).then((res) => {
        if (res.respCode == SUCCESS) {
          Utils.copyValueFromVO(this.model, res.data);
        }
      });
    },

    /**
        * 货物条款等非机构栏位回填
        * @param {Object} val 选种行的值,按钮的值
        * @param {Object} url 字段路劲 需要回填的字段路劲
        *  @param {Object} url 对应字段值是否覆盖 ,需要为true,否则合并叠加
        * @param {String} rulePath 路径
        */
    selectMsg(val, modelUrl, isCover, rulePath) {
      for (let k in val) {
        let msg = val[k]
        if ((typeof isCover === 'string' && isCover === '') || !isCover[k]) {
          let ms = _.get(this.model, modelUrl[k], '')
          msg = (ms ? ms + '\r\n' : '') + msg
        }
        _.set(this.model, modelUrl[k], msg);
        this.defaultFunction();
      }
    },
    /**
     * 改变表单项的是否必填属性
     * @param {String} property 属性
     * @param {Boolean} required 是否必填
     */
    changeFormItemRequired(property, required) {
      this.getRoot().pattern[property][0].required = required
    },
    /**
     * 在 A 交易中打开 B 交易视图(详情、开立...)。
     * 
     * 路由视图跳转,例:
     *    this.gotoView("Ditopn", {inr: "001021021"}, {name: "lisi"})   实际请求的 url 为 /business/ditopn/001021021?name=lisi
     *    params, query按需传入(得提前配置好 Router ),在对应的vue页面做好处理
     * @param {String} name 路由的name
     * @param {Object} params 路由的params
     * @param {Object} query 路由的query
     */
    gotoView(name, params, query) {
      params = params || {}
      query = query || {}
      this.$router.push({ name, params, query })
    },
    gotoUrl(url) {
      this.$router.push(url)
    },
    /**
     * 设置拖动组件的内容
     * @param {String} currentTool 
     * @param {String} toolTitle 
     */
    setDraggableContent(currentTool, toolTitle) {
      const layout = this.$root.$children[0].$children[0]
      layout.dragShow = true;
      layout.changeSize(1);
      layout.currentTool = currentTool;
      layout.toolTitle = toolTitle;
    },

    /**
     * 判断状态信息,包括visiable,modified,enabled等
     */
    judgeVisiableInfo(rulePath){
        // var model = this.model;
        // if(model == null){
        //     return false;
        // }
        // var info = this.model.statusInfo;
        // if(info == null || info.length == 0){
        //     return false;
        // }
        // var visiable = info["visiable"];
        // if(visiable[rulePath] == null){
        //     return false;
        // }
        // return visiable[rulePath];
        return true
    }
  },
  computed: {
    isInDisplay() {
      return this.$store.state.Status.mode === 'display'
    }
  }
}