import { Application, BackendSession, pinus } from "pinus";
import { gameData, hasShopType } from "../../../pubUtils/data";
import { parseGoodStr, resResult } from "../../../pubUtils/util";
import { STATUS, GUILD_STRUCTURE, ITID, CONSUME_TYPE, HERO_QUALITY_TYPE, HERO_GROW_MAX, ITEM_CHANGE_REASON } from "../../../consts";
import { UserShopModel } from "../../../db/UserShop";
import { handleCost, addItems } from "../../../services/role/rewardService";
import { SHOP } from "../../../pubUtils/dicParam";
import { HeroModel } from "../../../db/Hero";
import { checkShopInPurchase, getShopDicById, getShopListByType, getShopPrice, getShopMaxBuyTimes } from "../../../services/shopService";
import { RewardInter } from "../../../pubUtils/interface";
import { UserShopTypeModel } from "../../../db/UserShopType";
import { nowSeconds } from "../../../pubUtils/timeUtil";
import { isGoodsHidden } from "../../../services/dataService";
import { RoleModel } from './../../../db/Role';

export default function(app: Application) {
    return new ShopHandler(app);
}

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

    // 获得商品列表
    async getShopList(msg: { shop: number, type: number }, session: BackendSession) {
        let roleId = session.get('roleId');
        let serverId = session.get('serverId');
        let { shop, type } = msg;

        if(!hasShopType(shop, type)) {
            return resResult(STATUS.WRONG_PARMS);
        }

        const result = await getShopListByType(shop, type, roleId, serverId);
        return resResult(STATUS.SUCCESS, result);
    }

    // 读取红点
    async readShop(msg: { shop: number, type: number }, session: BackendSession) {
        let roleId = session.get('roleId');
        let { shop, type } = msg;

        if(!hasShopType(shop, type)) {
            return resResult(STATUS.WRONG_PARMS);
        }

        await UserShopTypeModel.read(roleId, shop, type);
        return resResult(STATUS.SUCCESS);
    }

    // 购买商品
    async purchase(msg: { activityId: number, shopItemId: number, count: number }, session: BackendSession) {
        let roleId = session.get('roleId');
        let roleName = session.get('roleName');
        let sid = session.get('sid');
        let serverId = session.get('serverId');
        let seasonNum = pinus.app.get('pvpSeasonNum');

        let { activityId = 0, shopItemId, count } = msg;

        let dicShopItem = await getShopDicById(activityId, shopItemId, roleId, serverId);
        if(!dicShopItem) return resResult(STATUS.DIC_DATA_NOT_FOUND);
        if(dicShopItem['productID'] && dicShopItem['productID'] != '&') return resResult(STATUS.CAN_NOT_PURCHASE);
        if(dicShopItem['beginTime'] && dicShopItem['beginTime'] > nowSeconds()) return resResult(STATUS.SHOP_CLOSED);
        if(dicShopItem['endTime'] && dicShopItem['endTime'] < nowSeconds()) return resResult(STATUS.SHOP_CLOSED);

        let userShop = await UserShopModel.findByRoleAndItem(roleId, dicShopItem, seasonNum);
    
        let checkResult = await checkShopInPurchase(session, activityId, count, userShop?.count||0, dicShopItem);
        if(checkResult.code != STATUS.SUCCESS.code) {
            return resResult(checkResult);
        }

        // 总计可买次数（从配置表读取）
        const totalCanBuyTimes = getShopMaxBuyTimes(dicShopItem.price);
        if (!totalCanBuyTimes || totalCanBuyTimes <= 0) {
            return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);
        }
    
        // 最大已买次数 = 总计可买次数 - 本次要买次数
        const maxAlreadyBuyTimes = totalCanBuyTimes - count;
        
        // 消耗
        let cost = getShopPrice(dicShopItem.money, count, userShop?.count||0, dicShopItem.price);
        let costResult = await handleCost(roleId, sid, cost, ITEM_CHANGE_REASON.SHOP_PURCHASE);
        if(!costResult) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);

        // 次数
        userShop = await UserShopModel.purchase(roleId, roleName, activityId, dicShopItem, count, seasonNum);
        if (!userShop || (userShop && userShop.count > totalCanBuyTimes)) {
            // rollback 消耗
            let role = await RoleModel.findByRoleId(roleId);
            addItems(roleId, role.roleName, sid, cost, ITEM_CHANGE_REASON.SHOP_PURCHASE);

            // rollback 购买次数
            await UserShopModel.updateCount(roleId, dicShopItem, -count, seasonNum)
            return resResult(STATUS.BUY_COUNT_OVER);
        }

        // 获得
        let reward = [{
            id: dicShopItem.goodId,
            count: count * (dicShopItem.num||1)
        }];
        let goods = await addItems(roleId, roleName, sid, reward, ITEM_CHANGE_REASON.SHOP_PURCHASE);

        return resResult(STATUS.SUCCESS, {
            shopItemId, count,
            goods
        });
        
    }

    // 将魂回收
    async recycleSoul(msg: { goodsId: number, count: number }, session: BackendSession) {
        let roleId = session.get('roleId');
        let roleName = session.get('roleName');
        let sid = session.get('sid');
        let { goodsId, count } = msg;

        if(isGoodsHidden(goodsId)) return resResult(STATUS.ITEM_IS_HIDDEN);
        let dicGoods = gameData.goods.get(goodsId);
        if(!dicGoods) return resResult(STATUS.DIC_DATA_NOT_FOUND);
        let dicItid = ITID.get(dicGoods.itid);
        if(!dicItid) return resResult(STATUS.DIC_DATA_NOT_FOUND);
        if(dicItid.type != CONSUME_TYPE.SOUL) {
            return resResult(STATUS.ITEM_NOT_SOUL);
        }

        let hero = await HeroModel.findByHidAndRole(dicGoods.hid, roleId);
        if(!hero) return resResult(STATUS.HERO_NOT_MAX);
        if(hero.colorStar != HERO_GROW_MAX.COLORSTAR) return resResult(STATUS.HERO_NOT_MAX);

        // 检查自己的数量
        let cost = [{
            id: goodsId, count
        }];
        let costResult = await handleCost(roleId, sid, cost, ITEM_CHANGE_REASON.RECYCLE_SOUL);
        if(!costResult) return resResult(STATUS.BATTLE_CONSUMES_NOT_ENOUGH);

        let reward: RewardInter[] = [];
        switch (dicGoods.quality) {
            case HERO_QUALITY_TYPE.BLUE:
                reward = parseGoodStr(SHOP.HERO_SOUL_BULE); break;
            case HERO_QUALITY_TYPE.PURPLE:
                reward = parseGoodStr(SHOP.HERO_SOUL_PURPLE); break;
            case HERO_QUALITY_TYPE.GOLD:
                reward = parseGoodStr(SHOP.HERO_SOUL_GOLDEN); break;
            case HERO_QUALITY_TYPE.UR:
                reward = parseGoodStr(SHOP.HERO_SOUL_UR); break;
        }
        // 增加货币
        let goods = await addItems(roleId, roleName, sid, reward.map(cur => { return {id: cur.id, count: cur.count * count} }), ITEM_CHANGE_REASON.RECYCLE_SOUL);

        return resResult(STATUS.SUCCESS, {
            goodsId, count,
            goods
        });
    }

    // !测试接口。 去除限购次数
    async debugClearPurchaseLimit(msg: { }, session: BackendSession) {
        let roleId = session.get('roleId');

        await UserShopModel.deleteAccount(roleId);
        return resResult(STATUS.SUCCESS);
    }
}