import {GanHaiRed} from '../../api_s2c/ganhai/ApiOpen';
import {checkCrossWsIsDisconnect} from '../../setWsClient';
import {PublicShared} from '../../shared/public/public';
import {GHManage} from '../gonghui/manage';

export type schedulerType =
    'jjc'
    | 'qjzzd'
    | 'zhanling'
    | 'hbzb_jfs_prize'
    | 'hbzb_zbs_prize'
    | 'hbzb_local_reset'
    | 'hbzb_cross_reset'
    | 'hbzb_zbs_ready'
    | 'kbzz'
    | 'clsl_prize'
    | 'clsl_cross_ctor'
    | 'clsl_cross_group'
    | 'wzry_autobaoming'
    | 'wzry_dldstart'
    | 'wzry_dldjinji'
    | 'wzry_zuanshione'
    | 'wzry_zuanshitwo'
    | 'wzry_zuanshithree'
    | 'wzry_zuanshifour'
    | 'wzry_zuanshisendprize'
    | 'wzry_wangzheone'
    | 'wzry_wangzhetwo'
    | 'wzry_wangzhethree'
    | 'wzry_wangzhefour'
    | 'wzry_wangzhesendprize'
    | 'wzry_wangzheWZZD'
    | 'wzry_jingcaiprize'
    | 'wzry_end'
    | 'crosseamil_wzry'
    | 'newDay_local_ctor'
    | 'hbzb_zbs_clear'
    | 'hbzb_zbs_group'
    | 'wzry_zuanshi16to8'
    | "cross_email_pull"
    | "watch_dog"
    | "xiaofeijingsai_local_ctor";

export class SchedulerManage {
    static logTime = false;
    static allStartList = ['newDay_local_ctor']

    static start() {
        setInterval(() => {
            G.updateTime();
            this.logTime && console.log(G.date.format("YYYY-MM-DD hh:mm:ss"));
            G.argv.serverType == 'msg' && GHManage.check();
            checkCrossWsIsDisconnect();
            GanHaiRed.check();
        }, 1000);
    }

    static onlyPm2() {
        setInterval(() => {
            Scheduler.schedulers.filter(i => !this.allStartList.includes(i.name)).forEach(s => s.cheak());
        }, 1000);
    }

    static allPm2() {
        setInterval(() => {
            Scheduler.schedulers.filter(i => this.allStartList.includes(i.name)).forEach(s => s.cheak());
        }, 1000);
    }
}

export abstract class Scheduler {

    static schedulers: Scheduler[] = [];

    abstract id: string;
    abstract name: string;

    abstract read(): Promise<void>;

    abstract start(): Promise<void>;

    time: number;
    type: string;
    /**是否在准备状态 */
    isReady = true;
    /**是否在运行中 */
    isStart = false;
    /**运行时间戳 */
    startTime: number;

    get db() {
        return G.mongodb.collection('scheduler');
    }

    get zeroTime() {
        return this.type == 'day' ? PublicShared.getToDayZeroTime() : PublicShared.getToWeekMondayZeroTime();
    }

    get nextTime() {
        return this.zeroTime + this.time + (this.type == 'day' ? 1 : 7) * 24 * 3600;
    }

    constructor() {

    }

    init() {
        Scheduler.schedulers.push(this);
        this.read().then(_ => {
            this.log(`state: 准备完毕 预计下次执行时间：${new Date(this.startTime * 1000).format("YYYY-MM-DD hh:mm:ss")}`);
        });
    }

    log(...args: any[]) {
        console.log(`定时器 === ${this.name} -> ${Array.from(arguments).join(' ')}`);
    }

    cheak() {
        if (this.isReady) return;
        if (this.isStart) return;
        if (G.time >= this.startTime) {
            this.isStart = true;
            this.log(`state: 执行中`);
            this.start().then(_ => {
                this.log(`state: 执行结束 预计下次执行时间：${new Date(this.startTime * 1000).format("YYYY-MM-DD hh:mm:ss")}`);
            });
        }
    }

    async record() {
        await this.db.updateOne({type: this.id}, {$set: {lastRunTime: G.time}}, {upsert: true});
        this.startTime = this.nextTime;
        this.isStart = false;
    }

    async ctorStartTime() {
        let db = await this.db.findOne({type: this.id});
        let sTime = this.zeroTime + this.time;

        if (!db || this.zeroTime > db.lastRunTime) {
            this.startTime = G.time > sTime ? this.nextTime : sTime;
        } else {
            this.startTime = G.time > db.lastRunTime ? this.nextTime : sTime;
        }
    }
}

globalThis['scheduler'] = Scheduler;