import BaseModel from './BaseModel';
import { getModelForClass, prop, DocumentType, modelOptions } from '@typegoose/typegoose';
import { CounterModel } from './Counter';
import { COUNTER } from '../consts';

class Rewards {
    @prop({ required: true })
    id: number;
    @prop({ required: true })
    count: number;
}

/**
  * 举报记录
**/
@modelOptions({ schemaOptions: { id: false } })
export default class GiftCode extends BaseModel {
    @prop({ required: true, default: '' })
    id: number;           // 唯一id

    @prop({ required: true, default: '' })
    name: string;           // 礼包码名

    @prop({ required: true, default: false })
    isLimit: boolean;       // 每个码是否有使用次数限制

    @prop({ required: true, default: 0 })
    count: number;         // 每个码可使用次数

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

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

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

    @prop({ required: true, default: '' })
    remark: string;           // 备注

    @prop({ required: true, default: 0 })
    generateType: number;         // 生成类型

    @prop({ required: true, default: 0 })
    generateCnt: number;         // 已生成条数，giftCodeDetail的数量

    @prop({ required: true, default: '' })
    generateCode: string;         // 单条的生成的那一个code

    @prop({ required: true, default: 0 })
    usedNum: number;         // 使用次数

    public static async findData(id: number) {
        let rec: GiftCodeType = await GiftCodeModel.findOne({ id }).lean();
        return rec;
    }

    public static async updateData(id: string|number, values: GiftCodeParam, uid = 1) {
        if(id == 'new') {
            id = await CounterModel.getNewCounter(COUNTER.GIFT_CODE);
        }
        let doc = new GiftCodeModel();
        let createObj = doc.toJSON();
        delete values.id;
        delete createObj._id;
        delete createObj.id;
        for(let key in values) {
            delete createObj[key];
        }

        let rec: GiftCodeType = await GiftCodeModel.findOneAndUpdate({ id }, { $set: {...values, updatedBy: uid}, $setOnInsert: { ...createObj, createdBy: uid } },
            { new: true, upsert: true }).lean(true);
        return rec;
    }

    public static async increaseUsedNum(id: number) {
        let result: GiftCodeType = await GiftCodeModel.findOneAndUpdate({ id }, { $inc: { usedNum: 1 } }, { new: true }).lean();
        return result;
    }

    private static getSearchObj(form: { name?: string, current?: boolean }) {
        let searchObj = {};
        if (form.name != undefined) searchObj['name'] = { $regex: new RegExp(form.name.toString(), 'i') };
        if (form.current) {
            searchObj['beginTime'] = { $lte: new Date };
            searchObj['endTime'] = { $gte: new Date };
        }
        return searchObj
    }

    public static async findByCondition(page: number, pageSize: number, sortField: string, sortOrder: string, form: { name?: string, current?: boolean } = {}) {

        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: GiftCodeType[] = await GiftCodeModel.find(searchObj, { _id: 0 }).limit(pageSize).skip((page - 1) * pageSize).sort(sort).lean({ getters: true, virtuals: true });
        return result;

    }

    public static async countByCondition(form: { name?: string, current?: boolean } = {}) {

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

export const GiftCodeModel = getModelForClass(GiftCode);

export interface GiftCodeType extends Pick<DocumentType<GiftCode>, keyof GiftCode> { }
export type GiftCodeParam = Partial<GiftCodeType>;
