<template>
  <div class="l-flex--col">
    <div class="c-sibling-item--v has-bottom-padding--sm has-bottom-border">
      <div
        class="l-flex--row inline c-sibling-item--v u-font-size--sm u-bold"
        :class="{ 'has-active': isAssets }"
        @click="onEditAssets"
      >
        <span class="c-sibling-item">上播内容</span>
        <i
          v-if="isAssets"
          class="c-sibling-item near el-icon-edit"
        />
      </div>
      <div class="l-flex--row c-sibling-item--v near">
        <el-select
          v-model="currentTarget.type"
          class="l-flex__none c-sibling-item u-width--sm"
          @change="onChangeTargetType"
        >
          <el-option
            v-for="option in eventTypeOptions"
            :key="option.value"
            :label="option.label"
            :value="option.value"
          />
        </el-select>
        <template v-if="isAssets">
          <div
            class="l-flex__none c-sibling-item o-button"
            @click="onImportDataset"
          >
            导入
          </div>
          <div class="l-flex__fill l-flex--row right c-sibling-item u-font-size--sm u-color-black u-bold">
            {{ statistics }}
          </div>
        </template>
        <div
          v-else
          class="l-flex__auto l-flex--row c-sibling-item far"
        >
          <div
            class="has-active u-ellipsis"
            @click="onViewCurrentTarget"
          >
            {{ targetInfo }}
          </div>
        </div>
      </div>
    </div>
    <template v-if="isAssets">
      <template v-if="currentTarget.assets.length">
        <draggable
          v-model="currentTarget.assets"
          class="l-flex__fill c-sibling-item--v u-overflow-y--auto"
          handle=".mover"
          animation="300"
        >
          <draggable-item
            v-for="(asset, index) in currentTarget.assets"
            :key="asset.key"
            :item="asset"
            @view="onViewAsset"
            @del="onDelAsset(index)"
          />
        </draggable>
      </template>
      <el-empty
        v-else
        class="l-flex__fill l-flex--row center"
        description="请添加资源"
      />
    </template>
    <schema-table
      v-else
      :key="currentTarget.type"
      class="c-sibling-item--v"
      :schema="schema"
      row-key="id"
      :current-row-key="selectedId"
      highlight-current-row
      @row-click="onClickRow"
    />
    <multi-asset-transfer-dialog
      ref="transferDialog"
      title="上播内容"
      :choosen="onSaveAssets"
      ignore-duration
      @view="onViewAsset"
    />
    <radio-table-dialog
      ref="datasetDialog"
      title="素材包"
      message="请选择素材包"
      :schema="datasetSchema"
      append-to-body
      @confirm="onChoosenDataset"
    />
    <table-dialog
      ref="contentDialog"
      title="素材包"
      :schema="contentSchema"
      append-to-body
    />
    <preview-dialog ref="previewDialog" />
    <material-dialog ref="materialDialog" />
  </div>
</template>

<script>
import {
  State,
  ScheduleType,
  EventTarget,
  EventTargetInfo,
  AssetTagInfo,
  AssetType,
  AssetTypeInfo,
  Dataset
} from '@/constant'
import { transformDatasetAssetToAsset } from '@/utils'
import { getRatios } from '@/api/device'
import {
  getDatasets,
  getCommonDataset
} from '@/api/asset'
import { getPrograms } from '@/api/program'
import { getSchedules } from '@/api/calendar'
import Draggable from 'vuedraggable'

export default {
  name: 'EventTargetPicker',
  components: {
    Draggable
  },
  props: {
    eventTarget: {
      type: Object,
      default: null
    },
    ratio: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      eventTypeOptions: [
        { value: EventTarget.ASSETS, label: EventTargetInfo[EventTarget.ASSETS] },
        { value: EventTarget.PROGRAM, label: EventTargetInfo[EventTarget.PROGRAM] }/* ,
        { value: EventTarget.RECUR, label: EventTargetInfo[EventTarget.RECUR] } */
      ],
      currentTarget: null,
      datasetSchema: {
        list: getDatasets,
        condition: { type: Dataset.COMMON },
        cols: [
          { prop: 'name', label: '名称', 'align': 'center' },
          { type: 'invoke', render: [
            { label: '查看', on: this.onViewDataset }
          ] }
        ]
      },
      contentSchema: {
        singlePage: true,
        list: this.getAssets,
        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: 'duration', label: '上播时长', 'align': 'center', width: 100 },
          { type: 'invoke', render: [
            { label: '查看', allow: ({ minioData }) => !!minioData, on: this.onViewAsset }
          ] }
        ]
      }
    }
  },
  computed: {
    isAssets () {
      return this.currentTarget?.type === EventTarget.ASSETS
    },
    statistics () {
      if (this.isAssets) {
        const assets = this.currentTarget.assets
        const length = assets.length
        return `共${length}条，总时长${assets.reduce((total, { duration }) => total + duration, 0)}秒`
      }
      return ''
    },
    selectedId () {
      return this.currentTarget?.detail?.id
    },
    targetInfo () {
      if (this.isAssets) {
        return ''
      }
      return this.currentTarget?.detail
        ? this.currentTarget.detail.name || '未知'
        : ''
    },
    schema () {
      if (!this.currentTarget) {
        return {}
      }
      const { type } = this.currentTarget

      return {
        list: this.getListInvoke,
        condition: { resolutionRatio: this.ratio, name: '' },
        filters: [
          { key: 'resolutionRatio', type: 'select', placeholder: '分辨率', remote: getRatios },
          { key: 'name', type: 'search', placeholder: '名称' }
        ],
        cols: [
          { render: ({ id }, h) => h(
            'span',
            { staticClass: `el-radio__input ${id === this.selectedId ? 'is-checked' : ''}` },
            [h('span', { staticClass: 'el-radio__inner' })]
          ), width: 60, align: 'center' },
          type === EventTarget.PROGRAM
            ? { label: '缩略图', type: 'asset', render ({ img }) {
              return img
                ? { thumb: img }
                : null
            }, on: this.onView }
            : null,
          { prop: 'name', label: '名称', 'min-width': 120 },
          { prop: 'resolutionRatio', label: '分辨率' },
          { type: 'invoke', render: [
            { label: '查看', on: this.onView }
          ] }
        ]
      }
    }
  },
  watch: {
    eventTarget: {
      handler () {
        this.init()
      },
      immediate: true
    }
  },
  methods: {
    init () {
      const target = this.eventTarget

      switch (target?.type) {
        case EventTarget.PROGRAM:
        case EventTarget.RECUR:
          this.currentTarget = {
            type: target.type,
            detail: target,
            assets: []
          }
          break
        default:
          this.currentTarget = {
            type: EventTarget.ASSETS,
            detail: null,
            assets: (target?.sources || []).map(asset => {
              return {
                key: `${Date.now()}_${Math.random().toString(16).slice(2)}`,
                disabled: asset.type === AssetType.VIDEO,
                info: `${AssetTagInfo[asset.tag]} ${AssetTypeInfo[asset.type]}`,
                file: {
                  type: asset.type,
                  url: asset.keyName
                },
                ...asset
              }
            })
          }
          break
      }
    },
    onChangeTargetType () {
      this.currentTarget.detail = null
      this.currentTarget.assets = []
    },
    getListInvoke (params) {
      switch (this.currentTarget.type) {
        case EventTarget.RECUR:
          return getSchedules({
            type: ScheduleType.RECUR,
            status: State.AVAILABLE,
            ...params
          })
        default:
          return getPrograms({
            status: State.AVAILABLE,
            ...params
          })
      }
    },
    onView ({ id }) {
      switch (this.currentTarget.type) {
        case EventTarget.PROGRAM:
          this.$refs.materialDialog.showProgram(id)
          break
        case EventTarget.RECUR:
          this.$refs.materialDialog.showSchedule(id)
          break
        default:
          break
      }
    },
    onViewCurrentTarget () {
      this.onView(this.currentTarget.detail)
    },
    onClickRow (row) {
      this.currentTarget.detail = row
    },
    onViewAsset ({ file }) {
      this.$refs.previewDialog.show(file)
    },
    onEditAssets () {
      if (!this.isAssets) {
        return
      }
      this.$refs.transferDialog.show(this.currentTarget.assets)
    },
    onSaveAssets (assets) {
      this.currentTarget.assets = assets
      return Promise.resolve()
    },
    onImportDataset () {
      this.$datasetAssets = null
      this.$refs.datasetDialog.show()
    },
    onViewDataset ({ id }) {
      this.$datasetId = id
      this.$datasetAssets = null
      this.$refs.contentDialog.show()
    },
    getAssets () {
      if (this.$datasetAssets) {
        return Promise.resolve({ data: this.$datasetAssets })
      }
      return getCommonDataset(this.$datasetId).then(({ data: { mediaList } }) => {
        this.$datasetAssets = mediaList.map(transformDatasetAssetToAsset)
        return { data: this.$datasetAssets }
      })
    },
    onChoosenDataset ({ value, done }) {
      if (this.$datasetId !== value.id) {
        this.$datasetId = value.id
        this.$datasetAssets = null
      }
      this.getAssets().then(({ data }) => {
        data.forEach(item => {
          const { tag, type, keyName, adDuration, name, file, minioData } = item
          if (minioData) {
            this.currentTarget.assets.push({
              tag,
              type,
              name,
              keyName,
              size: minioData.size,
              md5: minioData.md5,
              duration: adDuration,
              key: `${Date.now()}_${Math.random().toString(16).slice(2)}`,
              disabled: type === AssetType.VIDEO,
              info: `${AssetTagInfo[tag]} ${AssetTypeInfo[type]}`,
              file
            })
          }
        })
        done()
      })
    },
    onDelAsset (index) {
      this.currentTarget.assets.splice(index, 1)
    },
    createEventTarget () {
      if (this.isAssets ? !this.currentTarget.assets.length : !this.selectedId) {
        this.$message({
          type: 'warning',
          message: '请选择上播内容'
        })
        return null
      }
      const { type, detail, assets } = this.currentTarget
      return type === EventTarget.PROGRAM
        ? {
          type,
          id: detail.id,
          name: detail.name,
          programUrl: `${detail.buckets}/${detail.itemConfigName}`
        }
        : type === EventTarget.RECUR
          ? {
            type,
            id: detail.id,
            name: detail.name
          }
          : {
            type,
            sources: assets.map(({ tag, type, name, keyName, duration, size, md5 }) => {
              return { tag, type, name, keyName, duration, size, md5 }
            })
          }
    },
    getSnapshot () {
      return this.currentTarget
    },
    getValue () {
      const eventTarget = this.createEventTarget()
      if (eventTarget && !this.isAssets && (!this.ratio || this.ratio !== this.currentTarget.detail.resolutionRatio)) {
        eventTarget.adaptive = 1
      }
      return eventTarget
    }
  }
}
</script>
