import BaseModel from './BaseModel';
import { index, getModelForClass, prop, DocumentType } from '@typegoose/typegoose';
import { SearchSurveyParam } from '../domain/backEndField/search';
import { Reward } from '../domain/battleField/pvp';
import { genCode } from '../pubUtils/util';
import { nowSeconds } from '../pubUtils/timeUtil';

@index({ surveyId: 1 })
export default class Survey extends BaseModel {

    @prop({ required: true })
    code: string;           // 唯一id

    @prop({ required: true })
    surveyId: string;           // 问卷id

    @prop({ required: true })
    surveyName: string;           // 问卷标题

    @prop({ required: true })
    surveyLink: string;           // 问卷地址

    @prop({ required: true })
    beginTime: number;           // 开始时间

    @prop({ required: true })
    endTime: number;             // 结束时间

    @prop({ required: true })
    lv: number;             // 限制等级

    @prop({ required: true })
    roleIndex: number;           // 玩家

    @prop({ required: true, type: Reward, _id: false })
    reward: Reward[];              // 奖励

    @prop({ required: true })
    mailContent: string;         // 邮件文字

    @prop({ required: true })
    isEnable: boolean;             // 是否显示

    public static async findEnableSurvey(lv: number, select = '') {
        let rec: SurveyType[] = await SurveyModel.find({ isEnable: true, lv: { $lte: lv }, beginTime: { $lte: nowSeconds() }, endTime: { $gte: nowSeconds() } }).select(select).lean();
        return rec;
    }

    public static async findBySurveyId(surveyId: string) {
        let rec: SurveyType = await SurveyModel.findOne({ surveyId }).lean();
        return rec;
    }

    public static async findByCode(code: string) {
        let rec: SurveyType = await SurveyModel.findOne({ code }).lean();
        return rec;
    }

    public static async updateSurvey(code: string, param: SurveyUpdate, select = '') {
        if(code == 'new') code = genCode(6);
        let rec: SurveyType = await SurveyModel.findOneAndUpdate({ code }, { $set: {...param, code} }, {new: true, upsert: true}).select(select).lean();
        return rec;
    }

    public static async receive(code: string, roleId: string) {
        let rec: SurveyType = await SurveyModel.findOneAndUpdate({ code }, { $push: { receivedRole: roleId } }, { new: true }).lean();
        return rec;
    }

    public static async deleteSurvey(code: string) {
        let rec: SurveyType = await SurveyModel.deleteMany({ code }).lean();
        return rec;
    }

    private static getSearchObj(form: SearchSurveyParam) {
        let searchObj = {};
        if (form.surveyName) searchObj['roleName'] = { $regex: new RegExp(form.surveyName.toString(), 'i') };
        return searchObj
    }

    public static async findByCondition(page: number, pageSize: number, sortField: string = 'updatedAt', sortOrder: string = 'descend', form: SearchSurveyParam = {}) {

        let searchObj = this.getSearchObj(form);
        let sort = {};
        if (sortField && sortOrder) {
            if (sortOrder == 'ascend') {
                sort[sortField] = 1;
            } else if (sortOrder == 'descend') {
                sort[sortField] = -1;
            }
        }
        const result: SurveyType[] = await SurveyModel.find(searchObj).limit(pageSize).skip((page - 1) * pageSize).sort(sort).lean({ getters: true, virtuals: true });
        return result;

    }

    public static async countByCondition(form: SearchSurveyParam = {}) {

        let searchObj = this.getSearchObj(form);
        const result = await SurveyModel.count(searchObj);
        return result;
    }
}

export const SurveyModel = getModelForClass(Survey);

export interface SurveyType extends Pick<DocumentType<Survey>, keyof Survey> { };
export type SurveyUpdate = Partial<SurveyType>; // 将所有字段变成可选项
