import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType, mongoose, Ref } from '@typegoose/typegoose';
import Role, { RoleType } from './Role';
import { genCode } from '../pubUtils/util';
import { ROLE_SELECT } from '../consts';

/**
  * 好友系统关系表
  */
@index({ roleId: 1, frdRoleId: 1 })
@index({ applyCode: 1 })

export default class FriendApply extends BaseModel {

    @prop({ required: true, default: '' })
    applyCode: string;	    // 唯一code
    @prop({ required: true, default: '' })
    roleId: string;	    // 操作玩家本人id

    @prop({ required: true, default: '' })
    frdRoleId: string;   // 好友id
    @prop({ required: true, ref: 'Role', type: mongoose.Schema.Types.ObjectId })
    friend: Ref<Role>;

    // 创建申请
    public static async createApply(roleId: string, friend: RoleType) {
        const applyCode = genCode(10);
        const result: FriendApplyType = await FriendApplyModel.findOneAndUpdate({ roleId, frdRoleId: friend.roleId },
            {
                $set: { roleId, frdRoleId: friend.roleId, friend: friend._id },
                $setOnInsert: { applyCode }
            }, { upsert: true, new: true }).lean();

        return result;
    }

    // 获取列表
    public static async getApplyList(roleId: string) {
        const list: FriendApplyType[] = await FriendApplyModel.find({ roleId }, { _id: 0 })
            // .select(select)
            .populate('friend', ROLE_SELECT.SHOW_FRIEND_APPLY_LIST, 'Role')
            .lean({ getters: true, virtuals: true });
        return list;
    }

    // 获取自己发出的申请列表
    public static async getSentApplyList(roleId: string, time: Date) {
        const list: FriendApplyType[] = await FriendApplyModel.find({ frdRoleId: roleId, updatedAt: { $gt: time } }, { _id: 0 })
            .lean({ getters: true });
        return list;
    }

    // 根据applyCode获得申请
    public static async getApplyListByCode(applyCodeList: string[]) {
        const list: FriendApplyType[] = await FriendApplyModel.find({ applyCode: { $in: applyCodeList } }, { _id: 0 })
            // .select(select)
            .populate('friend', ROLE_SELECT.SHOW_FRIEND_APPLY_LIST, 'Role')
            .lean({ getters: true, virtuals: true });
        return list;
    }

    // 删除申请
    public static async deleteApply(applyCodeList: string[]) {
        const { deletedCount } = await FriendApplyModel.deleteMany({ applyCode: { $in: applyCodeList } });
        return deletedCount;
    }

    // 拉黑时删除申请
    public static async deleteApplyByRoles(roleId: string, frdRoleId: string) {
        const { deletedCount: hisRecApplyCount } = await FriendApplyModel.deleteMany({ roleId, frdRoleId });
        const { deletedCount: myRecApplyCount } = await FriendApplyModel.deleteMany({ roleId: frdRoleId, frdRoleId: roleId });
        return { hisRecApplyCount, myRecApplyCount };
    }

    public static async deleteAccount(roleId: string) {
        let result = await FriendApplyModel.deleteMany({ $or: [{ roleId: roleId }, { frdRoleId: roleId }] });
        return result;
    }

}

export const FriendApplyModel = getModelForClass(FriendApply);

export interface FriendApplyType extends Pick<DocumentType<FriendApply>, keyof FriendApply> { };