<template>
  <wrapper
    fill
    margin
    padding
    background
    horizontal
  >
    <device-tree-single
      class="c-sibling-item c-sidebar u-font-size--sm"
      @change="onChange"
    />
    <schema-table
      v-if="deviceId"
      ref="table"
      class="c-sibling-item far"
      row-key="id"
      :schema="schema"
    />
    <el-empty
      v-else
      class="l-flex__auto l-flex--row center c-sibling-item far"
      description="请选择设备"
    />
    <dataset-config-dialog ref="datasetConfigDialog" />
    <table-dialog
      ref="tableDialog"
      :title="title"
      size="lg"
      :schema="schedulingSchema"
    />
    <table-dialog
      ref="contentDialog"
      title="上播内容"
      :schema="contentSchema"
    />
    <preview-dialog ref="previewDialog" />
    <confirm-dialog
      ref="schedulingOptionsDialog"
      title="一键排单"
      @confirm="onConfirm"
    >
      <div class="c-grid-form auto u-align-self--center">
        <div class="c-grid-form__label">排单日期范围</div>
        <el-date-picker
          v-model="dateRange"
          type="daterange"
          range-separator="至"
          value-format="yyyy-MM-dd"
          :picker-options="pickerOptions"
          :editable="false"
          :clearable="false"
        />
      </div>
    </confirm-dialog>
  </wrapper>
</template>

<script>
import {
  TaskFromType,
  TaskFromTypeInfo,
  AssetTag,
  AssetTagInfo,
  AssetType,
  AssetTypeInfo
} from '@/constant'
import {
  parseTime,
  parseDuration
} from '@/utils'
import { getOrderDetail } from '../api'
import {
  createScheduling,
  getDeviceSchedulings,
  getDeviceScheduling,
  setSchedulingEnable
} from './api'
import DatasetConfigDialog from '../dataset/components/DatasetConfigDialog.vue'

const SchedulingStatus = {
  ERROR: 0,
  PROCESSING: 1,
  CREATED: 2,
  RESOLVED: 3
}

export default {
  name: 'AdScheduling',
  components: {
    DatasetConfigDialog
  },
  data () {
    const canEdit = this.$store.getters.isOperator
    const canAudit = this.$store.getters.isGroupAdmin

    return {
      deviceId: '',
      schema: {
        buttons: canEdit
          ? [
            { label: '填充素材包', on: this.onDataset },
            { label: '一键排单', on: this.onScheduling }
          ]
          : null,
        condition: { order: 'startDate' },
        list: this.getDeviceSchedulings,
        transform: this.transform,
        filters: [
          { key: 'order', type: 'select', options: [
            { value: 'startDate', label: '日期降序' },
            { value: 'createTime', label: '生成时间降序' }
          ] }
        ],
        cols: [
          { type: 'refresh' },
          { prop: 'startDate', label: '日期' },
          { prop: 'createTime', label: '生成时间' },
          { prop: 'statusTag', type: 'tag', on: (canEdit || canAudit) && this.onToggle },
          { prop: 'remark', label: '备注', 'align': 'right' },
          { type: 'invoke', render: [
            canAudit ? { label: '上架', render: ({ status, expired }) => !expired && status === SchedulingStatus.CREATED, on: this.onToggle } : null,
            canAudit ? { label: '下架', render: ({ status, expired }) => !expired && status === SchedulingStatus.RESOLVED, on: this.onToggle } : null,
            canEdit ? { label: '重编', render: ({ status, expired }) => !expired && status === SchedulingStatus.ERROR, on: this.onToggle } : null,
            { label: '详情', allow: ({ status }) => status !== SchedulingStatus.ERROR, on: this.onView }
          ].filter(Boolean) }
        ]
      },
      schedulingId: '',
      title: '',
      minDate: '',
      dateRange: [],
      contentSchema: {
        list: this.getContentAssets,
        cols: [
          { prop: 'tagType', label: '文件', width: 100, align: 'center' },
          { prop: 'fileType', label: '', width: 80 },
          { prop: 'file', label: '', type: 'asset', on: this.onViewAsset },
          { prop: 'name', label: '' },
          { prop: 'adDuration', label: '上播时长', width: 100, align: 'center' },
          { type: 'invoke', render: [
            { label: '查看', allow: ({ file }) => !!file, on: this.onViewAsset }
          ] }
        ]
      }
    }
  },
  computed: {
    schedulingSchema () {
      return {
        list: getDeviceScheduling,
        transform: this.transformScheduling,
        condition: { id: this.schedulingId },
        cols: [
          { prop: 'fromInfo', type: 'refresh', width: 80, align: 'center' },
          { prop: 'dataTag', label: '类型', width: 80, align: 'center' },
          { prop: 'dataType', label: '', width: 80, align: 'center' },
          { prop: 'file', label: '', type: 'asset', on: this.onViewAsset },
          { prop: 'originalName', label: '' },
          { prop: 'time', label: '时间', 'align': 'center' },
          { prop: 'tag', type: 'tag' },
          { type: 'invoke', render: [
            { label: '查看', allow: ({ relationBOS }) => relationBOS?.length, on: this.onViewDetail }
          ] }
        ]
      }
    },
    pickerOptions () {
      return {
        disabledDate: this.isDisableDate
      }
    }
  },
  watch: {
    deviceId () {
      this.$refs.table?.pageTo(1)
    }
  },
  methods: {
    onChange ({ id }) {
      this.deviceId = id
    },
    getDeviceSchedulings (params) {
      return getDeviceSchedulings({
        deviceId: this.deviceId,
        ...params
      })
    },
    isDisableDate (date) {
      return date < this.minDate
    },
    onDataset () {
      this.$refs.datasetConfigDialog.show({ id: this.deviceId })
    },
    onScheduling () {
      const date = parseTime(new Date(), '{y}-{m}-{d}')
      this.minDate = new Date(`${date} 00:00:00`)
      this.dateRange = [date, date]
      this.$refs.schedulingOptionsDialog.show()
    },
    onConfirm (done) {
      this.$confirm(
        '新生成的节目单将覆盖原有节目单但不影响已下发的数据，确认继续？',
        '一键排单',
        { type: 'warning' }
      ).then(() => this.createScheduling(this.dateRange[0], this.dateRange[1])).then(done)
    },
    createScheduling (startDate, endDate) {
      createScheduling([this.deviceId], {
        startDate,
        endDate: endDate || startDate
      }).then(() => {
        this.$refs.table.pageTo()
      })
    },
    transform (scheduling) {
      const expired = scheduling.startDate < parseTime(new Date(), '{y}-{m}-{d}')
      scheduling.expired = expired
      scheduling.statusTag = this.getStatusTag(scheduling.status, expired)
      return scheduling
    },
    getStatusTag (status, hasExpired) {
      return {
        label: ['生成失败', '生成中', hasExpired ? '未发布' : '待发布', hasExpired ? '已生效' : '生效中'][status],
        type: hasExpired ? null : ['danger', 'primary', 'warning', 'success'][status]
      }
    },
    onView ({ id, startDate, status }) {
      if (status === 0) {
        return
      }
      this.title = startDate
      this.schedulingId = id
      this.$refs.tableDialog.show()
    },
    transformScheduling (data) {
      const { from, startTime, endTime } = data
      data.fromInfo = TaskFromTypeInfo[from] || '未知'
      data.dataTag = this.getDataTag(data)
      data.dataType = this.getDataType(data)
      data.file = this.getDataFile(data)
      data.time = `${startTime}-${endTime}`
      data.tag = this.getTag(data)
      return data
    },
    getDataTag ({ from, relationBOS }) {
      switch (from) {
        case TaskFromType.ORDER:
          return AssetTagInfo[AssetTag.AD]
        case TaskFromType.FILL:
        case TaskFromType.ASSET:
          return relationBOS?.[0] ? AssetTagInfo[relationBOS[0].tag] : '-'
        default:
          return '-'
      }
    },
    getDataType ({ from, relationBOS }) {
      switch (from) {
        case TaskFromType.FILL:
        case TaskFromType.ASSET:
          return relationBOS?.[0] ? AssetTypeInfo[relationBOS[0].type] : '-'
        default:
          return '素材包'
      }
    },
    getDataFile ({ from, relationBOS }) {
      switch (from) {
        case TaskFromType.FILL:
        case TaskFromType.ASSET:
          return relationBOS?.[0] && {
            type: relationBOS[0].type,
            url: relationBOS[0].keyName
          }
        default:
          return null
      }
    },
    getTag ({ relationBOS }) {
      return relationBOS?.length
        ? {
          type: 'success',
          label: '成功'
        }
        : {
          type: 'primary',
          label: '生成中'
        }
    },
    onViewDetail (detail) {
      switch (detail.from) {
        case TaskFromType.ORDER:
        case TaskFromType.CONTRACT:
          this.getContent(detail)
          break
        case TaskFromType.FILL:
        case TaskFromType.ASSET:
          this.onViewAsset(detail)
          break
        default:
          break
      }
    },
    getContent ({ from, fromId, relationBOS }) {
      if (fromId === this.$fromId) {
        this.$refs.contentDialog.show()
        return
      }
      switch (from) {
        case TaskFromType.ORDER:
          getOrderDetail(fromId).then(({ data }) => {
            this.showContentDialog(fromId, data.assets.map(this.transformOrderAsset))
          })
          break
        case TaskFromType.CONTRACT:
          this.showContentDialog(fromId, relationBOS.map(this.transformContractAsset))
          break
        default:
          break
      }
    },
    showContentDialog (fromId, assets) {
      this.$fromId = fromId
      if (assets.length === 1) {
        assets[0].adDuration = '独占'
      }
      this.$assets = assets
      this.$refs.contentDialog.show()
    },
    getContentAssets () {
      const assets = this.$assets
      return Promise.resolve({
        data: assets,
        totalCount: assets.length
      })
    },
    transformOrderAsset ({ type, keyName, adDuration, thumb }) {
      const isImage = type === AssetType.IMAGE
      return type
        ? {
          tagType: AssetTagInfo[AssetTag.AD],
          fileType: AssetTypeInfo[type],
          file: {
            type,
            url: keyName,
            thumb: isImage ? keyName : thumb,
            origin: !isImage
          },
          adDuration: parseDuration(adDuration)
        }
        : {
          tagType: '素材已删除',
          adDuration: parseDuration(adDuration)
        }
    },
    transformContractAsset ({ tag, type, keyName, originalName, duration }) {
      return {
        tagType: AssetTagInfo[tag],
        fileType: AssetTypeInfo[type],
        file: {
          type,
          url: keyName
        },
        name: originalName,
        adDuration: parseDuration(duration)
      }
    },
    onViewAsset ({ file }) {
      this.$refs.previewDialog.show(file)
    },
    onToggle (scheduling) {
      if (scheduling.status === SchedulingStatus.ERROR) {
        this.$confirm(
          '重新生成节目单？',
          { type: 'warning' }
        ).then(() => {
          this.createScheduling(scheduling.startDate)
        })
        return
      }
      if (scheduling.status === SchedulingStatus.PROCESSING) {
        return
      }
      const enable = scheduling.status === SchedulingStatus.CREATED
      setSchedulingEnable(scheduling, enable).then(() => {
        scheduling.status = enable ? SchedulingStatus.RESOLVED : SchedulingStatus.CREATED
        scheduling.statusTag = this.getStatusTag(scheduling.status)
      })
    }
  }
}
</script>
