import {CollectionEmail} from '../module/collection_email';
import {ReqEmail} from '../monopoly/protocols/PtlEmail';
import {MsgEmail} from '../shared/protocols/msg_s2c/MsgEmail';


export class EmailFun {
    /**获取玩家单个邮件 */
    static async getEmail(uid: string, _id: string) {
        let email = await G.mongodb.collection("email").findOne(
            {_id: G.mongodb.conversionId(_id), isdel: {$exists: false}}
        )
        if (email.uid == "system" && email.prizeData) email.emailRead = (email?.readlist || []).includes(uid);
        if (email && email.uid == "system" && email.prizeData) email.prizeData.isGet = email.prizelist.includes(uid);

        return email
    }

    /**获取玩家所有邮件 */
    static async getAllEmail(uid: string, cache = false) {

        // if (!cache) {
        let kvList: k_v<CollectionEmail> = {};
        // let emailList = await G.mongodb.collection('email')
        //     .find({ uid: { $in: [uid, "system"] } })
        //     .sort({"createTime": -1})
        //     .toArray();

        //let gud = await G.mongodb.collection('user').findOne({ uid: uid })   // 全服的邮件增加创号时间检测

        let gud = await G.mongodb.findOne('user', {uid: uid}, ['cTime'])   // 全服的邮件增加创号时间检测

        let filter: any = {
            $or: [
                {uid: uid, isdel: {$exists: false}},
                {
                    uid: "system",
                    dellist: {$not: {$in: [uid]}},
                }
            ]
        }

        // 有些用户账号创建时间未初始化导致报错
        if (gud?.cTime) filter.$or[1].createTime = {$gte: gud.cTime}

        let emailList = await G.mongodb.collection("email").find(filter).sort({"createTime": -1}).toArray();

        for (let email of emailList) {
            let _email = G.mongodb.conversionIdObj(email);

            kvList[_email._id] = _email;
            _email.emailRead = email.emailRead ? email.emailRead : false;
            if (email.uid == "system" && email.prizeData) _email.emailRead = (_email?.readlist || []).includes(uid);
            if (email.uid == "system" && email.prizeData) _email.prizeData.isGet = _email.prizelist.includes(uid);

            delete _email.readlist;
        }
        let lng = await G.redis.rawGet(`user:lng:${uid}`)

        return Object.values(kvList).map(i => ({
            ...i,
            title: i.lngTitle ? (i.lngTitle[lng] || i.lngTitle['ja']) : i.title,
            content: i.lngContent ? (i.lngContent[lng] || i.lngContent['ja']) : i.content
        }));
    }

    /**领取邮件 */
    static receiveEmail(uid: string, _id: string): k_v<boolean>;
    static receiveEmail(uid: string, _id: string[]): k_v<boolean>;
    static receiveEmail(uid: string, _id: string | string[]) {
        let _ids: string[] = [].concat(_id);
        let change: k_v<boolean> = {};
        let oids = _ids.map(id => {
            change[id] = true;
            return G.mongodb.conversionId(id);
        })

        G.mongodb.collection('email').updateMany(
            {_id: {$in: oids}, prizelist: {$exists: false}},
            {
                $set: {
                    emailRead: true,
                    'prizeData.isGet': true
                }
            }
        );
        G.mongodb.collection('email').updateMany({
            _id: {$in: oids}, uid: "system"
        }, {$push: {prizelist: uid}});

        return change;
    }

    // 更改邮件状态为已读-仅限没有奖励的邮件
    static async readEmail(uid: string, id: string) {
        G.mongodb.collection('email').updateOne(G.mongodb.conversionIdObj({
            uid: uid, _id: id
        }), {$set: {emailRead: true}});

        G.mongodb.collection('email').updateOne(G.mongodb.conversionIdObj({
            uid: "system", _id: id
        }), {$push: {readlist: uid}});

        return
    }

    /**删除邮件 */
    static removeEmail(uid: string, _id: string): string[];
    static removeEmail(uid: string, _id: string[]): string[];
    static removeEmail(uid: string, _id: string | string[]) {
        let _ids: string[] = [].concat(_id);

        let oids = _ids.map(id => {
            return G.mongodb.conversionId(id);
        });

        G.mongodb.collection('email').updateMany(
            {uid: uid, _id: {$in: oids}}, {$set: {isdel: true}}
        );
        G.mongodb.collection('email').updateMany(
            {uid: "system", _id: {$in: oids}}, {$push: {dellist: uid}}
        );

        return _ids;
    }

    /**向玩家发送邮件 */
    /**增加 跨服定时器发送邮件 直接写入数据 （跨服定时器执行检测时会报错）*/
    static async addEmail(email: ReqEmail & { createTime?: number; }, isCross: boolean = false) {
        let {prize, uid, ...e} = email;
        let lng = await G.redis.rawGet(`user:lng:${uid}`)

        let sendEmail: MsgEmail = {
            _id: null,
            uid: uid,
            type: e.type,
            title: e.lngTitle ? (e.lngTitle[lng] || e.lngTitle['ja']) : e.title,
            content: e.lngContent ? (e.lngContent[lng] || e.lngContent['ja']) : e.content,
            createTime: e.createTime || G.time,
            contentInsertArr: e.contentInsertArr || []
        };
        /**跨服邮件给sid标识*/
        if (isCross) {
            sendEmail.sid = uid.split('_')[0]
        }

        if (prize?.length > 0) {
            sendEmail.prizeData = {
                prize: email.prize,
                isGet: false
            };
        }

        if (email.g123log && Object.keys(email.g123log).length > 0) sendEmail.g123log = email.g123log;

        if (email.lngTitle) {
            sendEmail.lngTitle = email.lngTitle
            sendEmail.lngContent = email.lngContent
        }

        //太亏了！换其他清理机制，getAllEmail是性能消耗大户
        //todo.. 换其他清理机制
        // if (!isCross) {
        //     let emailList = await this.getAllEmail(uid);
        //     if (emailList.length >= 50) {
        //         emailList.sort((a, b) => {
        //             let noPrizeA = a.prizeData == undefined ? 0 : 1;
        //             let noPrizeB = b.prizeData == undefined ? 0 : 1;
        //             let getA = a.prizeData?.isGet == true ? 0 : 1;
        //             let getB = b.prizeData?.isGet == true ? 0 : 1;

        //             if (noPrizeA != noPrizeB) {
        //                 return noPrizeA - noPrizeB;
        //             } else if (getA != getB) {
        //                 return getA - getB;
        //             }
        //             return a.createTime - b.createTime;
        //         });

        //         this.removeEmail(uid, emailList[0]._id);
        //         G.server.sendMsgByUid(uid, 'msg_s2c/EmailDel', emailList[0]._id);
        //     }
        // }

        let _id = (await G.mongodb.collection('email').insertOne({
            ttl: new Date(), ...G.mongodb.conversionIdObj(sendEmail)
        })).insertedId.toHexString();

        // 跨服定时器发送的邮件直接返回
        if (isCross) return _id

        sendEmail._id = _id;
        G.server.sendMsgByUid(uid, 'msg_s2c/Email', sendEmail);

        return _id;
    }

    /**发送全服邮件 */
    static async addQuanFuEmail(email: ReqEmail & { createTime?: number; }) {
        let {prize, uid, ...e} = email;
        if (uid != "system") return '全服邮件 uid 为 system : ' + uid;

        let lng = await G.redis.rawGet(`user:lng:${uid}`)

        let sendEmail: MsgEmail = {
            _id: null,
            uid: uid,
            type: e.type,
            title: e.lngTitle ? (e.lngTitle[lng] || e.lngTitle['ja']) : e.title,
            content: e.lngContent ? (e.lngContent[lng] || e.lngContent['ja']) : e.content,
            createTime: e.createTime || G.time,
            contentInsertArr: e.contentInsertArr || [],
            prizelist: [],
            dellist: [],
        };
        if (prize) sendEmail.prizeData = {
            prize: email.prize,
            isGet: false
        };

        if (email.g123log && Object.keys(email.g123log).length > 0) sendEmail.g123log = email.g123log;

        if (email.lngTitle) {
            sendEmail.lngTitle = email.lngTitle
            sendEmail.lngContent = email.lngContent
        }

        let _id = (await G.mongodb.collection('email').insertOne({
            ttl: new Date(),
            ...G.mongodb.conversionIdObj(sendEmail)
        })).insertedId.toHexString();
        sendEmail._id = _id;

        G.server?.broadcastMsg('msg_s2c/Email', sendEmail);

        return _id;
    }
}
