import { ObjectId } from 'mongodb';
import { CollectionGongHui } from '../../module/collection_gonghui';
import { player } from '../../shared/protocols/user/type';
import { PlayerFun } from '../player';
import { GH } from './gh';
import { clusterRunOnce } from '../../clusterUtils';
import {PublicShared} from "../../shared/public/public";

export class GHManage {
    /**
     * 所有公会
     */
    // static list: k_v<GH> = {};
    static redisKey = "gonghui:list"
    /**
     * 从数据库拉取公会
     */
    static async init() {
        //因为是存redis了，所以只需要第一个进程来干
        clusterRunOnce(async () => {
            // redis存在数据，不初始化。
            if(await this.getGHListLen() > 0) {
                // 检测是否存在空field，存在则删除
                let check = await G.redis.hGet(this.redisKey, "");
                if(check) G.redis.hDel(this.redisKey, "")
                return 
            }
            
            const ghs = await G.mongodb.collection('gonghui').find({}).toArray();
            ghs.forEach(gh => {
                let _gh = G.mongodb.conversionIdObj(gh);
                this.setGH(_gh._id, _gh)
                // this.list[_gh._id] = new GH(_gh);
            });
        })
    }
    static async setGH(ghId: string, data: CollectionGongHui) {
        ghId = ghId || data._id
        if(!ghId) return 
        G.redis.hSet(this.redisKey, ghId, data)
        return 
    }

    /**
     * 获取指定公会对象
     * @param ghId 
     * @returns 
     */
    static async getGH(ghId: string): Promise<GH|undefined> {
        let data:CollectionGongHui = await G.redis.hGet(this.redisKey, ghId)
        if(!data) {
            let res = await G.mongodb.collection('gonghui').findOne(G.mongodb.conversionIdObj({_id: ghId}))
            data = G.mongodb.conversionIdObj(res)
            if(data) this.setGH(ghId, data)
        }
        if(data) return new GH(data)
        return undefined
    }

    /**
     * 获取全部公会列表
     */
    static async getGHList(): Promise<k_v<GH>> {
        let res = await G.redis.hGetAll(this.redisKey);
        for(let i in res) {
            res[i] = new GH(res[i])
        }
        return res
    }

    /**
     * 获取公会总数
     */
    static async getGHListLen(): Promise<number> {
        return await G.redis.hLen(this.redisKey)
    }

    /**
     * 新增一个公会
     */
    static async addNew(data: CollectionGongHui) {
        new GH(data);
        // this.list[data._id] = new GH(data);
    }
    /**
     * 删除一个公会
     */
    static async remove(ghid: string) {
        let GHdata = await this.getGH(ghid)
        GHdata.data.players.forEach(v => {
            this.removeRole(v.uid);
        });
        // this.list[ghid] = null;
        // delete this.list[ghid];
        G.mongodb.collection('gonghui').deleteOne({ _id: G.mongodb.conversionId(ghid) });
        G.redis.hDel(this.redisKey, ghid)
    }
    /**
     * 公会删除一个人
     */
    static async removeRole(uid: string) {
        let exit_cd:number
        if (PublicShared.getOpenServerDay() <= 1){
            exit_cd = 0
        }else {
            exit_cd = G.time
        }
        PlayerFun.changeAttr(uid, { ghId: '', ghLevel: 0, ghExitTime: exit_cd});
        G.server.sendMsgByUid(uid, 'msg_s2c/PlayerChange', { ghId: '', ghLevel: 0, ghName: '', ghExitTime: exit_cd });
        // 退出公会 保留捐献记录
        // G.mongodb.collection('gonghuiUser').findOneAndUpdate({ uid: uid }, { $unset: { jx: 1 } });
    }
    /**
     * 公会会长上线
     */
    static async hzsx(gud: player) {
        let GHdata = await this.getGH(gud.ghId)
        if (GHdata.data.tanhe) {
            GHdata.data.tanhe = null;
            delete GHdata.data.tanhe;
            GHdata.updateDb({ $unset: { tanhe: 1 } });
        }
    }




    static countInterval = 0;
    static checkInterval = 60;
    static async check() {
        if (this.countInterval < this.checkInterval) {
            return this.countInterval++;
        }
        this.countInterval = 0;
        let list:k_v<GH> = await this.getGHList()
        Object.entries(list).forEach(v => {
            let [_id, gh] = v;
            if (gh.data?.tanhe && G.time >= gh.data.tanhe.time) {
                let player = gh.data.players.find(p => p.uid == gh.data.tanhe.uid);

                if (player) {
                    gh.managePlayer(gh.data.createPlayer.uid, player.level);
                    gh.managePlayer(player.uid, 1);
                }

                gh.data.tanhe = null;
                delete gh.data.tanhe;
                gh.updateDb({ $unset: { tanhe: 1 } });
            }
        });
    }
}