import { OptionalId, UpdateFilter } from 'mongodb';
import { CollectionFriend } from '../../module/collection_friend';
import { MongodbCollections } from '../../module/mongodb';
import { ResOpen } from '../../shared/protocols/friend/PtlOpen';
import { PublicShared } from '../../shared/public/public';
import { FriendManage } from './manage';


export class Friend {
    constructor(public data: CollectionFriend) {
        if (!data.myApplyList) this.updateDb({ $set: { myApplyList: [] } });
    }
    updateDb(update: UpdateFilter<OptionalId<MongodbCollections['friend']>>) {
        G.mongodb.collection('friend').updateOne({ uid: this.data.uid }, update);
        FriendManage.setFriend(this.data.uid, this.data)
    }
    //往申请列表中插入uid
    addApply(uid: string) {
        if (!this.data) return;
        this.data.applyList.push(uid);
        this.sendMsg({ applyList: this.data.applyList });
        this.updateDb({ $push: { applyList: uid } });
    }
    //往黑名单中插入uid
    addBlack(uid: string) {
        if (!this.data) return;
        this.data.blacklist.push(uid);
        this.sendMsg({ blacklist: this.data.blacklist });
        this.updateDb({ $push: { blacklist: uid } });
    }
    //往好友列表中插入uid
    addFriend(uid: string) {
        if (!this.data) return;
        this.data.friendList.push(uid);
        this.sendMsg({ friendList: this.data.friendList });
        this.updateDb({ $push: { friendList: uid } });
    }
    addMyApply(uid: string) {
        this.data.myApplyList.push(uid);
        this.sendMsg({ myApplyList: this.data.myApplyList });
        this.updateDb({ $push: { myApplyList: uid } });
    }
    delApply(uid: string) {
        this.data.applyList.removeOne(_uid => _uid == uid);
        this.sendMsg({ applyList: this.data.applyList });
        this.updateDb({ $pull: { blacklist: uid } });
    }
    delBlack(uid: string) {
        if (!this.data) return;
        this.data.blacklist.removeOne(_uid => _uid == uid);
        this.sendMsg({ blacklist: this.data.blacklist });
        this.updateDb({ $pull: { blacklist: uid } });
    }
    delFriend(uid: string) {
        if (!this.data) return;
        this.data.friendList.removeOne(_uid => _uid == uid);
        this.sendMsg({ friendList: this.data.friendList });
        this.updateDb({ $pull: { friendList: uid } });
    }
    delMyApply(uid: string) {
        this.data.myApplyList.removeOne(u => u == uid);
        this.sendMsg({ myApplyList: this.data.myApplyList });
        this.updateDb({ $pull: { myApplyList: uid } });
    }
    protected addGift(uid: string) {
        this.data.getGift[uid] = G.time;
        this.sendMsg({ getGift: this.data.getGift });
        this.updateDb({ $set: G.mongodb.createTreeObj({ key: 'getGift', k: uid, val: G.time }) });
    }
    recGift(uid: string | string[]) {
        this.data.recGift = this.data.recGift.concat(uid);
        this.updateDb({ $push: { recGift: { $each: [].concat(uid) } } });
    }
    sendGift(uid: string | string[]) {
        let uids: string[] = [].concat(uid);
        this.data.sendGift = this.data.sendGift.concat(uids);
        this.updateDb({ $push: { sendGift: { $each: [].concat(uids) } } });

        uids.forEach(async _uid => {
            let friendData = await FriendManage.getFriend(_uid)
            friendData?.addGift(this.data.uid);
        });
    }
    refreshTime() {
        let getGift = Object.fromEntries(Object.keys(this.data.getGift).filter(uid => this.data.getGift[uid] >= PublicShared.getToDayZeroTime()).map(uid => [uid, this.data.getGift[uid]]));

        let data: Partial<MongodbCollections['friend']> = {
            refreshTime: G.time,
            sendGift: [],
            recGift: [],
            getGift: getGift
        };
        Object.assign(this.data, data);
        this.updateDb({ $set: { ...data } });
    }
    sendMsg(msg: Partial<ResOpen>) {
        G.server.sendMsgByUid(this.data.uid, 'msg_s2c/Friend', msg);
    }
}