
<template>
    <as-popup
        @right="handleConfirm"
        :title="computedOptions.title"
        :visible="visible"
        @update:visible="hide"
        class="as-time-range"
        :class="[`as-time-${computedOptions.type}`]"
    >
        <template #right>
            <span>确认</span>
        </template>
        <div class="as-time-range-inner">
            <ul class="as-time-range-nav">
                <li :class="{ active: index === current, disabled: item.disabled }"
                    v-for="(item, index) in computedItems"
                    @click="handleSwitch(item, index)"
                    :key="index"
                >
                    <p>
                        {{ item.label }}
                        <span v-if="item.badge">{{ item.badge }}</span>
                    </p>
                </li>
            </ul>
            <ul class="as-time-range-content" ref="refContent">
                <li :class="{ active: item.index > -1, disabled: item.disabled }"
                    v-for="(item) in computedRanges"
                    @click="handleSelect(item)"
                    :key="item.key">
                    <span>{{ item.label }}</span>
                    <van-icon name="success" />
                </li>
            </ul>
        </div>
    </as-popup>
</template>

<script>
    import { Icon } from 'vant'
    import AsPopup from '../as-popup'
    import { parseDate, parseDayTime } from '../../../plugins/utils'
    import { filterDate } from '../../../plugins/filters'

    export default {
        name: 'AsTimeRange',
        data () {
            return {
                visible: false,
                options: {},
                resolve: null,
                reject: null,
                value: [],
                current: 0,
                items: []
            }
        },
        props: {
            title: { default: '时间段' },
            lazy: { default: true, type: Boolean },
            type: { default: 'single' }, // multiple  single
            maxRange: { default: '', type: Number | String },
            range: { default: 60 * 60 * 1000, type: Number },
            startTime: { default: '00:00:00', type: String },
            endTime: { default: '24:00:00', type: String },
            maxDate: { default: Date.now() +  parseDayTime(7) },
            minDate: { default: Date.now() },
            formatItem: { default: () => ({}), type: Function },
            formatItemRange: { default: () => ({}), type: Function },
        },
        computed: {
            computedOptions () {
                return Object.assign({}, this.$props, this.options)
            },
            computedItems () {
                const { value, items } = this
                return items.map(item => {
                    const { value: date } = item
                    const min = parseDate(`${date} 00:00:00`).getTime()
                    const max = parseDate(`${date} 23:59:59`).getTime()
                    const badge = value.filter(([ start, end ]) => {
                        return parseDate(start).getTime() >= min && max >= parseDate(end).getTime()
                    }).length
                    return Object.assign({ badge }, item)
                })
            },
            computedRanges () {
                const { value, items, current } = this
                const { children = [] } = items[current] || {}
                return children.map(item => {
                    return Object.assign({ }, item, { index: value.findIndex(v => JSON.stringify(item.value) === JSON.stringify(v)) })
                })
            },
        },
        methods: {
            show (options = {}) {
                let { value, ...restOptions } = options
                return new Promise((resolve, reject) => {
                    this.options = restOptions
                    const { type } = this.computedOptions
                    this.value = value ? type === 'single' ? [value] : value : []
                    console.log('value => ', this.value)
                    this.parseItems()
                    this.parseRanges()
                    this.resolve = resolve
                    this.reject = reject
                    this.visible = true
                })
            },
            hide () {
                this.reject && this.reject('')
                this.visible = false
            },
            parseItems () {
                const { maxDate, minDate, formatItem } = this.computedOptions
                const items = []
                const maxDateTime = parseDate(maxDate).getTime()
                const oneDayTime = parseDayTime()
                let dateTime = parseDate(minDate).getTime()
                const today = filterDate(undefined, 'yyyy-MM-dd')
                const tomorrow = filterDate(Date.now() + oneDayTime, 'yyyy-MM-dd')
                while (dateTime < maxDateTime) {
                    const value = filterDate(dateTime, 'yyyy-MM-dd')
                    const [ , m, d ] = value.split('-')
                    let label = value === today ? '今天' : value === tomorrow ? '明天' : `${m}月${d}日`
                    items.push({ label, value, disabled: false, children: [], ...formatItem({ label, value, dateTime }) })
                    dateTime += oneDayTime
                }
                this.items = items
            },
            parseRanges () {
                const { current } = this
                const { value: date, children } = this.items[current] || {}
                const { range: rangeTime, startTime, endTime, formatItemRange, lazy } = this.computedOptions
                if (lazy && children.length) return
                const maxDateTime = parseDate(`${date} ${endTime}`).getTime()
                let dateTime = parseDate(`${date} ${startTime}`).getTime()
                const curTime = Date.now()
                while (dateTime < maxDateTime) {
                    const start = filterDate(dateTime, 'hh:mm:ss')
                    const [ sh, sm ] = start.split(':')
                    const startDateTime = dateTime
                    const disabled = dateTime <= curTime
                    dateTime += rangeTime
                    const end = filterDate(dateTime, 'hh:mm:ss')
                    const [ eh, em ] = end.split(':')
                    const label = `${sh}:${sm} — ${eh}:${em}`
                    const value = [`${date} ${start}`, `${date} ${end}`]
                    children.push({ key: value.join(''), value, label, disabled, ...formatItemRange({ label, value, startDateTime, endDateTime: dateTime }) })
                }
            },
            handleSwitch (item, index) {
                if (item.disabled) return
                this.current = index
                this.parseRanges()
                this.$refs.refContent.scrollTop = 0
            },
            handleSelect (item) {
                const { disabled, value, index } = item
                if (disabled) return
                const { type, maxRange } = this.computedOptions
                if (type === 'single') {
                    return this.value = index > -1 ? [] : [[...value]]
                }
                if (index > -1) {
                    return this.value.splice(index, 1)
                }
                if (!maxRange || this.value.length < +maxRange) {
                    this.value.push([...value])
                }
            },
            handleConfirm () {
                const { value } = this
                const { type } = this.computedOptions
                this.resolve && this.resolve(type === 'single' ? value[0] : value)
                this.reject = null
                this.hide()
            },
        },
        components: {
            AsPopup,
            VanIcon: Icon,
        },
    }
</script>

<style lang="scss" scoped>
    @import "../../assets/scss/define";
    .as-time-range{
        @extend %df;
        /deep/{
            .as-popup-inner{
                @extend %df;
                @extend %fdc;
            }
        }
        &.as-time-multiple{
            .as-time-range-nav{
                span{
                    @extend %db;
                }
            }
        }
        &-inner{
            @extend %oh;
            @extend %df;
            @extend %df1;
            li{
                @extend %df;
                @extend %aic;
                @extend %c3;
                @extend %cp;
                @extend %ao8;
                @extend %usn;
                @extend %pr;
                font-size: j(14);
                height: j(48);
                padding: 0 j(12);
                &.active{
                    color: $color-primary;
                    i{
                        @extend %db;
                    }
                }
                &.disabled {
                    color: #c8c9cc;
                    cursor: not-allowed;
                }
            }
        }
        &-nav{
            @extend %h100;
            @extend %bsb;
            @extend %oya;
            width: j(120);
            background-color: #f7f8fa;
            .active{
                background-color: #fff;
                &:before{
                    @extend %pa;
                    @extend %l0;
                    top: 50%;
                    width: j(4);
                    height: j(16);
                    background-color: $color-primary;
                    -webkit-transform: translateY(-50%);
                    transform: translateY(-50%);
                    content: '';
                }
            }
            p{
                @extend %dib;
                @extend %pr;
            }
            span{
                @extend %pa;
                @extend %dn;
                @extend %t0;
                @extend %r0;
                @extend %bsb;
                @extend %cfff;
                @extend %tac;
                min-width: 16px;
                padding: 0 3px;
                font-size: 12px;
                line-height: 1.2;
                background-color: $color-danger;
                border: 1px solid #fff;
                border-radius: 16px;
                transform: translate(50%, -50%);
                transform-origin: 100%;
            }
        }
        &-content{
            @extend %df1;
            @extend %oya;
            @extend %bsb;
            @extend %h100;
            background-color: #fff;
            li{
                padding: 0 j(16);
            }
            span{
                @extend %df1;
            }
            i{
                @extend %dn;
                color: $color-primary;
            }
        }
    }
</style>

