import { GIFT_GENERATE_TYPE, GM_MAIL_TYPE, MAIL_TIME_TYPE, SERVER_TIMER } from "../../consts";
import { isArray, isNumber, isString } from 'underscore';
import ServerStategy, { GMMail } from "../../db/ServerStategy";
import { RegionType } from "../../db/Region";
import { RewardInter } from "../../pubUtils/interface";
import { isTimestamp } from '../../pubUtils/util';

export class UpdateMailParams {
    hasGoods: boolean = false;                // 是否有道具
    goods: {id: number; count: number}[];
    timeType: MAIL_TIME_TYPE;          // 邮件时间类型
    expire: number;                 // 有效时间，单位小时
    startTime: number;               // 发送时间，延时邮件使用
    circleStart: number;               // 循环邮件开始循环时间
    circleEnd: number;               // 循环邮件结束循环时间
    circleDay: number;               // 循环时间，每周几，0表示每天
    circleHour: string;               // 几点发送
    title: string;
    content: string;
    sendName: string;
    mailType: GM_MAIL_TYPE;         // 收件人类型
    receivers: {env: string; serverId: number; roleId: string; roleName: string; }[];
    reason: string;                   // 原因
    isSp: boolean = false;                   // 特殊邮件
    isSingle: boolean;

    constructor(obj: UpdateMailParams) {
        this.goods = obj.goods;
        this.hasGoods = obj.goods?.length > 0;
        this.timeType = obj.timeType;
        this.expire = obj.expire;
        this.startTime = obj.startTime;
        this.circleStart = obj.circleStart;
        this.circleEnd = obj.circleEnd;
        this.circleDay = obj.circleDay;
        this.circleHour = obj.circleHour;
        this.title = obj.title;
        this.content = obj.content;
        this.sendName = obj.sendName;
        if(obj.isSingle == true) {
            this.mailType = GM_MAIL_TYPE.SINGLE;
        } else if (obj.isSingle == false) {
            this.mailType = GM_MAIL_TYPE.SERVER;
        }
        this.receivers = obj.receivers;
        this.reason = obj.reason;
    }

    checkParams() {
        if(!this.title || !this.content || !this.sendName || !this.reason) return false;
        if(this.timeType == MAIL_TIME_TYPE.IMMEDIATE) {
            if(!this.expire) return false;
        } else if (this.timeType == MAIL_TIME_TYPE.DELAY) {
            if(!this.expire || !this.startTime) return false;
        } else if (this.timeType == MAIL_TIME_TYPE.CIRCLE) {
            if(!this.expire || !this.circleStart || !this.circleEnd || this.circleDay == undefined || !this.circleHour)
                return false;
        }
        if(!this.receivers || !isArray(this.receivers)) return false;
        if(!this.mailType) return false;
        for(let { serverId, roleId, roleName } of this.receivers) {
            if(!serverId) return false;
            if(this.mailType == GM_MAIL_TYPE.SINGLE||this.mailType == GM_MAIL_TYPE.GROUP) {
                if(!roleId || !roleName) return false;
            }
        }
        return true;
    }
}

export class UpdateRegionParams {
    id: number|'new' = 0;                // 大区id
    name: string = '';              // 大区名
    prefix: string = '';            // 区名前缀
    remark: string = '';

    maxPlayerCnt: number = 0;
    timers: SERVER_TIMER[] = [];
    activityGroupId: number[] = [];
    openMail?: GMMail;
    circleMail?: GMMail;
    stopRegisterTime: number = 0;

    hasOpenMail: boolean = false;
    hasCircleMail: boolean = false;

    constructor(obj: UpdateRegionParams) {
        for(let key in obj) {
            this[key] = obj[key];
        }
    }

    checkParams() {
        if(!this.id || !this.name || !this.prefix || !this.maxPlayerCnt || !isArray(this.timers) || this.timers.length <= 0 || !isArray(this.activityGroupId) || this.activityGroupId.length <= 0 ) {
            return false
        }
        return true;
    }

    getUpdateParam(oldRegion?: RegionType) {
        if(!oldRegion) {
            let stategy = new ServerStategy(this);
            return {
                name: this.name,
                prefix: this.prefix,
                remark: this.remark,
                stategy
            }
        } else {
            let stategy = new ServerStategy(this);
            return {
                name: this.name||oldRegion.name,
                prefix: this.prefix||oldRegion.prefix,
                remark: this.remark||oldRegion.remark,
                stategy: { ...(oldRegion.stategy||{}), ...stategy }
            }
        }
    }
}

export class CreateRegionParam {
    name: string = '';              // 大区名
    prefix: string = '';            // 区名前缀
    remark: string = '';
    env: string = '';               // 环境变量
    gmLink: string;                 // 对应后台链接
    gameHost: string;               // 长链接
    gmPort: number;                 // 后台使用的connector端口

    constructor(obj: any) {
        for(let key in obj) {
            this[key] = obj[key];
        }
    }

    checkParams() {
        if(!this.name || !this.prefix || !this.env || !this.gmLink || !this.gameHost || !this.gmPort || !isNumber(this.gmPort) ) {
            return false
        }
        return true;
    }
}

export class CreateServerParam {
    env: string = '';
    openTime: number = 0;
    activityGroupId: number[] = [];
    hasOpenMail: boolean = false;
    openMail?: GMMail;
    hasCircleMail: boolean = false;
    circleMail?: GMMail;
    stopRegisterTime: number = 0;

    constructor(obj?: any) {
        if(obj) {
            for(let key in obj) {
                this[key] = obj[key];
            }
        }
    }

    setByRegionStategy(region: RegionType, openTime: number) {
        this.env = region.env;
        this.openTime = openTime;
        if(region.stategy) {
            this.activityGroupId = region.stategy.activityGroupId;
            this.hasOpenMail = !!region.stategy.openMail;
            this.openMail = region.stategy.openMail;
            this.hasCircleMail = !!region.stategy.circleMail;
            this.circleMail = region.stategy.circleMail;
            this.stopRegisterTime = region.stategy.stopRegisterTime;
        }
        
    }

    checkParams() {
        if(!this.env || !this.openTime  || !this.stopRegisterTime || !isArray(this.activityGroupId) || this.activityGroupId.length <= 0 ) {
            return false
        }
        if(this.hasOpenMail && !this.openMail) return false;
        if(this.hasCircleMail && !this.circleMail) return false;
        return true;
    }
}

export class CreateGiftCode {
    name: string;           // 礼包码名
    goods: RewardInter[];         // 奖励
    beginTime: number;         // 开始时间
    endTime: number;           // 结束时间
    codeLen: number;           // 礼包码位数
    remark: string = '';           // 备注
    generateType: GIFT_GENERATE_TYPE;         // 生成类型
    code: string = '';

    constructor(obj: any) {
        this.name = obj.name;
        this.goods = obj.goods;
        this.beginTime = obj.beginTime;
        this.endTime = obj.endTime;
        this.codeLen = obj.codeLen;
        this.remark = obj.remark;
        this.generateType = obj.generateType;
        this.code = obj.code;
    }

    checkParams() {
        if(!isString(this.name)) return false;
        if(!isArray(this.goods)) return false;
        for(let { id, count } of this.goods) {
            if(!isNumber(id) || !isNumber(count)) return false;
        }
        if(!isTimestamp(this.beginTime) || !isTimestamp(this.endTime)) return false;
        if(!isNumber(this.codeLen) || this.codeLen <= 0) return false;

        if(this.generateType != GIFT_GENERATE_TYPE.ONE_TO_MANY && this.generateType != GIFT_GENERATE_TYPE.ONE_TO_ONE) {
            return false
        }
        if(this.code != undefined && !isString(this.code)) return false
        return true;
    }
}

export class UpdateGiftCode {
    id: number;
    name: string;           // 礼包码名
    goods: RewardInter[];         // 奖励
    beginTime: number;         // 开始时间
    endTime: number;           // 结束时间
    codeLen: number;           // 礼包码位数
    remark: string = '';           // 备注

    constructor(id: number, obj: any) {
        this.id = id;
        this.name = obj.name;
        this.goods = obj.goods;
        this.beginTime = obj.beginTime;
        this.endTime = obj.endTime;
        this.codeLen = obj.codeLen;
        this.remark = obj.remark;
    }

    checkParams() {
        if(!isNumber(this.id) || this.id <= 0) return false
        if(!isString(this.name)) return false;
        if(!isArray(this.goods)) return false;
        for(let { id, count } of this.goods) {
            if(!isNumber(id) || !isNumber(count)) return false;
        }
        if(!isTimestamp(this.beginTime) || !isTimestamp(this.endTime)) return false;
        if(!isNumber(this.codeLen) || this.codeLen <= 0) return false;
        return true;
    }
}

export class GuildFormParam {
    code: string;
    name: string;
    notice: string;
    fund: number;
    lv: number;
    equipProduce: number;
    boss: number;
    train: number;
    wishPool: number;
    store: number;
    donate: number;
    
    constructor(obj?: any) {
        if(obj) {
            for(let key in obj) {
                this[key] = obj[key];
            }
        }
    }

    checkParams() {
        if(!this.code || !isString(this.code)) return false;
        if(this.name && !isString(this.name)) return false;
        if(this.notice && !isString(this.notice)) return false;
        if(this.fund && !isNumber(this.fund)) return false;
        if(this.lv && !isNumber(this.lv)) return false;
        if(this.equipProduce && !isNumber(this.equipProduce)) return false;
        if(this.boss && !isNumber(this.boss)) return false;
        if(this.train && !isNumber(this.train)) return false;
        if(this.wishPool && !isNumber(this.wishPool)) return false;
        if(this.store && !isNumber(this.store)) return false;
        if(this.donate && !isNumber(this.donate)) return false;
        return true;
    }
}