import { Application, BackendSession, HandlerService, } from "pinus";
import { resResult } from "../../../pubUtils/util";
import { STATUS, ITEM_CHANGE_REASON, GROUP_SHOP_PRICE_STATUS, PUSH_ROUTE, ACTIVITY_TYPE, } from "../../../consts";
import { getGroupShopData, getGroupShopDataShow, getGroupShopPriceStatus, getGroupShopServerData, refundGroupShop } from "../../../services/activity/groupShopService";
import { addItems, getGoldObject, handleCost } from "../../../services/role/rewardService";
import { ActivityGroupShopUserRecModel, GroupShopBuyRecord } from "../../../db/ActivityGroupShopUserRec";
import { ActivityGroupShopRecModel, GroupShopRecord } from "../../../db/ActivityGroupShopRec";
import { pick } from "underscore";
import { addRoleToGroupShopChannel, leaveGroupShopChannel } from "../../../services/chatChannelService";
import { sendMessageToGroupShopWithSuc } from "../../../services/pushService";
import { getActivitiesByType } from "../../../services/activity/activityService";
import { GroupShopData } from "../../../domain/activityField/groupShopField";

export default function (app: Application) {
    new HandlerService(app, {});
    return new GroupShopHandler(app);
}

export class GroupShopHandler {
    constructor(private app: Application) {
    }

    /**
    * @description 1. 进入团购主页面
    * @param {{}} msg
    * @param {BackendSession} session
    * @memberof GroupShopHandler
    */
    async getGroupShopPage(msg: { activityId: number }, session: BackendSession) {
        const { activityId } = msg;
        const roleId: string = session.get('roleId');
        const sid: string = session.get('sid');

        let playerData = await getGroupShopDataShow(activityId, roleId);
        if (!playerData) {
            return resResult(STATUS.ACTIVITY_MISSING);
        }
        await addRoleToGroupShopChannel(roleId, sid);

        return resResult(STATUS.SUCCESS, { playerData });
    }

    /**
    * @description 2. 离开团购主页面
    * @param {{}} msg
    * @param {BackendSession} session
    * @memberof GroupShopHandler
    */
    async leaveGroupShopPage(msg: { activityId: number }, session: BackendSession) {
        const roleId: string = session.get('roleId');
        const sid: string = session.get('sid');

        await leaveGroupShopChannel(roleId, sid)
        return resResult(STATUS.SUCCESS);
    }

    /**
    * @description 3. 购买
    * @param {{}} msg
    * @param {BackendSession} session
    * @memberof GroupShopHandler
    */
    async buy(msg: { activityId: number, price: number, itemId: number, buyCnt: number }, session: BackendSession) {
        const { activityId, price: clientPrice, itemId, buyCnt } = msg;
        const roleId: string = session.get('roleId');
        const roleName: string = session.get('roleName');
        const sid: string = session.get('sid');
        
        let playerData = await getGroupShopData(activityId, roleId);
        if (!playerData) return resResult(STATUS.ACTIVITY_MISSING);

        let item = playerData.findItemById(itemId);
        if (!item) return resResult(STATUS.ACTIVITY_GROUP_SHOP_ITEM_NOT_FOUND);
        if(!item.checkBuyCnt(buyCnt)) return resResult(STATUS.ACTIVITY_GROUP_SHOP_BUY_CNT_MAX);

        let curDiscount = item.getCurDiscount();
        let priceStatus = getGroupShopPriceStatus(clientPrice, curDiscount.price);
        if(priceStatus == GROUP_SHOP_PRICE_STATUS.NOT_ENOUGH) return resResult(STATUS.ACTIVITY_GROUP_SHOP_PRICE_ERR);
        let cost = [getGoldObject(curDiscount.price)];
        let result = await handleCost(roleId, sid, cost, ITEM_CHANGE_REASON.ACT_GROUP_SHOP_BUY);
        if(!result) return resResult(STATUS.BATTLE_GOLD_NOT_ENOUGH);

        // 玩家添加次数
        let playerRecord = await ActivityGroupShopUserRecModel.incBuyCnt(activityId, roleId, itemId, item.id, buyCnt, new GroupShopBuyRecord(curDiscount, buyCnt));
        playerData.setPlayerRecord([playerRecord]);
        // 全服添加次数
        let serverRecord = await ActivityGroupShopRecModel.incBuyCnt(activityId, itemId, item.id, buyCnt);
        let isRankUp = playerData.incAllRecord(serverRecord);

        item = playerData.findItemById(itemId);
        let nextDiscount = item.getCurDiscount();
        if(isRankUp) {
            await ActivityGroupShopRecModel.addRecord(activityId, itemId, new GroupShopRecord(nextDiscount));
            // 推送频道
            await sendMessageToGroupShopWithSuc(PUSH_ROUTE.GROUP_SHOP_UPDATE, { activityId, itemId, sum: item.sum, curDiscount: nextDiscount });
        }
        let reward = [{ id: item.id, count: item.count * buyCnt }];
        let goods = await addItems(roleId, roleName, sid, reward, ITEM_CHANGE_REASON.ACT_GROUP_SHOP_BUY);

        return resResult(STATUS.SUCCESS, {
            curItem: pick(item, ['itemId', 'id', 'sum', 'hasBoughtCnt']),
            goods,
            status: priceStatus,
            oldDiscount: curDiscount,
            nextDiscount
        });
    }

    async debugRefund(msg: {}, session: BackendSession) {
        await refundGroupShop(true);
        return resResult(STATUS.SUCCESS);
    }

    async debugSetSum(msg: { itemId: number, sum: number }, session: BackendSession) {
        const roleId: string = session.get('roleId');
        const serverId = session.get('serverId');
        let { itemId = 0, sum = 0 } = msg;
        let activities = await getActivitiesByType(serverId, ACTIVITY_TYPE.GROUP_SHOP);
        if(activities.length <= 0) return resResult(STATUS.ACTIVITY_MISSING);
        for(let activityData of activities) {
            let recs = await ActivityGroupShopRecModel.debugSetSum(activityData.activityId, itemId, sum);
            let playerData = new GroupShopData(activityData, 0, 0);
            playerData.setRecords(recs);

            let items = itemId == 0? playerData.items: [playerData.findItemById(itemId)];
            for(let item of items) {
                if(!item) continue;
                let nextDiscount = item.getCurDiscount();
                // 推送频道
                await sendMessageToGroupShopWithSuc(PUSH_ROUTE.GROUP_SHOP_UPDATE, { activityId: activityData.activityId, itemId: item.itemId, sum: item.sum, curDiscount: nextDiscount });
            }
        }
        let playerData = await getGroupShopDataShow(activities[0].activityId, roleId);

        return resResult(STATUS.SUCCESS, { playerData });
    }

    async debugClearCnt(msg: {  }, session: BackendSession) {
        const roleId: string = session.get('roleId');
        const serverId = session.get('serverId');

        let activities = await getActivitiesByType(serverId, ACTIVITY_TYPE.GROUP_SHOP);
        if(activities.length <= 0) return resResult(STATUS.ACTIVITY_MISSING);

        for(let activityData of activities) {
            await ActivityGroupShopUserRecModel.clearCnt(activityData.activityId, roleId);
        }

        let playerData = await getGroupShopDataShow(activities[0].activityId, roleId);
        return resResult(STATUS.SUCCESS, { playerData });
    }
}