<template>
    <view :class="[safeAreaInsetBottom ? 'safe-area-inset-bottom' : '', 'u-theme-' + cTheme, 'time']">
        <view class="time-move">
            <view class="time-move-txt bg-size-contain">{{ getCurrentHour(currentHour) }}</view>
        </view>
        <view :class="{ touch: timeFlickIsTouch }" class="time-content" :style="timeContentStyle" ref="timeContent">
            <view class="time-show-img" :style="cTimeHeight ? { width: parseFloat(cTimeHeight) + 'rpx' } : {}" @click="timeClick">
                <image class="time-show-img-btn" :style="btnStyle" v-show="timeIsPlay" src="../../assets/pause.svg" mode="aspectFit" />
                <image class="time-show-img-btn" :style="btnStyle" v-show="!timeIsPlay" src="../../assets/play.svg" mode="aspectFit" />
            </view>
            <view ref="timeAxis" @touchstart.stop.prevent="timeFlickTouchStart" @touchmove.stop.prevent="timeFlickTouch" @touchend.stop.prevent="timeFlickTouchEnd" :class="{ touch: timeFlickIsTouch }" :style="[timeAxisStyle]" class="time-axis">
                <view class="time-axis-item" :style="[timeAxisItemStyle(item.hours), axisItemBgc(i)]" v-for="(item, i) in dateTimeList" :key="i">
                    <view class="day">{{ item.day }}</view>
                    <view class="hours-list">
                        <span class="hours" v-for="(item, index) in item.hoursList" :key="index">{{ item }}</span>
                    </view>
                </view>
            </view>
        </view>
    </view>
</template>

<script>
/**
 * timeBar 横向时间轴
 * @description 横向时间轴组件一般用于物流信息展示，各种跟时间相关的记录等场景。
 * @tutorial https://www.uviewui.com/components/timeLine.html
 * theme
 * interval
 * itemWidth 时间轴item的宽度
 * timeHeight 时间轴高度
 * date 时间数据
 * isContinued 实时响应时间
 * bgColorList 背景色
 * @change 触发时间改变
 * @example <u-time-bar></u-time-bar>
 */
import dayjs from 'dayjs';
export default {
    name: 'u-time-bar',
    emits: ['change'],
    data() {
        return {
            timeIsPlay: false, // 是否在播放
            currentHour: '', // 当前小时
            timePlayIndex: 0, // 时间播放时的下标
            timeMoveLeft: 0, // 时间播放条位置
            moveWidth: 0, // 每次移动的距离
            timer: null, // 时间播放定时器
            timeFlickIsTouch: false,
            dateTimeList: [],
            dayArray: [], //所有小时的数组
            hoursList: ['01', '04', '07', '10', '13', '16', '19', '22'],
            offsetLeft: 0,
            touchX: 0,
            LeftPart: 0, //最大偏移量
            screenCenter: 0, // 计算窗体中心位置
            //完成整个进度的时间,默认值为100
            // intervalTime: 120000,
            // userSetTime: 120000,
            day_diff_n: 0 //一共多少天
        };
    },
    props: {
        // 关怀模式: normal, care(fpi新增)
        theme: {
            type: String,
            default: ''
        },
        // 自动播放的速度
        interval: {
            type: Number,
            default: 1000
        },
        // 每日进度条的长度
        itemWidth: {
            type: [Number, String],
            default: null
        },
        // 时间轴的高度
        timeHeight: {
            type: [Number, String],
            default: null
        },
        date: {
            type: Array,
            default: () => [
                dayjs()
                    .subtract(7, 'd')
                    .format('YYYY-MM-DD HH:00'),
                dayjs().format('YYYY-MM-DD HH:00')
            ]
        },
        // 实时监听
        isContinued: {
            type: Boolean,
            default: false
        },
        bgColorList: {
            type: Array,
            default: () => []
        },
        safeAreaInsetBottom: {
            type: Boolean,
            default: true
        }
    },
    computed: {
        cTheme() {
            return this.theme || (uni.$u || {}).theme;
        },
        getCurrentHour() {
            return value => {
                return dayjs(value).format('HH:00');
            };
        },
        // 时间轴外包围
        timeContentStyle() {
            let obj = {
                transition: 'height ease-out 0.3s'
            };
            if (this.cTimeHeight) {
                obj['height'] = this.timeFlickIsTouch ? this.cTimeHeight * 2 + 'rpx' : this.cTimeHeight + 'rpx';
            }
            if (!this.timeFlickIsTouch) obj['transition-delay'] = '1s';
            return obj;
        },
        // 时间轴
        timeAxisStyle() {
            let obj = {
                transition: 'height ease-out 0.3s',
                left: this.timeMoveLeft + 'px'
            };
            if (this.cTimeHeight) {
                obj['height'] = this.timeFlickIsTouch ? this.cTimeHeight * 2 + 'rpx' : this.cTimeHeight + 'rpx';
                obj['line-height'] = this.cTimeHeight + 'rpx';
            }
            if (!this.timeFlickIsTouch) obj['transition-delay'] = '1s';
            return obj;
        },
        // 开始暂停按钮
        btnStyle() {
            if (this.cTimeHeight) return { width: (this.cTimeHeight * 3) / 5 + 'rpx' };
        },
        // 时间轴每个item的样式
        timeAxisItemStyle() {
            return hour => {
                return { width: (hour / 24) * this.cItemWidth + 'rpx' };
            };
        },
        // 过滤itemWidth,判断适老化
        cItemWidth() {
            let itemWidth = this.itemWidth ? parseFloat(this.itemWidth) : 320;
            if (this.cTheme === 'care') {
                itemWidth = (itemWidth * 4) / 3;
            }
            return itemWidth;
        },
        // 过滤timeHeight,判断适老化
        cTimeHeight() {
            let timeHeight = this.timeHeight ? parseFloat(this.timeHeight) : null;
            if (this.cTheme === 'care' && timeHeight) {
                timeHeight = (timeHeight * 4) / 3;
            }
            return timeHeight;
        },
        axisItemBgc() {
            return i => {
                let obj = {}
                if (i === 0) {
                    obj['paddingLeft'] = this.screenCenter + 'px'
                } else if (i === this.dateTimeList.length - 1) {
                    obj['paddingRight'] = this.screenCenter + 'px'
                }
                if (this.bgColorList && this.bgColorList.length) {
                    obj['backgroundColor'] = i % 2 === 0 ? this.bgColorList[0] : this.bgColorList[1]
                }
                return obj;
            };
        },
        hoursLists() {
            /**
             * 总共24个
             * 大于 760 显示24个
             * 大于 480 小于 760 显示12个
             * 大于 320 小于 480 显示8个
             * 大于 240 小于 320 显示6个
             * 大于 160 小于 240 显示4个
             * 大于 120 小于 160 显示3个
             * 小于 120 显示2个
             */
            // 这里不使用 cItemWidth 是因为开启适老化后,字体变大,如果width变大,下面的list的if提升一级的话,怕页面上展示不下
            const width = this.itemWidth;
            let list = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23'];
            // console.log(this.hoursList);
            if (width >= 480 && width < 760) {
                list = this.filterData(list, 2);
            } else if (width >= 320 && width < 480) {
                list = this.filterData(list, 3);
            } else if (width >= 240 && width < 320) {
                list = this.filterData(list, 4);
            } else if (width >= 160 && width < 240) {
                list = this.filterData(list, 6);
            } else if (width >= 120 && width < 160) {
                list = this.filterData(list, 8);
            } else if (width < 120) {
                list = this.filterData(list, 12);
            }
            return list;
        }
    },
    async mounted() {
        await this.getDay();
        await this.initWidth();
    },
    methods: {
        // 时间轴播放点击
        timeClick() {
            this.timeIsPlay = !this.timeIsPlay;
            this.timeIsPlay ? this.timePlay() : this.timePause();
        },
        // 时间播放
        timePlay() {
            // this.timePlayIndex += 1;
            this.timePlayIndex === this.dayArray.length ? (this.timePlayIndex = 0) : '';
            this.playFunc();
            this.timer = setInterval(() => {
                this.timePlayIndex += 1;
                // console.log(this.timePlayIndex);
                // console.log(this.dayArray[this.timePlayIndex]);
                // console.log(this.dayArray.length);
                if (this.timePlayIndex === this.dayArray.length) {
                    this.timePlayIndex = 0;
                    this.timeIsPlay = false;
                    this.timePause();
                    return;
                }
                this.playFunc();
            }, this.interval);
        },
        // 播放具体过程
        playFunc() {
            this.currentHour = this.dayArray[this.timePlayIndex];
            this.timeMoveLeft = 0 - this.timePlayIndex * this.moveWidth;
            this.$emit('change', { index: this.timePlayIndex, time: this.currentHour, timestamp: dayjs(this.currentHour).valueOf() });
        },
        // 时间停止
        timePause() {
            this.timer && clearInterval(this.timer);
            this.timer = null;
        },
        // 时间拨动轴开始触摸
        timeFlickTouchStart(e) {
            if (!this.timeIsPlay) {
                // console.log("开始触摸！！！！！！！！！！！！！！！！！");
                // console.log(e);
                // let offsetLeft = this.$refs.timeAxis.$el.offsetLeft
                const query = uni.createSelectorQuery().in(this);
                query.select('.time-axis').boundingClientRect(data => {
                    let offsetLeft = data.left
                    this.touchX = e.changedTouches[0].pageX - offsetLeft;
                }).exec();
                // this.offsetLeft = this.$refs.timeAxis.$el.offsetLeft;
            }
        },
        // 时间拨动轴触摸中
        async timeFlickTouch(e) {
            if (!this.timeIsPlay) {
                this.timeFlickIsTouch = true;
                // console.log("时间拨动轴触摸中", e)
                // console.log('距离左边的距离:', offsetLeft);
                uni.createIntersectionObserver(this).observe('.time-axis', (res) => {
                    let offsetLeft = res.boundingClientRect.left
                    let index = parseInt(Math.abs(offsetLeft) / this.moveWidth);
                    this.timePlayIndex = index;
                    this.currentHour = this.dayArray[index];
                    if (this.isContinued) this.$emit('change', { index: this.timePlayIndex, time: this.currentHour, timestamp: dayjs(this.currentHour).valueOf() });
                })
                const pageX = e.changedTouches[0].pageX - this.touchX;
                this.timeMoveLeft = pageX;
                if (pageX > 0) {
                    this.timeMoveLeft = 0;
                    return;
                } else if (pageX < this.LeftPart) {
                    this.timeMoveLeft = this.LeftPart;
                    return;
                }
                // let offsetLeft = this.$refs.timeAxis.$el.offsetLeft;
            }
        },
        // 时间拨动轴结束触摸
        timeFlickTouchEnd(e) {
            if (!this.timeIsPlay) {
                // console.log("时间拨动轴结束触摸", e.changedTouches[0].pageX)
                this.timeFlickIsTouch = false;
                // emit
                this.$emit('change', { index: this.timePlayIndex, time: this.currentHour, timestamp: dayjs(this.currentHour).valueOf() });
                // let currentPageX = this.timeMoveLeft - 48;
                // this.timePlayIndex = parseInt(currentPageX / this.moveWidth);
                // const touchX = e.changedTouches[0].pageX - this.offsetLeft
                // const nowLeft = this.$refs.timeAxis.$el.clientWidth + this.$refs.timeAxis.$el.offsetLeft;
                // this.intervalTime = nowLeft / this.$refs.timeAxis.$el.clientWidth * this.userSetTime;
                // this.playFunc();
            }
        },
        dateArray(dateStart, dateEnd) {
            console.log(dateStart,dateEnd);
            let date_array = [];
            let startHour = dayjs(dateStart);
            let endHour = dayjs(dateEnd);
            console.log(startHour,endHour);
            let diff = endHour.diff(startHour, 'hours');
            console.log(diff);
            // date_array.push(startHour.format('YYYY-MM-DD HH:00'));
            for (let i = 0; i <= diff; i++) {
                date_array.push(startHour.add(i, 'hours').format('YYYY-MM-DD HH:00'));
            }
            return date_array;
        },
        getDay() {
            let d0 = this.date[0];
            let d1 = this.date[1];
            console.log('开始', d0);
            console.log('结束', d1);
            this.currentHour = dayjs(d0).format('YYYY-MM-DD HH:00');
            console.log(dayjs(d0).valueOf());
            console.log(dayjs(d1).valueOf());
            /*相差多少天*/
            const day_diff = (dayjs(d1).valueOf() - dayjs(d0).valueOf()) / 1000 / 3600 / 24;
            console.log('相差', day_diff);
            /*日期数组*/
            let day_array = this.dateArray(d0, d1);
            // console.log(day_array);
            // 所有时间的小时数组
            this.dayArray = day_array;
            // 左边空的
            const left_hours = 24 - dayjs(d0).hour();
            // 右边空的
            const right_hours = 24 - dayjs(d1).hour();
            // console.log(left_hours);
            // console.log(right_hours);
            if ((left_hours === 0 && right_hours === 0) || (left_hours === 24 && right_hours === 24)) this.day_diff_n = day_diff;
            else if (left_hours !== right_hours)
                // 如果最左边和最右边的时间轴小时数量不相等,则向上取整,+1天
                this.day_diff_n = Math.ceil(day_diff);
            else this.day_diff_n = day_diff + 1;
            for (let j = 0; j < this.day_diff_n; j++) {
                if (j === 0) {
                    // 第一天
                    // n下标就是0
                    if (left_hours === 0) {
                        // 当第一天的left_hours是0的时候,就是一整天,长度就是160
                        this.dateTimeList.push({
                            day: dayjs(d0).format('MM-DD'),
                            hours: 24,
                            hoursList: this.hoursLists
                        });
                    } else {
                        let list = this.hoursLists.filter(item => {
                            return 24 - left_hours < parseInt(item);
                        });
                        // console.log('第一列', list);
                        this.dateTimeList.push({
                            day: list.length < this.hoursLists.length / 2 ? dayjs(d0).format('DD') : dayjs(d0).format('MM-DD'),
                            hours: left_hours,
                            hoursList: list
                        });
                    }
                } else if (j === this.day_diff_n - 1) {
                    let hours = 0;
                    // 最后一天
                    if (right_hours === 0) hours = 24;
                    else if (right_hours !== 24) hours = 24 - right_hours;
                    else hours = right_hours;
                    let list = this.hoursLists.filter(item => {
                        return hours > parseInt(item);
                    });
                    // console.log('最后一列', list);
                    this.dateTimeList.push({
                        day:
                            list.length < this.hoursLists.length / 2
                                ? dayjs(d0)
                                    .add(j, 'd')
                                    .format('DD')
                                : dayjs(d0)
                                    .add(j, 'd')
                                    .format('MM-DD'),
                        hours: hours,
                        hoursList: list
                    });
                } else {
                    this.dateTimeList.push({
                        day: dayjs(d0)
                            .add(j, 'd')
                            .format('MM-DD'),
                        hours: 24,
                        hoursList: this.hoursLists
                    });
                }
            }
            this.$emit('change', { index: this.timePlayIndex, time: this.currentHour, timestamp: dayjs(this.currentHour).valueOf() });
        },
        /**
         * 初始化一些长度
         */
        async initWidth() {
            const query = uni.createSelectorQuery().in(this);
            query.select('.time-axis').boundingClientRect(data => {
                let realWidth = parseFloat(data.width)
                // 计算每小时移动的距离
                this.moveWidth = realWidth / (this.dayArray.length - 1);
                // 最大偏移量
                this.LeftPart = this.timeMoveLeft - realWidth;
            }).exec();
            const query1 = uni.createSelectorQuery().in(this);
            await query1.select('.time-content').boundingClientRect(data => {
                let screenWidth = parseFloat(data.width)
                // 屏幕中心的x距离
                this.screenCenter = screenWidth / 2;
            }).exec();
            // console.log(111,screenWidth.boundingClientRect());
            // realWidth = this.$refs.timeAxis.$el.clientWidth;
            // console.log(this.dayArray.length);
            // console.log(this.moveWidth);

            // const nowLeft = this.$refs.timeAxis.$el.clientWidth + this.$refs.timeAxis.$el.offsetLeft;
            // this.intervalTime = nowLeft / this.$refs.timeAxis.$el.clientWidth * this.userSetTime;
        },
        filterData(arr, value) {
            var temp = [];
            for (var i = 0, len = arr.length; i < len; i++) {
                if (i % value == 1) {
                    temp.push(arr[i]);
                }
            }
            return temp;
        }
    }
};
</script>

<style lang="scss" scoped>
@import "../../libs/css/style.components.scss";
@include themify($themes) {
    &.time {
        width: 100%;
        // height: 32px;
        position: relative;
        transition-duration: 0.4s;
        .time-content {
            width: 100%;
            height: themed("grid-size-40");
            overflow: hidden;
            position: relative;
            // transition: height ease-out 0.3s;
            // transition-delay: 1s;

            .time-show-img {
                z-index: 30;
                width: themed("grid-size-40");
                height: 100%;
                position: absolute;
                cursor: pointer;
                display: flex;
                align-items: center;
                justify-content: center;
                &-btn {
                    width: 48rpx;
                    height: 52rpx;
                }
            }
            .bg-common {
                background-size: contain;
                background-repeat: no-repeat;
                background-position: center center;
            }
            .time-axis {
                display: flex;
                align-items: center;
                position: absolute;
                bottom: 0;
                height: themed("grid-size-40");
                line-height: themed("grid-size-40");
                // transition: height ease-out 0.3s;
                // transition-delay: 1s;
                margin: 0;
                .time-axis-item {
                    height: 100%;
                    width: 320rpx;
                    box-sizing: content-box;
                    .day {
                        width: 100%;
                        text-align: center;
                        color: #fff;
                        font-size: themed("font-size-18");
                    }
                    .hours-list {
                        font-size: themed("font-size-12");
                        white-space: nowrap;
                        width: calc(100% - 12 * 2rpx);
                        line-height: normal;
                        margin: 0 8 * 2rpx 0 4 * 2rpx;
                        display: flex;
                        align-items: center;
                        justify-content: space-between;
                        .hours {
                            text-align: center;
                            color: rgba($color: #fff, $alpha: 0.6);
                            // display: table-cell;
                        }
                    }
                }
                .time-axis-item:nth-child(odd) {
                    background-color: rgba(63, 61, 80, 0.76);
                }
                .time-axis-item:nth-child(even) {
                    background-color: rgba(0, 0, 0, 0.63);
                }
            }
            // .time-axis.move {
            //     transition: left linear 1s, height ease-out 0.3s;
            // }
            .time-axis.touch {
                height: themed("grid-size-80");
                transition: height ease-out 0.3s;
            }
        }
        .time-content.touch {
            height: themed("grid-size-80");
            transition: height ease-out 0.3s;
        }

        .time-move {
            position: absolute;
            font-size: themed("font-size-18");
            left: 50%;
            width: themed("grid-size-80");
            margin-left: - themed("grid-size-40");
            top: - themed("grid-size-42");
            display: flex;
            align-items: center;
            justify-content: center;
            transition-duration: 0.2s;
            .time-move-txt {
                width: themed("grid-size-80");
                height: themed("grid-size-32");
                font-size: themed("font-size-18");
                color: #fff;
                text-align: center;
                line-height: themed("grid-size-32");
                border-radius: 26 * 2rpx;
                box-shadow: 0 0 4 * 2rpx 0 black;
                cursor: grab;
                position: relative;
                background-color: themed("u-type-primary");
                color: white;
                box-sizing: border-box;
                padding: 0 10rpx;
                white-space: nowrap;
            }
            .time-move-txt::before {
                top: 100%;
                left: themed("grid-size-40");
                border: solid transparent;
                content: "";
                height: 0;
                width: 0;
                position: absolute;
                border-top-color: themed("u-type-primary");
                border-width: 10 * 2rpx;
                margin-left: -10 * 2rpx;
            }
            .bg-size-contain {
                background-size: 100% 100%;
            }
        }
    }
}
</style>
