<template>
  <div :key="key" :class="$style.panel">
    <sd-header :class="$style.panelHeader">
      <div slot="left" />
    </sd-header>
    <div v-show="state !== 0" :class="$style.skeletonBox">
      <div :class="$style.skeLeft">
        <a-skeleton :paragraph="false" />
        <a-skeleton :paragraph="{ rows: 25 }" :class="$style.skeleton" />
      </div>
      <div :class="$style.skeRight">
        <a-skeleton :paragraph="{ rows: 7 }" />
        <a-skeleton :paragraph="{ rows: 5 }" />
        <a-skeleton :paragraph="{ rows: 5 }" />
      </div>
    </div>
    <component :is="webform" v-show="state === 1" />
    <a-result
      v-if="state === 0"
      :class="$style.panelResult"
      status="404"
      :title="errorinfo.message"
    >
      <template v-slot:extra>
        <a-button type="primary" @click="close">
          关闭
        </a-button>
      </template>
    </a-result>
  </div>
</template>

<script>
import Vue from 'vue'
import { Message } from 'ant-design-vue'
import FlowService from '@/webflow/flow-service'
import crossWindowWatcher from '@/common/services/cross-window-watcher'
import extWebflowTemplate from '@extension-points/webflow/ext-webflow-template.vue'
import sdInformLog from '@/webflow/sd-inform-log.vue'
import sdFlowchart from '@/webflow/sd-flowchart.vue'
import sdOpinionLog from '@/webflow/sd-opinion-log.vue'
import sdProcessInfo from '@/webflow/sd-process-info.vue'
import sdReminderLog from '@/webflow/sd-reminder-log.vue'
import sdModifyLog from '@/webflow/sd-modify-log.vue'
import sdRelateDoc from '@/webflow/sd-relate-doc.vue'
import sdWebflowPrintBlock from '@/webflow/button-handlers/components/sd-webflow-print-block.vue'
import components from './_import-components/sd-webflow-panel-import'
/* eslint-disable vue/match-component-file-name */
Vue.component('sd-webflow', extWebflowTemplate)
Vue.component('sd-flowchart', sdFlowchart)
Vue.component('sd-inform-log', sdInformLog)
Vue.component('sd-process-info', sdProcessInfo)
Vue.component('sd-opinion-log', sdOpinionLog)
Vue.component('sd-reminder-log', sdReminderLog)
Vue.component('sd-modify-log', sdModifyLog)
Vue.component('sd-relate-doc', sdRelateDoc)
Vue.component('sd-webflow-print-block', sdWebflowPrintBlock)
export default {
  name: 'SdWebflowPanel',
  components,
  data() {
    return {
      webform: null,
      errorinfo: null,
      state: -1,
      pageTitle: undefined,
      FlowData: {},
      key: 1,
    }
  },
  metaInfo() {
    return {
      title: this.pageTitle,
    }
  },
  provide() {
    return {
      FlowDataPanel: this.FlowData,
      updateFlowPanel: this.updateFlow,
    }
  },
  watch: {
    '$route.params.id': function(a, b) {
      // 路由如果发生了变化，等到数据更新了再更新视图
      this.state = -1
      this.updateFlow().then(() => {
        this.key++
      })
    },
  },
  created() {
    this.updateFlow().then(() => {
      if (this.$route.query.tempField) {
        const { tempField, ...query } = this.$route.query
        this.$router.replace(
          this.$router.resolve({
            path: this.$route.path,
            query,
          }).route.fullPath
        )
      }
    })
  },
  methods: {
    close() {
      crossWindowWatcher.notifyChange(true)
      window.close()
    },
    updateFlow() {
      let p = this.$route?.meta?.preData
      if (!p) {
        p = FlowService.getData(this.$route.params)
      } else {
        this.$route.meta.preData = undefined
      }
      return p
        .then((res) => {
          if (!res.optimistic && res.mode === 'EDIT') {
            // 悲观锁主动加锁
            return FlowService.getLock(res.instId, true).then((flag) => {
              if (!flag) {
                // eslint-disable-next-line no-console
                console.log('获取锁失败，以只读方式打开')
                res.processFormData.processFormPropertyValues.forEach((item) => {
                  item.readonly = true
                  if (item.dataType === 'attachment') item.attr = {}
                })
                res.pushButtons = []
                res.saveButtons = []
                res.buttons = res.buttons.filter((btn) => {
                  return ['workflow$myAttention', 'we-doc$close'].includes(btn.buttonId)
                })
                Message.warn(`其他用户正在处理此流程`)
              }
              return res
            })
          } else {
            return res
          }
        })
        .then((res) => {
          Object.assign(this.FlowData, res)
          if (this.FlowData.attrs.lockInfo) {
            Message.warn(`${this.FlowData.attrs.lockInfo}正在处理此流程`)
          }
          this.pageTitle = res.pageTitle
          this.webform = FlowService.getWebForm(res)
          this.state = 1
        })
        .catch((e) => {
          // eslint-disable-next-line no-console
          console.error('获取流程详情信息失败,请排查详情接口')
          this.errorinfo = e.response
          if (e.response?.data?.code === '-1') {
            this.errorinfo.message = e.response?.data?.message
          } else if (['403', '401'].includes(e.response?.data?.code)) {
            this.errorinfo.message = '您没有访问权限'
          } else {
            this.errorinfo.message = '处理失败，请关闭此页面'
          }
          this.state = 0
        })
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;
$panel-margin: 5%;
.panel {
  height: 100%;
  overflow: hidden;
  .panel-header {
    position: fixed;
    top: 0;
    right: 0;
    width: 100%;
  }
  .skeleton-box {
    position: absolute;
    z-index: 0;
    display: flex;
    justify-content: space-around;
    width: 100%;
    height: 100%;
    padding: 1%;
    margin: auto;
    overflow: hidden;
    .ske-right,
    .ske-left {
      display: flex;
      flex-direction: column;
      justify-content: space-between;
      margin-top: $panel-margin;
    }
    .ske-left {
      .skeleton {
        margin-top: 1%;
      }
    }
  }
  .panel-result {
    margin-top: $panel-margin;
  }
}
@media screen and (min-width: 992px) and (max-width: 1439px) {
  .ske-left {
    width: 60%;
  }
  .ske-right {
    width: 35%;
  }
}
@media screen and (min-width: 1440px) and (max-width: 1599px) {
  .ske-left {
    width: 65%;
  }
  .ske-right {
    width: 30%;
  }
}
@media screen and (min-width: 1600px) and (max-width: 1919px) {
  .ske-left {
    width: 70%;
  }
  .ske-right {
    width: 25%;
  }
}
@media screen and (min-width: 1920px) {
  .ske-left {
    width: 75%;
  }
  .ske-right {
    width: 20%;
  }
}
</style>
