<template>
  <wrapper
    fill
    margin
    padding
    background
  >
    <div class="l-flex--row">
      <button
        class="o-button c-sibling-item"
        @click="onTransferSchedule"
      >
        迁移设备排期
      </button>
      <button
        class="o-button c-sibling-item"
        @click="onTransferHistory"
      >
        迁移发布历史
      </button>
    </div>
    <el-dialog
      title="迁移设备排期"
      :visible.sync="scheduleTransfering"
      custom-class="c-dialog"
    >
      <c-table
        v-if="scheduleTransfering"
        :options="deviceOptions"
        @pagination="getDevices"
      >
        <template #header>
          <button
            v-if="deviceOptions.totalCount"
            class="o-button c-sibling-item"
            @click="transferPageDevices"
          >
            迁移当前页
          </button>
          <button
            v-if="deviceOptions.totalCount > deviceOptions.params.pageSize"
            class="o-button c-sibling-item"
            @click="transferAllDevices"
          >
            迁移所有
          </button>
        </template>
        <el-table-column
          prop="id"
          label="ID"
          align="center"
        />
        <el-table-column
          prop="name"
          label="设备名称"
          align="center"
        />
        <el-table-column
          label="操作"
          align="center"
        >
          <template v-slot="scope">
            <div
              class="c-table__btn u-pointer"
              @click="transformOneDevice(scope.row)"
            >
              迁移至事件模式
            </div>
            <div
              class="c-table__btn u-pointer"
              @click="clearDevice(scope.row)"
            >
              清除
            </div>
          </template>
        </el-table-column>
      </c-table>
    </el-dialog>
    <el-dialog
      title="迁移发布历史"
      :visible.sync="historyTransfering"
      custom-class="c-dialog"
    >
      <c-table
        v-if="historyTransfering"
        :options="historyOptions"
        @pagination="getHistoriesByOptions"
      >
        <template #header>
          <button
            v-if="historyOptions.totalCount"
            class="o-button c-sibling-item"
            @click="transferPageHistories"
          >
            迁移当前页
          </button>
          <button
            v-if="historyOptions.totalCount > historyOptions.params.pageSize"
            class="o-button c-sibling-item"
            @click="transferAllHistories"
          >
            迁移所有
          </button>
        </template>
        <el-table-column
          prop="id"
          label="ID"
          align="center"
        />
        <el-table-column
          prop="programCalendarName"
          label="名称"
          align="center"
        />
        <el-table-column
          prop="createTime"
          label="审核时间"
          align="center"
        />
        <el-table-column
          label="操作"
          align="center"
        >
          <template v-slot="scope">
            <div
              class="c-table__btn u-pointer"
              @click="transferOneHistory(scope.row)"
            >
              迁移
            </div>
          </template>
        </el-table-column>
      </c-table>
    </el-dialog>
  </wrapper>
</template>

<script>
import { getDevices } from '@/api/device'
import request from '@/utils/request'
import { toEvent } from '@/utils/event'
import { createListOptions } from '@/utils'
import {
  State,
  PublishType
} from '@/constant'

export default {
  name: 'Transfer',
  data () {
    return {
      scheduleTransfering: false,
      deviceOptions: null,
      historyTransfering: false,
      historyOptions: null
    }
  },
  methods: {
    onTransferSchedule () {
      this.deviceOptions = createListOptions()
      this.getDevices()
      this.scheduleTransfering = true
    },
    getDevices () {
      const options = this.deviceOptions
      options.error = false
      options.loading = true
      getDevices(options.params).then(
        ({ data, totalCount }) => {
          options.list = data.map(({ id, name }) => {
            return { id, name }
          })
          options.totalCount = totalCount
        },
        () => {
          options.error = true
          options.list = []
        }
      ).finally(() => {
        options.loading = false
      })
    },
    setDeviceCalendar (id, events) {
      return request({
        url: `/content/deviceCalender/${id}`,
        method: 'POST',
        data: events,
        custom: true
      })
    },
    clearDevice (device) {
      const loading = this.$showLoading()
      this.setDeviceCalendar(device.id, []).then(
        () => {
          this.$message({
            type: 'success',
            message: '数据已清除'
          })
        },
        () => {
          this.$message({
            type: 'warning',
            message: '数据清除失败'
          })
        }
      ).finally(() => {
        this.$closeLoading(loading)
      })
    },
    async transferDevice ({ id }) {
      const { data } = await request({
        url: `/content/deviceCalender/${id}`,
        method: 'GET',
        custom: true
      })
      const schedules = JSON.parse(data.eventDetail) || []
      if (schedules.length && !schedules[0].freq) {
        const events = []
        for (let i = 0; i < schedules.length; i++) {
          const event = toEvent(schedules[i])
          await event.invoke()
          events.push(event)
        }
        await this.setDeviceCalendar(id, events)
        return true
      }
      return false
    },
    async transferDevices (devices) {
      const length = devices.length
      for (let i = 0; i < length; i++) {
        const device = devices[i]
        try {
          await this.transferDevice(device)
        } catch (e) {
          console.warn(e)
          this.$message({
            type: 'warning',
            message: `${device.name}迁移失败`
          })
          return
        }
      }
      this.$message({
        type: 'success',
        message: '数据迁移成功'
      })
    },
    async transformOneDevice (device) {
      const loading = this.$showLoading()
      try {
        const has = await this.transferDevice(device)
        if (has) {
          this.$message({
            type: 'success',
            message: '数据迁移成功'
          })
        } else {
          this.$message({
            type: 'warning',
            message: '数据不需迁移或已迁移'
          })
        }
      } catch (e) {
        console.warn(e)
        this.$message({
          type: 'warning',
          message: '数据迁移失败'
        })
      }
      this.$closeLoading(loading)
    },
    async transferPageDevices () {
      const loading = this.$showLoading()
      await this.transferDevices(this.deviceOptions.list)
      this.$closeLoading(loading)
    },
    async transferAllDevices () {
      if (this.deviceOptions.totalCount <= this.deviceOptions.params.pageSize) {
        this.transferPageDevices()
      } else {
        const loading = this.$showLoading()
        try {
          const { data } = await getDevices({
            pageNum: 1,
            pageSize: this.deviceOptions.totalCount
          })
          await this.transferDevices(data)
        } catch (e) {
          console.warn(e)
          this.$message({
            type: 'warning',
            message: '获取迁移数据失败'
          })
        }
        this.$closeLoading(loading)
      }
    },
    onTransferHistory () {
      this.historyOptions = createListOptions()
      this.getHistoriesByOptions()
      this.historyTransfering = true
    },
    getHistories ({ pageNum: pageIndex, pageSize }) {
      return request({
        url: '/orchestration/calendarRelease/page',
        method: 'GET',
        params: {
          pageIndex,
          pageSize,
          status: State.RESOLVED
        }
      })
    },
    getHistoriesByOptions () {
      const options = this.historyOptions
      options.error = false
      options.loading = true
      this.getHistories(options.params).then(
        ({ data, totalCount }) => {
          options.list = data
          options.totalCount = totalCount
        },
        () => {
          options.error = true
          options.list = []
        }
      ).finally(() => {
        options.loading = false
      })
    },
    transferHistory ({ id, programCalendarId }) {
      return request({
        url: `/orchestration/calendarRelease/${id}/save`,
        method: 'POST',
        data: {
          type: PublishType.CALENDAR,
          detail: programCalendarId
        },
        custom: true
      })
    },
    async transferHistories (histories) {
      const length = histories.length
      for (let i = 0; i < length; i++) {
        const history = histories[i]
        try {
          await this.transferHistory(history)
        } catch (e) {
          console.warn(e)
          this.$message({
            type: 'warning',
            message: `${history.programCalendarName}迁移失败`
          })
          return
        }
      }
      this.$message({
        type: 'success',
        message: '数据迁移成功'
      })
      const options = this.historyOptions
      if (options.params.pageNum > 1 && options.list.length <= length) {
        if (options.params.pageSize >= length) {
          options.params.pageNum -= 1
        } else {
          options.params.pageNum = 1
        }
      }
      this.getHistoriesByOptions()
    },
    async transferOneHistory (history) {
      const loading = this.$showLoading()
      await this.transferHistories([history])
      this.$closeLoading(loading)
    },
    async transferPageHistories () {
      const loading = this.$showLoading()
      await this.transferHistories(this.historyOptions.list)
      this.$closeLoading(loading)
    },
    async transferAllHistories () {
      if (this.historyOptions.totalCount <= this.historyOptions.params.pageSize) {
        this.transferPageHistories()
      } else {
        const loading = this.$showLoading()
        try {
          const { data } = await this.getHistories({
            pageNum: 1,
            pageSize: this.historyOptions.totalCount
          })
          await this.transferHistories(data)
        } catch (e) {
          console.warn(e)
          this.$message({
            type: 'warning',
            message: '获取迁移数据失败'
          })
        }
        this.$closeLoading(loading)
      }
    }
  }
}
</script>

<style lang="scss" scoped>
</style>
