<template>
  <wrapper
    fill
    margin
    padding
    background
  >
    <el-tabs
      :value="active"
      class="c-tabs has-bottom-padding"
      @tab-click="onTabClick"
    >
      <el-tab-pane
        label="待审核"
        name="1"
      />
      <el-tab-pane
        label="已审核"
        name="2"
      />
      <el-tab-pane
        label="驳回"
        name="3"
      />
    </el-tabs>
    <schema-table
      ref="table"
      :schema="schema"
      @row-click="onToggle"
    />
    <preview-dialog ref="previewDialog" />
    <program-dialog ref="programDialog" />
    <schedule-dialog ref="scheduleDialog" />
    <table-dialog
      ref="tableDialog"
      title="流程历史"
      :schema="historySchema"
    />
  </wrapper>
</template>

<script>
import {
  getMyWorkflows,
  calendarPublishRestart,
  viewHistory,
  deleteWorkflow
} from '@/api/workflow'
import {
  PublishType,
  EventPriority,
  State,
  EventTarget
} from '@/constant'
import { getEventDescription } from '@/utils/event'

const Category = {
  minio: '媒资',
  item: '节目',
  carousel: '轮播',
  program: '排期'
}

export default {
  name: 'MyWorkflows',
  data () {
    return {
      active: `${State.SUBMITTED}`,
      workflowId: ''
    }
  },
  computed: {
    isRejected () {
      return this.active === `${State.REJECTED}`
    },
    schema () {
      const isRejected = this.isRejected

      return {
        condition: { status: Number(this.active) },
        list: getMyWorkflows,
        transform: this.transform,
        cols: [
          { type: 'expand', refresh: true, render: this.renderRelative },
          { prop: 'type', label: '类型', align: 'center', width: 100 },
          { prop: 'name', label: '', 'min-width': 100 },
          { prop: 'updateTime', label: this.active === `${State.SUBMITTED}` ? '提交时间' : '审批时间' },
          isRejected ? { prop: 'reason', label: '驳回原因', 'min-width': 100 } : null,
          { type: 'invoke', width: isRejected ? 200 : 120, render: [
            isRejected ? { label: '编辑', render: ({ canResubmit }) => canResubmit, on: this.onEdit } : { label: '查看', on: this.onView },
            isRejected ? { label: '重提交', render: ({ canResubmit }) => canResubmit, on: this.onResubmit } : null,
            { label: '历史', on: this.onViewHistory },
            isRejected ? { label: '删除', on: this.onDel } : null
          ].filter(Boolean) }
        ]
      }
    },
    historySchema () {
      return {
        props: { rowClassName: this.isShowExpend },
        listeners: { 'row-click': this.onToggleHistory },
        condition: { workflowId: this.workflowId },
        list: viewHistory,
        transform: this.transformHistory,
        cols: [
          { type: 'expand', render: this.renderReason },
          { prop: 'handledBy', label: '处理人', width: 100 },
          { prop: 'createTime', label: '时间' },
          { prop: 'tag', label: '状态', type: 'tag' },
          { prop: 'reason', label: '备注' }
        ]
      }
    }
  },
  methods: {
    isShowExpend ({ row }) {
      if (row.status !== State.REJECTED) {
        return 'hide-expend'
      }
      return ''
    },
    renderRelative (data, h) {
      return h('div', { staticClass: 'o-info' }, [
        h('div', null, data.desc),
        h('div', { staticClass: 'c-sibling-item--v' }, `设备：${data.device}`),
        ...(this.isRejected
          ? this.renderRelativeItems(data, h, false)
          : [])
      ])
    },
    renderReason (data, h) {
      return data.status === State.REJECTED
        ? h('div', { staticClass: 'o-info' }, [
          ...this.renderRelativeItems(data, h)
        ])
        : null
    },
    renderRelativeItems (data, h, isView = true) {
      const children = []
      if (data.status === State.REJECTED) {
        if (data.canResubmit) {
          if (data.rejectEvent?.length) {
            children.push(h('div', {
              staticClass: 'c-sibling-item--v'
            }, '驳回对象：'))
            children.push(
              h('div', {
                staticClass: 'l-flex--col',
                staticStyle: { 'align-items': 'flex-start' }
              }, data.rejectEvent.map(item => this.renderRejectItem(item, h, isView)))
            )
          }
        } else {
          children.push(h('div', {
            staticClass: 'c-sibling-item--v u-color--error'
          }, '发布驳回'))
        }
      }
      return children
    },
    renderRejectItem (item, h, isView = false) {
      const category = Category[item.category]
      const canClick = !isView && !!category
      return h('div', {
        staticClass: canClick ? 'u-color--blue u-pointer' : 'u-color--black',
        staticStyle: { padding: '4px 0' },
        on: canClick
          ? {
            click: $event => {
              $event.stopPropagation()
              this.onViewOrEditItem(item)
            }
          }
          : null
      }, `${category || ''} ${item.name}`)
    },
    onViewHistory ({ workflowId }) {
      this.workflowId = workflowId
      this.$refs.tableDialog.show()
    },
    onTabClick ({ name: active }) {
      if (this.active !== active) {
        this.active = active
      }
    },
    transform (data) {
      return {
        ...this.getDiff(data.calendarRelease),
        ...this.getStatus(data),
        workflowId: data.id,
        updateTime: data.updateTime
      }
    },
    transformHistory (data) {
      const { status } = data
      return {
        ...data,
        ...this.getStatus(data),
        tag: {
          type: ['', 'primary', 'success', 'danger'][status],
          label: ['草稿', '提交', '通过', '驳回'][status]
        }
      }
    },
    getStatus ({ status, rejectEvent, reason }) {
      if (status === State.REJECTED) {
        const events = JSON.parse(rejectEvent)
        const canResubmit = !(events && events.length === 1 && events[0].category === 'calendar')
        return {
          status,
          canResubmit,
          rejectEvent: (events || []).filter(({ category }) => category !== 'calendar'),
          reason
        }
      }
      return {
        status,
        canResubmit: false
      }
    },
    getDiff (item) {
      const target = JSON.parse(item.target)
      let type = ''
      switch (target.type) {
        case PublishType.CALENDAR:
          type = '排期'
          break
        case PublishType.EVENT:
          type = ['', '默认播放', '单播', '插播'][target.detail.priority]
          break
        default:
          break
      }
      return {
        name: item.programCalendarName,
        type,
        target,
        desc: this.getDesc(target),
        device: item.calendarReleaseDeviceList?.map(({ deviceName }) => deviceName).join('，')
      }
    },
    getDesc (target) {
      if (target.type === PublishType.EVENT && target.detail.priority === EventPriority.INSERTED) {
        return getEventDescription(target.detail)
      }
      return ''
    },
    onToggle (row) {
      this.$refs.table.getInst().toggleRowExpansion(row)
    },
    onToggleHistory (row) {
      if (row.status === State.REJECTED) {
        this.$refs.tableDialog.getTable().getInst().toggleRowExpansion(row)
      }
    },
    onView ({ target: { type, detail } }) {
      switch (type) {
        case PublishType.CALENDAR:
          this.$refs.scheduleDialog.show(detail)
          break
        case PublishType.EVENT:
          if (detail.target.type === EventTarget.RECUR) {
            this.$refs.scheduleDialog.show(detail.target.id)
          } else {
            this.$refs.programDialog.show(detail.target.id)
          }
          break
        default:
          break
      }
    },
    onEdit ({ target: { type, detail } }) {
      switch (type) {
        case PublishType.CALENDAR:
          this.$router.push({
            name: 'schedule-design',
            params: { id: detail }
          })
          break
        case PublishType.EVENT:
          if (detail.target.type === EventTarget.RECUR) {
            this.$router.push({
              name: 'recur-design',
              params: { id: detail.target.id }
            })
          } else {
            this.$designProgram(detail.target.id)
          }
          break
        default:
          break
      }
    },
    onViewOrEditItem (data) {
      switch (data.category) {
        case 'minio':
          this.$refs.previewDialog.show({
            type: data.type,
            url: data.id
          })
          break
        case 'item':
          this.$designProgram(data.id)
          break
        case 'carousel':
          this.$router.push({
            name: 'recur-design',
            params: { id: data.id }
          })
          break
        case 'program':
          this.$router.push({
            name: 'schedule-design',
            params: { id: data.id }
          })
          break
        default:
          break
      }
    },
    onResubmit (item) {
      calendarPublishRestart(item.workflowId, item.name).then(() => {
        this.$refs.table.decrease(1)
      })
    },
    onDel ({ workflowId }) {
      deleteWorkflow(workflowId).then(() => {
        this.$refs.table.decrease(1)
      })
    }
  }
}
</script>
<style lang="scss" scoped>
::v-deep .hide-expend .el-table__expand-icon {
  display: none;
}
</style>
