<template>
  <div class="l-flex__fill l-flex--col">
    <schema-table
      ref="table"
      class="l-flex__none c-sibling-item--v"
      :schema="schema"
    />
    <div class="l-flex__fill c-sibling-item--v u-overflow-y--auto">
      <div class="c-sibling-item--v u-font-size--sm u-color--black u-bold">目标设备</div>
      <div class="c-sibling-item--v near c-devices u-color--info">
        <div
          v-for="device in devices"
          :key="device.deviceId"
          class="l-flex__self u-ellipsis"
        >
          {{ device.deviceName }}
        </div>
      </div>
      <template v-if="targetContent">
        <div class="c-sibling-item--v u-font-size--sm u-color--black u-bold">上播内容</div>
        <template v-if="isProgram || isAssets">
          <schema-table
            class="c-sibling-item--v near"
            :schema="contentSchema"
          />
          <preview-dialog ref="previewDialog" />
        </template>
        <schedule
          v-else
          class="c-sibling-item--v"
          :schedule="targetContent"
          hide-header
        />
      </template>
    </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>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import {
  PublishTargetType,
  EventTarget,
  AssetTagInfo,
  AssetTypeInfo,
  Access,
  State,
  JUMP_REVIEW
} from '@/constant'
import {
  parseByte,
  parseDuration,
  getAssetThumb,
  getAssetDiff,
  getAIState
} from '@/utils'
import {
  resolveFirstLevel,
  rejectFirstLevel,
  resolveSecondLevel,
  rejectSecondLevel,
  resolveFinal,
  rejectFinal
} from '../../api'
import { transformCalendarRelease } from '../../utils'
import mixin from './mixin'

export default {
  name: 'WorkflowReviewPublish',
  mixins: [mixin],
  data () {
    return {
      solo: false,
      assetSchema: {
        nonPagination: true,
        list: this.getContentAssets,
        cols: [
          { prop: 'tagInfo', label: '类型', width: 80, align: 'center' },
          { prop: 'typeInfo', label: '资源', width: 72, align: 'center' },
          { prop: 'file', label: '', type: 'asset', on: this.onViewAsset },
          { prop: 'name', label: '' },
          { prop: 'adDuration', label: '上播时长', 'min-width': 60, align: 'center' },
          { type: 'invoke', render: [
            { label: '查看', allow: ({ file }) => !!file, on: this.onViewAsset }
          ] }
        ]
      },
      programAssetSchema: {
        nonPaination: true,
        list: this.getContentAssets,
        cols: [
          { prop: 'tagInfo', label: '类型', width: 80, align: 'center' },
          { prop: 'typeInfo', label: '资源', width: 72, align: 'center' },
          { prop: 'file', label: '', type: 'asset', on: this.onViewAsset },
          { prop: 'originalName', label: '' },
          { prop: 'ai', label: 'AI审核', type: 'tag' },
          { prop: 'size', label: '文件大小', align: 'right' },
          { prop: 'diff', label: '其他', align: 'center' },
          { type: 'invoke', render: [
            { label: '查看', on: this.onViewAsset }
          ] }
        ]
      },
      reviewOptions: [
        { value: 'reject', label: '驳回' },
        { value: '图文不符' },
        { value: '内容不合规' }
      ],
      review: {
        type: '',
        reason: ''
      }
    }
  },
  computed: {
    ...mapGetters(['access']),
    schema () {
      return {
        list: this.getList,
        cols: [
          { prop: 'priority', label: '优先级', width: 80, align: 'center' },
          { prop: 'priorityInfo', label: '', width: 80, align: 'center' },
          { prop: 'targetInfo', label: '上播内容', width: 80, align: 'center' },
          this.programScreenshot && { label: '缩略图', type: 'asset', render: () => {
            return {
              thumb: this.programScreenshot
            }
          }, on: this.onView },
          !this.isAssets && { prop: 'targetName', label: '' },
          { prop: 'desc', label: '上播时间', 'min-width': 160 },
          { type: 'invoke', render: [
            this.isProgram && { label: '查看', on: this.onView },
            { label: '通过', on: this.onResolve },
            { label: '驳回', on: this.onReject }
          ].filter(Boolean), width: this.isProgram ? 160 : 120 }
        ]
      }
    },
    contentSchema () {
      return this.isProgram ? this.programAssetSchema : this.assetSchema
    },
    devices () {
      return this.list?.[0].devices
    },
    status () {
      return this.workflow.status
    },
    isSecondLevel () {
      return this.status === State.FIRST_LEVEL
    },
    isFinalLevel () {
      return this.status === State.SECOND_LEVEL
    },
    resolveInvoke () {
      if (JUMP_REVIEW && this.access.has(Access.REVIEW_RELEASE_FINAL)) {
        return resolveFinal
      }
      switch (this.workflow.status) {
        case State.SUBMITTED:
          return resolveFirstLevel
        case State.FIRST_LEVEL:
          return resolveSecondLevel
        default:
          return resolveFinal
      }
    },
    rejectInvoke () {
      if (JUMP_REVIEW && this.access.has(Access.REVIEW_RELEASE_FINAL)) {
        return rejectFinal
      }
      switch (this.workflow.status) {
        case State.SUBMITTED:
          return rejectFirstLevel
        case State.FIRST_LEVEL:
          return rejectSecondLevel
        default:
          return rejectFinal
      }
    },
    publishTarget () {
      return this.list?.[0].target
    },
    isEvent () {
      return this.publishTarget?.type === PublishTargetType.EVENT
    },
    isProgram () {
      return this.isEvent && this.publishTarget.detail.target.type === EventTarget.PROGRAM
    },
    programScreenshot () {
      if (this.isProgram && this.workflow.items?.length) {
        return this.workflow.items[0].img
      }
      return null
    },
    isAssets () {
      return this.isEvent && this.publishTarget.detail.target.type === EventTarget.ASSETS
    },
    targetContent () {
      if (this.isEvent) {
        const target = this.publishTarget.detail.target
        let content = null
        switch (target.type) {
          case EventTarget.PROGRAM:
            content = this.workflow.minios?.map(this.transformProgramAsset)
            break
          case EventTarget.RECUR:
            content = target.id
            break
          case EventTarget.ASSETS:
            content = target.sources.map(this.transformAsset)
            if (content.length === 1) {
              content[0].adDuration = '独占'
            }
            break
          default:
            break
        }
        return content
      }
      return this.publishTarget?.detail
    }
  },
  created () {
    this.list = [this.transformItem(this.workflow.calendarReleaseScheduling)]
  },
  methods: {
    transformItem (item) {
      return transformCalendarRelease(item, {
        ignoreDeviceTransform: true
      })
    },
    transformProgramAsset (asset) {
      return {
        tagInfo: AssetTagInfo[asset.tag],
        typeInfo: AssetTypeInfo[asset.type],
        file: {
          type: asset.type,
          url: asset.keyName,
          thumb: getAssetThumb(asset),
          files: (asset.childrenData || []).map(({ type, keyName }) => {
            return { type, url: keyName }
          })
        },
        originalName: asset.originalName,
        ai: getAIState(asset),
        size: parseByte(asset.size),
        diff: getAssetDiff(asset)
      }
    },
    onView ({ target }) {
      this.$refs.materialDialog.showPublishTarget(target)
    },
    onViewAsset ({ file }) {
      this.$refs.previewDialog.show(file)
    },
    transformAsset ({ tag, type, keyName, name, duration }) {
      return {
        tagInfo: AssetTagInfo[tag],
        typeInfo: AssetTypeInfo[type],
        file: {
          type,
          url: keyName
        },
        name,
        adDuration: parseDuration(duration)
      }
    },
    getContentAssets () {
      return Promise.resolve({ data: this.targetContent })
    },
    onResolve () {
      this.$confirm(
        '审核通过？',
        '操作确认',
        { type: 'warning' }
      ).then(() => {
        this.resolveInvoke(this.workflow.workflowId).then(() => {
          this.$emit('finish')
        })
      })
    },
    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
      }
      this.rejectInvoke(this.workflow.workflowId, reason).then(() => {
        done()
        this.$message({
          type: 'success',
          message: '流程驳回成功'
        })
        this.$router.replace({ name: 'workflow-list' })
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.c-devices {
  display: flex;
  flex-wrap: wrap;
  gap: $spacing--xs;
}
</style>
