<template>
  <wrapper
    v-loading="loading"
    class="c-step"
    fill
    margin
    padding
    background
  >
    <div class="l-flex__none l-flex--row c-sibling-item--v u-color--black">
      <i
        class="l-flex__none c-sibling-item o-icon o-icon--hover el-icon-arrow-left u-pointer u-bold"
        @click="onBack"
      />
      <span
        v-if="title"
        class="c-sibling-item near u-font-size--md u-bold"
      >
        {{ title }}
      </span>
    </div>
    <status-wrapper
      v-if="loading || error"
      :error="error"
      @click="getWorkflow"
    />
    <template v-else>
      <template v-if="audit === 0">
        <div class="l-flex__none c-sibling-item--v">
          <schema-table :schema="schema" />
        </div>
        <div class="l-flex__fill l-flex c-sibling-item--v far">
          <div class="l-flex__none l-flex--col c-sibling-item u-width--md">
            <schema-table :schema="deviceSchema" />
          </div>
          <div class="l-flex__none l-flex--col c-sibling-item u-width--lg">
            <schema-table :schema="timeSchema" />
          </div>
          <template v-if="hasAssets">
            <div class="l-flex__fill l-flex--col c-sibling-item">
              <schema-table :schema="assetSchema" />
            </div>
            <preview-dialog ref="previewDialog" />
          </template>
        </div>
      </template>
      <div
        v-if="audit === 1"
        class="has-padding"
      >
        <el-result
          icon="success"
          title="审核成功"
        >
          <template slot="extra">
            <el-link
              type="primary"
              @click="onBack"
            >
              返回列表
            </el-link>
          </template>
        </el-result>
      </div>
      <material-dialog ref="materialDialog" />
      <confirm-dialog
        ref="rejectDialog"
        title="驳回"
        @confirm="onConfirmReject"
      >
        <div class="c-grid-form u-align-self--center">
          <span class="c-grid-form__label">审核意见</span>
          <el-select
            v-model="review.type"
            placeholder="请选择"
          >
            <el-option
              v-for="option in reviewOptions"
              :key="option.label"
              :label="option.label"
              :value="option.value"
            />
          </el-select>
          <template v-if="review.type === 'reject'">
            <span class="c-grid-form__label u-required">原因</span>
            <el-input
              v-model.trim="review.reason"
              type="textarea"
              placeholder="请填写驳回原因"
              maxlength="50"
              :rows="3"
              resize="none"
              show-word-limit
            />
          </template>
        </div>
      </confirm-dialog>
    </template>
  </wrapper>
</template>

<script>
import { mapGetters } from 'vuex'
import {
  State,
  Access,
  WorkflowState,
  WorkflowStateInfo,
  PublishTargetType,
  EventTarget,
  AssetTagInfo,
  AssetTypeInfo
} from '@/constant'
import { parseDuration } from '@/utils'
import { parseDeploy } from '../utils'
import {
  getWorkflow,
  resolveWorkflow,
  rejectWorkflow,
  getAssetsByProgramSnap
} from '../api'

export default {
  name: 'WorkflowAudit',
  data () {
    return {
      loading: true,
      error: false,
      workflow: null,
      audit: -1,
      deviceSchema: {
        nonPagination: true,
        props: {
          size: 'small'
        },
        list: this.getDevices,
        cols: [
          { prop: 'deviceName', label: '上播设备', 'show-overflow-tooltip': false }
        ]
      },
      timeSchema: {
        nonPagination: true,
        props: {
          size: 'small'
        },
        list: this.getTimes,
        cols: [
          { prop: 'time', label: '上播时间', 'show-overflow-tooltip': false }
        ]
      },
      assetSchema: {
        nonPagination: true,
        props: {
          size: 'small'
        },
        list: this.getAssets,
        cols: [
          { prop: 'tagInfo', label: '类型', width: 72, align: 'center' },
          { prop: 'typeInfo', label: '资源', width: 72, align: 'center' },
          { prop: 'file', label: '', type: 'asset', on: this.onViewAsset },
          { prop: 'name', label: '' },
          { prop: 'adDuration', label: '上播时长', width: 80, align: 'center' },
          { type: 'invoke', render: [
            { label: '查看', allow: ({ file }) => !!file, on: this.onViewAsset }
          ] }
        ]
      },
      reviewOptions: [
        { value: 'reject', label: '驳回' },
        { value: '图文不符' },
        { value: '内容不合规' }
      ],
      review: {
        type: '',
        reason: ''
      }
    }
  },
  computed: {
    ...mapGetters(['access']),
    id () {
      return this.$route.params.id
    },
    status () {
      const isFinal = this.access.has(Access.REVIEW_RELEASE_FINAL)
      if (__JUMP_REVIEW__ && isFinal) {
        return [WorkflowState.FIRST_LEVEL, WorkflowState.SECOND_LEVEL, WorkflowState.FINAL_LEVEL]
      }
      const arr = []
      if (isFinal) {
        arr.push(WorkflowState.FIRST_LEVEL)
      }
      if (this.access.has(Access.REVIEW_RELEASE_SECOND)) {
        arr.push(WorkflowState.SECOND_LEVEL)
      }
      if (this.access.has(Access.REVIEW_RELEASE_FIRST)) {
        arr.push(WorkflowState.FINAL_LEVEL)
      }
      return arr
    },
    title () {
      if (__JUMP_REVIEW__ && this.access.has(Access.REVIEW_RELEASE_FINAL)) {
        return '审核'
      }
      if (this.workflow) {
        return WorkflowStateInfo[this.workflow.currentSeveralReviewed]
      }
      return ''
    },
    isProgram () {
      if (this.workflow) {
        return this.workflow.options.publish === PublishTargetType.EVENT && this.workflow.options.event === EventTarget.PROGRAM
      }
      return false
    },
    isAssets () {
      if (this.workflow) {
        return this.workflow.options.publish === PublishTargetType.EVENT && this.workflow.options.event === EventTarget.ASSETS
      }
      return false
    },
    needView () {
      if (this.workflow) {
        return this.workflow.options.publish === PublishTargetType.CALENDAR || this.isProgram
      }
      return false
    },
    hasAssets () {
      return this.isProgram || this.isAssets
    },
    schema () {
      return {
        nonPagination: true,
        list: this.getList,
        cols: [
          { prop: 'priority', label: '优先级', width: 100, align: 'center' },
          { prop: 'type', label: '上播内容', width: 80, align: 'center' },
          { prop: 'name', label: '' },
          { prop: 'ratio', label: '适配', width: 120 },
          { prop: 'user', label: '申请人', width: 160, align: 'center' },
          { type: 'invoke', render: [
            this.needView && { label: '查看', on: this.onView },
            { label: '通过', on: this.onResolve },
            { label: '驳回', on: this.onReject }
          ].filter(Boolean), width: 160 }
        ]
      }
    },
    workflowNodeId () {
      // 待审核节点
      return this.workflow?.nodes.find(({ status }) => status === State.SUBMITTED)?.id
    }
  },
  created () {
    this.getWorkflow()
  },
  methods: {
    getWorkflow () {
      this.loading = true
      this.error = false
      getWorkflow(this.id).then(
        ({ data }) => {
          if (data.status === State.SUBMITTED && this.status.includes(data.currentSeveralReviewed)) {
            this.workflow = {
              id: data.id,
              user: data.createUser,
              currentSeveralReviewed: data.currentSeveralReviewed,
              nodes: data.workflowNodeDtoList,
              ...parseDeploy(data.businessData)
            }
            this.audit = 0
            this.loading = false
          } else {
            this.$message({
              type: 'warning',
              message: '流程已结束或无审核权限'
            })
            this.onBack()
          }
        },
        () => {
          this.error = true
          this.loading = false
        }
      )
    },
    getList () {
      return Promise.resolve({ data: [this.workflow] })
    },
    getDevices () {
      return Promise.resolve({ data: this.workflow.deviceList })
    },
    getTimes () {
      return Promise.resolve({ data: this.workflow.targetList })
    },
    onView ({ detail }) {
      this.$refs.materialDialog.showPublishTarget(detail)
    },
    getAssets () {
      if (this.isAssets) {
        const assets = this.workflow.detail.detail.target.sources.map(this.transformAsset)
        if (assets.length === 1) {
          assets[0].adDuration = '独占'
        }
        return Promise.resolve({ data: Object.freeze(assets) })
      }
      if (this.isProgram) {
        return getAssetsByProgramSnap(this.workflow.detail.detail.target.id).then(({ data }) => {
          return {
            data: data.map(this.transformAsset)
          }
        })
      }
      return Promise.resolve({ data: [] })
    },
    transformAsset ({ tag, type, keyName, name, originalName, duration }) {
      if (!type) {
        return {
          name: '资源已删除'
        }
      }
      return {
        tagInfo: AssetTagInfo[tag],
        typeInfo: AssetTypeInfo[type],
        file: {
          type,
          url: keyName
        },
        name: name || originalName,
        adDuration: parseDuration(duration)
      }
    },
    onViewAsset ({ file }) {
      this.$refs.previewDialog.show(file)
    },
    onBack () {
      this.$router.replace({ name: 'workflow-list' })
    },
    resolveWorkflow () {
      return resolveWorkflow(this.workflowNodeId)
    },
    onResolve () {
      this.$confirm(
        '审核通过？',
        '操作确认',
        { type: 'warning' }
      ).then(() => {
        this.resolveWorkflow().then(() => {
          this.audit = 1
        })
      })
    },
    onReject () {
      this.review = {
        type: 'reject',
        reason: ''
      }
      this.$refs.rejectDialog.show()
    },
    onConfirmReject (done) {
      const reason = this.review.type === 'reject' ? this.review.reason : this.review.type
      if (!reason) {
        this.$message({
          type: 'warning',
          message: '请选择或填写驳回原因'
        })
        return
      }
      rejectWorkflow(this.workflowNodeId, reason).then(() => {
        done()
        this.audit = 1
      })
    }
  }
}
</script>
