import moment = require('moment');
import { ACTIVITY_TIME_TYPE, REFRESH_TIME } from '../../consts';
import { ActivityModelType } from '../../db/Activity';
import { deltaDays } from '../../pubUtils/util';

// 活动数据
export abstract class ActivityBase {
    groupId: number;
    activityId: number = 0;
    name: string = '';
    beginTime: number = 0;
    endTime: number = 0;
    type: number = 0;
    todayIndex: number = 0;//从1开始
    delayDay: number = 0;//延迟多少天开启，0表示按照原计划开启
    effectDay: number = 0;// 活动生效天数
    hideDayByServer: number = 0;
    isEnable: boolean = false;
    interval: number = 0;

    roundIndex: number = 0;//周期活动第几个周期，从1开始
    nextRefreshTime: number = 0;//周期活动下次刷新时间

    abstract initData(data: string): void;

    //今天是活动第几天
    public today(): number {
        return this.todayIndex;
    }

    public canShow() {
        if(!this.isEnable) return false;
        if(this.beginTime > Date.now() || this.endTime < Date.now()) return false;
        if(this.nextRefreshTime && this.nextRefreshTime < Date.now()) return false;
        return true;
    }

    /**
     * getBaseKeys
     */
     public getBaseKeys() {
        return {
            activityId: this.activityId,
            name: this.name,
            beginTime: this.beginTime,
            endTime: this.endTime,
            type: this.type,
            todayIndex: this.todayIndex,
            delayDay: this.delayDay,
            roundIndex: this.roundIndex,
            nextRefreshTime: this.nextRefreshTime,
        }
    }

    constructor(activityData: ActivityModelType, createTime: number, serverTime: number) {
        this.activityId = activityData.activityId;
        this.groupId = activityData.groupId;
        this.delayDay = activityData.delayDay ? activityData.delayDay : 0;
        this.hideDayByServer = activityData.hideDayByServer||0;
        this.roundIndex = 1;
        this.name = activityData.name;
        this.isEnable = activityData.isEnable;
        this.interval = activityData.interval * 86400;

        this.type = activityData.type;
        // console.log('今天是活动第几天', activityData.beginTime, new Date, this.todayIndex, createTime, serverTime)
        // console.log('***** activityData', activityData.timeType, this.beginTime, this.endTime, this.interval, this.todayIndex, this.roundIndex, this.nextRefreshTime, this.effectDay)
        switch (activityData.timeType) {
            case ACTIVITY_TIME_TYPE.SERVER_OPEN_TIME: {
                this.beginTime = moment(serverTime * 1000).add(this.delayDay, 'd').startOf('d').add(REFRESH_TIME, 'h').valueOf();
                if (activityData.days > 0) {
                    this.endTime = moment(this.beginTime).add(activityData.days, 'd').valueOf();
                } else {
                    this.endTime = moment(this.beginTime).add(1, 'd').valueOf();
                }
                this.todayIndex = deltaDays(moment(this.beginTime).toDate(), new Date) + 1;
                break;
            }
            case ACTIVITY_TIME_TYPE.ROLE_REGISTER_TIME: {
                this.beginTime = moment(createTime * 1000).add(this.delayDay, 'd').startOf('d').add(REFRESH_TIME, 'h').valueOf();
                if (activityData.days > 0) {
                    this.endTime = moment(this.beginTime).add(activityData.days, 'd').valueOf();
                } else {
                    this.endTime = moment(this.beginTime).add(1, 'd').valueOf();
                }
                this.todayIndex = deltaDays(moment(this.beginTime).toDate(), new Date) + 1;

                break;
            }
            case ACTIVITY_TIME_TYPE.DATE_TIME: {
                this.beginTime = activityData.beginTime.valueOf();
                this.endTime = activityData.endTime.valueOf();
                let startOfBeginDay = moment(activityData.beginTime).startOf('d').add(REFRESH_TIME, 'h');
                this.todayIndex = deltaDays(startOfBeginDay.toDate(), new Date) + 1;

                break;
            }
            case ACTIVITY_TIME_TYPE.MULT_DATE_TIME: {
                let now = new Date();
                let multiTime = activityData.multiTime||[];

                for(let { id, beginTime, endTime } of multiTime) {
                    if(beginTime <= now && endTime > now) {
                        this.beginTime = beginTime.valueOf();
                        this.endTime = endTime.valueOf();
                        this.nextRefreshTime = this.endTime;
                        this.roundIndex = id;
                        let startOfBeginDay = moment(this.beginTime).startOf('d').add(REFRESH_TIME, 'h');
                        this.todayIndex = deltaDays(startOfBeginDay.toDate(), new Date) + 1;
                    }
                }

                break;
            }
            default: {
                break;
            }
        }
        if(activityData.timeType != ACTIVITY_TIME_TYPE.MULT_DATE_TIME) {
            if (activityData.interval > 0) {
                this.roundIndex = Math.ceil((moment(new Date).valueOf() - this.beginTime) / (activityData.interval * 86400000));
                this.nextRefreshTime = moment(this.beginTime).add(activityData.interval * (this.roundIndex - 1), 'day').add(activityData.effectDay, 'd').valueOf();
                this.todayIndex = Math.ceil(((moment(new Date).valueOf() - this.beginTime) / (24 * 60 * 60 * 1000)));
            } else {
                this.nextRefreshTime = this.endTime;
            }
        }
        if(activityData.hideDayByServer > 0) {
            let hidOverTime = moment(serverTime * 1000).add(activityData.hideDayByServer, 'd').startOf('d').add(REFRESH_TIME, 'h').valueOf();
            if(this.beginTime < hidOverTime) this.beginTime = hidOverTime;
        }
        // console.log('活动时间数据...', '活动id:', activityData.activityId, '类型:', activityData.timeType, '开始时间:', this.beginTime, moment(this.beginTime).toDate(),
        //     '结束:', this.endTime, moment(this.endTime).toDate(),
        //     '今天第几天:', this.todayIndex, '回合:', this.roundIndex, '下次刷新:', this.nextRefreshTime, moment(this.nextRefreshTime).toDate())
                    // console.log('###### roundIndex 1', this.roundIndex)
    }
}

class multiTime {
    id: number = 0;
    beginTime: number = 0;
    endTime: number = 0;
}

/**
 * 存在内存内的活动
 */
export class ActivityInRemote {
    groupId: number;				// 组Id
    activityId: number;				// 活动Id
    beginTime: number = 0;			    // 开启时间  timeType=3
    endTime: number = 0;					// 结束时间  timeType=3
    multiTime: multiTime[] = [];			    // 开启时间  timeType=4
    type: number;					// 活动类型
    data: string;					// 活动表中的数据

    timeType: number;			    // 活动时间类型 ACTIVITY_TIME_TYPE 1.服务器开启时间 2.角色创建时间 3.指定开启时间(beginTime,endTime)
    days: number = 0;					// 活动持续天数 timeType=1、2
    delayDay: number = 0;			    // 迟几天开启活动，0表示按照规定时间开启
    effectDay: number = 0;              // 生效天数
    interval: number = 0;			    // 周期性活动时间间隔,天
    hideDayByServer: number = 0;
    isEnable: boolean;
    name: string;
    
    constructor(activity?: ActivityModelType) {
        this.groupId = activity.groupId;
        this.activityId = activity.activityId;
        if(activity.beginTime) this.beginTime = activity.beginTime.getTime();
        if(activity.endTime) this.endTime = activity.endTime.getTime();
        if(activity.multiTime) {
            for(let { id, beginTime, endTime } of activity.multiTime) {
                this.multiTime.push({ id, beginTime: beginTime?.getTime()||0, endTime: endTime?.getTime()||0 });
            }
        }
        this.type = activity.type;
        this.data = activity.data;
        this.timeType = activity.timeType;
        this.days = activity.days;
        this.delayDay = activity.delayDay;
        this.interval = activity.interval;
        this.hideDayByServer = activity.hideDayByServer;
        this.isEnable = activity.isEnable;
        this.name = activity.name;
        this.effectDay = activity.effectDay;
    }
}

export function transActivityInRemoteToModelType(activity: ActivityInRemote): ActivityModelType {
    if(!activity) return null;
    return {
        ...activity,
        beginTime: new Date(activity.beginTime),
        endTime: new Date(activity.endTime),
        multiTime: activity.multiTime.map(cur => ({ id: cur.id, beginTime: new Date(cur.beginTime), endTime: new Date(cur.endTime)})),
        _id: '',
        createdAt: new Date(),
        updatedAt: new Date(),
        createdBy: 0,
        updatedBy: 0
    }
}


export class ActivityData extends ActivityBase {
    public initData(_data: string) {
        
    }

    constructor(activityData: ActivityModelType, createTime: number, serverTime: number) {
        super(activityData, createTime, serverTime)
        this.initData(activityData.data)
    }
}