<template>
  <wrapper
    fill
    margin
    background
  >
    <div class="l-flex__none l-flex--row c-step has-padding">
      <button
        class="l-flex__none c-sibling-item o-button"
        :class="{ hidden: active === 0 }"
        @click="onPresent"
      >
        上一步
      </button>
      <el-steps
        :active="active"
        class="l-flex__fill"
        finish-status="success"
        align-center
      >
        <el-step title="选择设备" />
        <el-step title="选择类型" />
        <el-step title="选择内容" />
      </el-steps>
      <button
        class="l-flex__none c-sibling-item o-button"
        :class="{ hidden: hideNext }"
        @click="onNext"
      >
        {{ btnMsg }}
      </button>
    </div>
    <div class="l-flex__fill l-flex">
      <device-tree
        v-show="active === 0"
        ref="tree"
        class="l-flex__fill has-padding"
        show-ratio
        @change="onChange"
      />
      <div
        v-if="active > 0"
        class="c-list has-padding u-overflow-y--auto"
      >
        <div class="c-list__item u-bold">{{ resolutionRatio }}</div>
        <div
          v-for="device in selectedDevices"
          :key="device.id"
          class="c-list__item"
        >
          {{ device.name }}
        </div>
      </div>
      <div
        v-if="active === 1"
        class="c-list fill has-padding u-overflow-y--auto"
      >
        <div class="c-list__section">
          <div class="o-type">发布类型</div>
          <el-select v-model="eventOptions.type">
            <el-option
              v-for="option in typeOptions"
              :key="option.value"
              :label="option.label"
              :value="option.value"
            />
          </el-select>
        </div>
        <event-picker
          v-if="isEvent"
          ref="picker"
          class="c-list__section"
          :event="eventOptions.inst"
          :priority="3"
          vertical
        />
      </div>
      <div
        v-if="active > 1"
        class="c-list small has-padding u-overflow-y--auto"
        :class="{ large: isEvent, fill: active === 1 }"
      >
        <div class="c-list__item u-bold">{{ typeMsg }}</div>
        <div
          v-for="msg in typeMsgs"
          :key="msg"
          class="c-list__item"
        >
          {{ msg }}
        </div>
      </div>
      <div
        v-if="active >= 2"
        class="c-list fill has-padding u-overflow-y--auto"
      >
        <div
          class="c-list__item o-choose-button"
          @click="showChoose"
        >
          点击选择内容
        </div>
        <schedule
          v-if="scheduleId"
          class="c-list__item"
          :schedule="scheduleId"
        />
        <div
          v-if="programId"
          class="o-program u-pointer"
          @click="toViewProgram"
        >
          {{ eventTarget.name }}
        </div>
      </div>
    </div>
    <el-dialog
      title="排期选择"
      :visible.sync="choosingSchedule"
      custom-class="c-dialog"
      :close-on-click-modal="false"
    >
      <c-table
        v-if="choosingSchedule"
        :options="scheduleOptions"
        @pagination="getSchedules"
        @row-dblclick="onChooseSchedule"
      >
        <el-table-column
          prop="name"
          label="名称"
          align="center"
          show-overflow-tooltip
        />
      </c-table>
    </el-dialog>
    <el-dialog
      :visible.sync="choosingEventTarget"
      title="节目选择"
      custom-class="c-dialog hidden-footer"
      :close-on-click-modal="false"
    >
      <event-target-choose
        v-if="choosingEventTarget"
        :ratio="resolutionRatio"
        @choose="onChooseEventTarget"
      />
    </el-dialog>
  </wrapper>
</template>

<script>
import { getSchedules } from '@/api/calendar'
import { publish } from '@/api/publish'
import { createListOptions } from '@/utils'
import {
  State,
  ScheduleType,
  EventFreq,
  EventTarget,
  PublishType
} from '@/constant'
import EventPicker from '@/components/EventPicker'
import EventTargetChoose from '@/components/EventTargetChoose'
import DeviceTree from '@/components/DeviceTree'

export default {
  name: 'ScheduleDeploy',
  components: {
    DeviceTree,
    EventPicker,
    EventTargetChoose
  },
  data () {
    return {
      typeOptions: [
        { value: PublishType.CALENDAR, label: '排期' },
        { value: PublishType.EVENT, label: '插播' }
      ],
      freqOptions: [
        { value: EventFreq.ONCE, label: '单次' },
        { value: EventFreq.WEEKLY, label: '每周重复' }
      ],
      weeks: [
        { value: '0', label: '日' },
        { value: '1', label: '一' },
        { value: '2', label: '二' },
        { value: '3', label: '三' },
        { value: '4', label: '四' },
        { value: '5', label: '五' },
        { value: '6', label: '六' }
      ],
      scheduleOptions: null,
      active: 0,
      selectedDevices: [],
      eventOptions: null,
      choosingSchedule: false,
      choosingEventTarget: false,
      eventTarget: null
    }
  },
  computed: {
    hideNext () {
      switch (this.active) {
        case 0:
          return this.selectedDevices.length === 0
        case 2:
          return !this.eventTarget
        default:
          return false
      }
    },
    btnMsg () {
      return this.active < 3 ? '下一步' : '发布'
    },
    resolutionRatio () {
      return this.selectedDevices[0]?.resolutionRatio
    },
    typeMsg () {
      return this.typeOptions[this.eventOptions?.type - 1]?.label
    },
    typeMsgs () {
      const msgs = []
      if (this.eventOptions?.type === PublishType.EVENT) {
        const { freq, start, until, byDay, startTime, endTime } = this.eventOptions.inst
        switch (freq) {
          case EventFreq.WEEKLY:
            msgs.push(`自${start.split(' ')[0]}开始`)
            until && msgs.push(`至${until.split(' ')[0]}前`)
            msgs.push(`每周${byDay.split(',').map(val => ['日', '一', '二', '三', '四', '五', '六'][val]).join('、')}`)
            msgs.push(`${startTime} - ${endTime}`)
            break
          default:
            msgs.push(`自${start}开始`)
            until && msgs.push(`${until}结束`)
            break
        }
      }
      return msgs
    },
    isCalendar () {
      return this.eventOptions?.type === PublishType.CALENDAR
    },
    isEvent () {
      return this.eventOptions?.type === PublishType.EVENT
    },
    scheduleId () {
      return this.eventOptions?.type === PublishType.CALENDAR || this.eventTarget?.type === EventTarget.RECUR ? this.eventTarget?.id : null
    },
    programId () {
      return this.eventTarget?.type === EventTarget.PROGRAM ? this.eventTarget.id : null
    }
  },
  methods: {
    onPresent () {
      if (this.active > 0) {
        if (this.active === 3) {
          this.active -= 2
        } else {
          this.active -= 1
        }
      }
    },
    onNext () {
      let pass = false
      switch (this.active) {
        case 0:
          pass = this.checkDevices()
          break
        case 1:
          pass = this.checkEventOptions()
          if (pass && this.checkEventTarget()) {
            this.active += 1
          }
          break
        case 2:
          pass = this.checkEventTarget()
          break
        case 3:
          this.publish()
          break
        default:
          return
      }
      if (pass) {
        this.active += 1
      }
    },
    _onError (message) {
      this.$message({
        type: 'warning',
        message
      })
      return false
    },
    onChange (devices) {
      this.selectedDevices = devices
    },
    checkDevices () {
      const devices = this.selectedDevices
      const length = devices.length
      if (!length) {
        return this._onError('请选择目标设备')
      }
      const resolutionRatio = this.resolutionRatio
      if (devices.some(device => device.resolutionRatio !== resolutionRatio)) {
        return this._onError('选择的设备分辨率不一致')
      }
      if (this.eventOptions) {
        if (this.resolutionRatio !== this.eventOptions.ratio) {
          this.eventTarget = null
        }
      } else {
        this.eventOptions = this.createEventOptions()
      }
      return true
    },
    createEventOptions () {
      return {
        ratio: this.resolutionRatio,
        type: PublishType.CALENDAR,
        inst: null
      }
    },
    checkEventOptions () {
      if (this.eventOptions.type === PublishType.EVENT) {
        const event = this.$refs.picker.getValue()
        if (!event) {
          return false
        }
        this.eventOptions.inst = event
      }
      return true
    },
    showChoose () {
      switch (this.eventOptions?.type) {
        case PublishType.CALENDAR:
          this.scheduleOptions = createListOptions({
            status: State.RESOLVED,
            type: ScheduleType.COMPLEX,
            resolutionRatio: this.resolutionRatio
          })
          this.getSchedules()
          this.choosingSchedule = true
          break
        case PublishType.EVENT:
          this.choosingEventTarget = true
          break
        default:
          break
      }
    },
    closeChoose () {
      switch (this.eventOptions?.type) {
        case PublishType.CALENDAR:
          this.choosingSchedule = false
          break
        case PublishType.EVENT:
          this.choosingEventTarget = false
          break
        default:
          break
      }
    },
    getSchedules () {
      const options = this.scheduleOptions
      options.error = false
      options.loading = true
      getSchedules(options.params).then(
        ({ data, totalCount }) => {
          options.list = data
          options.totalCount = totalCount
        },
        () => {
          options.error = true
          options.list = []
        }
      ).finally(() => {
        options.loading = false
      })
    },
    onChooseSchedule ({ id, name }) {
      this.closeChoose()
      this.eventTarget = { id, name }
      if (this.active === 2) {
        this.onNext()
      }
    },
    onChooseEventTarget (value) {
      this.closeChoose()
      this.eventTarget = value
      if (this.active === 2) {
        this.onNext()
      }
    },
    checkEventTarget () {
      if (this.isCalendar && this.eventTarget?.type || this.isEvent && this.eventTarget && !this.eventTarget.type) {
        this.eventTarget = null
      }
      if (!this.eventTarget) {
        this.showChoose()
        return false
      }
      return true
    },
    toViewProgram () {
      window.open(this.$router.resolve({
        name: 'view',
        params: { id: this.programId }
      }).href, '_blank')
    },
    _getPublishTarget () {
      switch (this.eventOptions.type) {
        case PublishType.CALENDAR:
          return {
            type: PublishType.CALENDAR,
            detail: this.eventTarget.id
          }
        case PublishType.EVENT:
          return {
            type: PublishType.EVENT,
            detail: {
              ...this.eventOptions.inst,
              target: this.eventTarget
            }
          }
        default:
          return null
      }
    },
    publish () {
      console.log('publish')
      const devices = this.selectedDevices
      this.$confirm(`确定对设备 ${devices.map(device => device.name)} 发布 ${this.typeMsg} ${this.eventTarget.name}？`).then(() => {
        return publish(devices.map(device => device.id), this._getPublishTarget(), {
          programCalendarName: this.eventTarget.name,
          resolutionRatio: this.resolutionRatio
        })
      }).then(() => {
        this.active = 0
        this.$refs.tree.reset()
        this.eventOptions = null
        this.eventTarget = null
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.c-step {
  border-bottom: 1px solid $gray--light;

  .hidden {
    visibility: hidden;
  }
}

.c-list {
  flex: 1 0 200px;
  min-width: 200px;
  max-width: 300px;
  padding-right: $spacing;
  color: $black;

  & + & {
    border-left: 1px solid $gray--light;
  }

  &.small {
    min-width: 100px;
    max-width: 200px;
  }

  &.large {
    min-width: 240px;
    max-width: 320px;
  }

  &.fill {
    max-width: initial;
  }

  &__item + &__item {
    margin-top: 8px;
  }

  &__section + &__section {
    margin-top: $spacing;
  }
}

.o-type {
  margin-bottom: 8px;
  font-size: 14px;
  font-weight: bold;
  line-height: 1;
}

.o-choose-button {
  padding: 20px 0;
  font-size: 20px;
  text-align: center;
  border: 1px solid $gray--light;
  color: $black;
  cursor: pointer;

  &:hover {
    color: #409eff;
    border-color: #c6e2ff;
    background-color: $blue--light;
  }

  &:active {
    color: #3a8ee6;
    border-color: #3a8ee6;
  }
}

.o-program {
  margin-top: $spacing;
  font-size: 24px;
  font-weight: bold;

  &:hover {
    color: #409eff;
  }
}
</style>
