import {
  toDate,
  toDateStr,
  toTimeStr,
  toZeroPoint,
  pickMin,
  getConflict,
  getEventDescription
} from '@/utils/event'
import {
  EventFreq,
  EventTarget
} from '@/constant'

export default {
  data () {
    return {
      event: null,
      dirty: false,
      conflicts: []
    }
  },
  methods: {
    onRemove (eventProxy) {
      this.$confirm(
        `移除 ${eventProxy.origin.target.name} ？`,
        { type: 'warning' }
      ).then(() => {
        this.removeEventProxy(eventProxy)
        this.correct()
      })
    },
    removeEventProxy (eventProxy) {
      if (eventProxy) {
        const { key } = eventProxy
        const index = this.events.findIndex(event => event.key === key)
        if (~index) {
          this.events.splice(index, 1)
          this.dirty = true
          return index
        }
      }
      return -1
    },
    onAdd (event) {
      if (this.editable) {
        if (event && event.until && toDate(event.until) <= new Date()) {
          this.calculate()
          return
        }
        this.editEvent(event)
      }
    },
    onEditProxy (eventProxy) {
      const event = eventProxy.origin
      if (this.editable) {
        this.$eventProxy = eventProxy
        this.editEvent(event)
      } else {
        switch (event.target.type) {
          case EventTarget.RECUR:
            this.$refs.scheduleDialog.show(event.target.id)
            break
          default:
            window.open(this.$router.resolve({
              name: 'program',
              params: { id: event.target.id }
            }).href, '_blank')
            break
        }
      }
    },
    editEvent (event) {
      if (this.editable) {
        this.event = event || {}
        this.$refs.editDialog.show()
      }
    },
    onSaveEvent (done) {
      const event = this.$refs.editor.getValue()
      if (!event) {
        return
      }
      console.log(event)
      if (this.$eventProxy && this.getEventUnique(this.$eventProxy.origin) === this.getEventUnique(event)) {
        done()
        this.dirty = true
        this.$eventProxy.origin.target = event.target
        return
      }
      this.conflicts = this.getConflicts({
        key: this.$eventProxy?.key,
        origin: event
      })
      if (!this.conflicts.length) {
        done()
        this.removeEventProxy(this.$eventProxy)
        this.saveEvent(event)
        return
      }
      this.$conflictSource = event
      this.$refs.conflictDialog.show()
    },
    getEventUnique (event) {
      const { freq, start, until, byDay, startTime, endTime } = event
      switch (freq) {
        case EventFreq.ONCE:
          return `${freq};${start};${until}`
        case EventFreq.WEEKLY:
          return `${freq};${start};${until};${byDay};${startTime};${endTime}`
        default:
          return Math.random().toString(16).slice(2)
      }
    },
    onCover (done) {
      done()
      this.$refs.editDialog.onCancel()
      this.conflicts.forEach(this.removeEventProxy)
      this.saveEvent(this.$conflictSource)
      this.$conflictSource = null
    },
    saveEvent (event) {
      this.dirty = true
      const minDate = toDate(event.start)
      const insertIndex = this.events.findIndex(eventProxy => toDate(eventProxy.origin.start) > minDate)
      if (~insertIndex) {
        this.events.splice(insertIndex, 0, this.createEventProxy(event))
      } else {
        this.events.push(this.createEventProxy(event))
      }
      this.toDay(minDate)
    },
    getConflicts ({ key, origin: event }) {
      const conflicts = []
      if (this.events.length) {
        this.events.forEach(eventProxy => {
          if (eventProxy.key !== key) {
            const date = getConflict(event, eventProxy.origin)
            if (date) {
              console.log(eventProxy.origin)
              conflicts.push({
                key: eventProxy.key,
                info: `与 ${eventProxy.origin.target.name} 于 ${toDateStr(date)} ${toTimeStr(date)} 有冲突`,
                desc: getEventDescription(eventProxy.origin)
              })
            }
          }
        })
      }
      return conflicts
    },
    onSave () {
      this.fix()
        .then(this.save)
        .then(() => { this.dirty = false })
    },
    fix () {
      let maxDate = Date.now() + 60000
      if (this.events.some(({ origin: { until } }) => until && toDate(until) <= maxDate)) {
        return this.$confirm(
          '存在过期或将要过期(<=60s)节目，是否移除？',
          {
            type: 'warning',
            distinguishCancelAndClose: true,
            confirmButtonText: '移除',
            cancelButtonText: '保留'
          }
        ).then(() => {
          maxDate = Date.now() + 60000
          this.scheduleOptions.events = this.events.filter(({ origin: { until } }) => !until || toDate(until) > maxDate)
          this.correct()
        }, action => {
          if (action === 'cancel') {
            return this.events
          }
          return Promise.reject()
        })
      }
      return Promise.resolve()
    },
    correct () {
      const today = new Date()
      const minDate = toZeroPoint(this.events.length ? pickMin(toDate(this.events[0].origin.start), today) : today)
      if (this.minDate < minDate) {
        this.minDate = minDate
        if (this.current < this.minDate) {
          this.toDay(this.current)
          return
        }
      }
      this.calculate()
    }
  }
}
