<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

namespace loyalsoft;

/**
 * Description of ShopProc
 *
 * @author c'y'zhao
 */
class ShopProc {

    /**
     * 逻辑分发
     * 所有的Proc中必须有这样一个方法
     * @param Req $req
     */
    public static function procMain($req) {
        switch ($req->cmd) {
            case CmdCode::cmd_shop_BuyGift:                                     # 6501 商城购买东西
                return ShopProc::ShopBuyGift();
            case CmdCode::cmd_shop_BuyTili:                                     # 6502 买体力
                return ShopProc::BuyTili();
            default:
                Err(ErrCode::cmd_err);
        }
    }

    public static function BuyTili() {
        list($type) = req()->paras;

        $addTili = 0;
        if ($type == 1) {//广告
            $maxNum = glc()->GuanggaoGetTili_DailyMaxNum;
            my_Assert(ctx()->privateState->guanggaoGetTiliNum < $maxNum, ErrCode::user_shop_GuanggaoGetTiliNumLimit);                      
            my_Assert(now() - ctx()->privateState->guanggaoGetTili_ts > 300, ErrCode::user_shop_DownTsLimit);           
            $addTili = glc()->GuanggaoGetTili;
            ctx()->baseInfo->Add_tili(glc()->GuanggaoGetTili);
            ctx()->privateState->guanggaoGetTiliNum += 1;
            
            ctx()->privateState->guanggaoGetTili_ts = now();
        } else {
            $maxNum = glc()->BuyTili_DailyMaxNum;
            my_Assert(ctx()->privateState->buyTiliNum < $maxNum, ErrCode::user_shop_buyTiliNumLimit);

            $arr = explode(',', glc()->BuyTiliCost);
            my_Assert(ctx()->baseInfo->cash >= $arr[0], ErrCode::user_shop_NotRepeatBuy);
            ctx()->baseInfo->Consume_Cash($arr[0]);
            $addTili = $arr[1];
            ctx()->baseInfo->Add_tili($arr[1]);

            ctx()->privateState->buyTiliNum += 1;
        }

        TaskProc::OnBuyTiliOrLookGuanggao();
        UserProc::updateUserInfo();
        return Resp::ok(array(
                    "privateState" => ctx()->privateState,
                    "baseInfo" => ctx()->baseInfo,
                    "tili" => $addTili,
                    "task" => ctx()->task,
        ));
    }

    /**
     * 商城购买东西
     * @return type
     */
    public static function ShopBuyGift() {
        list($type, $typeId, $buyNum) = req()->paras;
        $user = ctx();

        $resultArr = array();
        $dailyArr = array();
        $equip = array();
        $gateGift = array();
        switch ($type) {
            case EnumShopGift::GateGift_Shop://章节礼包
                my_Assert(!in_array($typeId, ctx()->privateState->gateGiftReceived), ErrCode::user_shop_NotRepeatBuy);

                $mo = GameConfig::shop_gategift_getItem($typeId);
                my_Assert($mo != null, ErrCode::err_const_no);

                $price = explode(';', $mo->reward);
                foreach ($price as $value) {
                    $item = explode(',', $value);
                    if (GameConfig::item_getItem($item[0])->itemType == EnumItemType::tuzhiBox) {
                        $dic = GameConfig::item();
                        $list = array();
                        foreach ($dic as $id => $val) {
                            if ($val->itemType == EnumItemType::tuzhi) {
                                $list[] = $val->typeId;
                            }
                        }

                        $randNum = rand(0, count($list) - 1);
                        $tuzhiId = $list[$randNum];
                        $gateGift[] = $tuzhiId . ',1';
                    } else {
                        $gateGift[] = $value;
                    }
                }

                foreach ($gateGift as $str) {
                    StoreProc::AddMultiItemInStore($str);
                }

                ctx()->privateState->gateGiftReceived[] = $typeId;

                ctx()->baseInfo->charge_amt += $mo->curPrice;
                break;
            case EnumShopGift::Daily_Shop://每日商店                             
                $mo = GameConfig::shop_daily_getItem($typeId);
                my_Assert($mo != null, ErrCode::err_const_no);

                my_Assert(in_array($typeId, $user->privateState->dailyShopRandItems), ErrCode::err_const_no);
                if ($mo->type == 1) {
                    $getNum = 0;
                    foreach ($user->privateState->dailyShopReceived as $id) {
                        if ($id == $typeId) {
                            $getNum += 1;
                        }
                    }

                    if ($getNum >= $mo->freeNum) {
                        my_Assert($user->privateState->dailyShop_GuangGaoNum < $mo->num, ErrCode::user_shop_GuanggaoFreeNumLimit);
                        if ($user->privateState->dailyShop_GuangGaoNum >= 1) {
                            my_Assert(now() - $user->privateState->dailyShop_GuangGaoTs >= $mo->downTs, ErrCode::user_shop_DownTsLimit);
                        }
                        $user->privateState->dailyShop_GuangGaoNum += 1;
                        $user->privateState->dailyShop_GuangGaoTs = now();
                    }
                } else {
                    my_Assert(!in_array($typeId, $user->privateState->dailyShopReceived), ErrCode::user_shop_NotRepeatBuy);

                    switch ($mo->costType) {
                        case EnumShopCost::Gold:
                            my_Assert($user->baseInfo->gold >= $mo->costNum, ErrCode::notenough_gold_msg);
                            ctx()->baseInfo->Consume_Gold($mo->costNum);
                            break;
                        case EnumShopCost::Cash:
                            my_Assert($user->baseInfo->cash >= $mo->costNum, ErrCode::notenough_cash_msg);
                            ctx()->baseInfo->Consume_Cash($mo->costNum);
                            break;
                        default:
                            break;
                    }

                    TaskProc::OnBuyNumDailyShop();
                }

//                $str = explode(',', $mo->reward);
//                if ($str[0] == 501) {//暂时还没有
//                }
                //$dailyArr

                StoreProc::AddMultiItemInStore($mo->reward);
                ctx()->privateState->dailyShopReceived[] = $typeId;

                break;

            case EnumShopGift::GemBox_Shop ://宝石宝箱
                $mo = GameConfig::shop_box_getItem($typeId);
                my_Assert($mo != null, ErrCode::err_const_no);

                if ($buyNum > 0) {
                    $cost = $mo->cost_ten;
                    if ($buyNum == 1) {
                        $cost = $mo->cost_one;
                    }
                    my_Assert($user->baseInfo->cash >= $cost, ErrCode::notenough_cash_msg);
                    $user->baseInfo->Consume_Cash($cost);
                }

                if ($mo->type == 1) {
                    if ($buyNum == 0) {
                        $buyNum = 1;
                        my_Assert(now() - $user->privateState->lastFreeGetTs_ShopBoxCommon >= $mo->freeDownTs * 24 * 60 * 60, ErrCode::user_shop_FreeNumLimit);
                        $user->privateState->lastFreeGetTs_ShopBoxCommon = now();
                    }
                } else if ($mo->type == 2) {
                    if ($buyNum == 0) {
                        $buyNum = 1;
                        my_Assert(now() - $user->privateState->lastFreeGetTs_ShopBoxBright >= $mo->freeDownTs * 24 * 60 * 60, ErrCode::user_shop_FreeNumLimit);
                        $user->privateState->lastFreeGetTs_ShopBoxBright = now();
                    }
                }

                $arr = array();
                $arr[] = 1;
                $arr[] = 10;
                if (!in_array($buyNum, $arr)) {
                    $buyNum = 1;
                }
                TaskProc::OnOpenNumBrightBox($typeId, $buyNum);
                TaskProc::OnOpenNumAnyBox($buyNum);

                $perList = explode(';', $mo->percent);
                $allNum = 0;
                foreach ($perList as $key => $value) {
                    $str = explode(',', $value);
                    $allNum += $str[1];
                }

                $allNum *= 10;
                for ($i = 0; $i < $buyNum; $i++) {
                    mt_srand((double) microtime() * 1000000);
                    $buyCount = 0;
                    if ($mo->type == 1) {
                        $user->privateState->buyNum_ShopBoxCommon += 1;
                        $buyCount = $user->privateState->buyNum_ShopBoxCommon;
                    } else {
                        $user->privateState->buyNum_ShopBoxBright += 1;
                        $buyCount = $user->privateState->buyNum_ShopBoxBright;
                    }

                    $bichu1 = explode(',', $mo->bichu1);
                    $qual = 0;
                    if ($buyCount % $bichu1[0] == 0) {
                        $qual = $bichu1[1];
                    }
                    if ($mo->bichu2 != null) {
                        $bichu2 = explode(',', $mo->bichu2);
                        if ($buyCount % $bichu2[0] == 0) {
                            $qual = $bichu2[1];
                        }
                    }

                    if ($qual == 0) {
                        $start = 0;
                        $end = 0;
                        $randNum = mt_rand(1, $allNum);
                        foreach ($perList as $k => $val) {
                            $str = explode(',', $val);
                            $end += $str[1] * 10;
                            if ($randNum > $start && $randNum <= $end) {
                                $qual = $str[0];
                                if ($qual == 4) {//自己加的控制概率的代码 多个出的紫色宝石 降低概率
                                    $descRand = mt_rand(1, 100);
                                    if ($descRand > 20 && $descRand <= 100) {
                                        $qual = 3;
                                    }
                                }
                                if ($qual == 5) {//自己加的控制概率的代码 多个出的金色宝石 降低概率
                                    $descRand = mt_rand(1, 100);
                                    if ($descRand > 10 && $descRand <= 100) {
                                        $qual = 4;
                                    }
                                }
                                if ($qual == 6) {//自己加的控制概率的代码 多个出的金色宝石 降低概率
                                    $descRand = mt_rand(1, 100);
                                    if ($descRand > 8 && $descRand <= 100) {
                                        $qual = 4;
                                    }
                                }
                                break;
                            }
                            $start = $end;
                        }
                    }

                    if ($qual > 0) {
                        $gemDic = GameConfig::gem();
                        $gemList = array();
                        foreach ($gemDic as $key => $value) {
                            if ($value->qual == $qual) {
                                $gemList[] = $value;
                            }
                        }

                        $n = rand(0, count($gemList) - 1);
                        $gem = StoreProc::initGem($gemList[$n]->typeId);
                        
                        if($mo->type == 2){
                            SystemProc::GetGem_GreaterOrangeQual_ShopBox(req()->zoneid, ctx()->baseInfo->name, $gemList[$n]->typeId);
                        }
                        
                        $resultArr[] = $gem->uid;
                        StoreProc::PutGemInStore2($gem);
                    }
                }


                break;
            case EnumShopGift::BujiBox_Shop://补给箱
                $mo = GameConfig::shop_supply_getItem($typeId);
                my_Assert($mo != null, ErrCode::err_const_no);

                $list = explode(',', $mo->cost);
                my_Assert(StlUtil::dictHasProperty($user->store->items, $list[0]), ErrCode::notenough_item);

                $user->store->removeItem($list[0], $list[1]);
                $user->baseInfo->Add_Gold($mo->gold);
                if (!StlUtil::dictHasProperty($user->privateState->junbeiShopNumRecord, $typeId)) {
                    $user->privateState->junbeiShopNumRecord->$typeId = 0;
                }
                $num = $user->privateState->junbeiShopNumRecord->$typeId += 1;

                if (!StlUtil::dictHasProperty($user->privateState->supplyBichuDic, $typeId)) {
                    $user->privateState->supplyBichuDic->$typeId = 0;
                }
                $user->privateState->supplyBichuDic->$typeId += 1;

                my_Assert($num <= $mo->limitNum, ErrCode::user_shop_LimitNum);
                $list = explode(';', $mo->percent);
                $randNum = rand(0, 10000);
                $start = 0;
                $end = 0;
                $qual = null;
                foreach ($list as $item) {
                    $arr = explode(',', $item);

                    $per = $arr[2] * 100;
                    $end += $per;
                    if ($randNum >= $start && $randNum < $end) {
                        $qual = $arr[0] . ',' . $arr[1]; //品阶，稀有度
                        break;
                    }
                    $start = $end;
                }
                //必出
                $bichu = explode(',', $mo->bichu);
                $qArr = explode(',', $qual);
                if ($qArr[0] == $bichu[1] && $qArr[1] == $bichu[2]) {//得到必出,重置数量记录
                    $user->privateState->supplyBichuDic->$typeId = 0;
                    $qual = $bichu[1] . ',' . $bichu[2];
                } else {
                    if ($user->privateState->supplyBichuDic->$typeId == $bichu[0]) {
                        $qual = $bichu[1] . ',' . $bichu[2];
                        $user->privateState->supplyBichuDic->$typeId = 0;
                    }
                }

                if ($qual != null) {
                    $str = explode(',', $qual);

                    $equipList = array();
                    $dic = GameConfig::equip();
                    foreach ($dic as $tid => $item) {
                        if ($item->qual == $str[0] && $item->rarity == $str[1]) {
                            $equipList[] = $item->typeId;
                        }
                    }

                    $rNum = rand(0, count($equipList) - 1);
                    $equipId = $equipList[$rNum];
                    StoreProc::PutEquipInStore($equipId, 1);
                    $equip[] = $equipId;
                }

                break;
            case EnumShopGift::Cash_Shop://商城-钻石
                $mo = GameConfig::shop_cash_getItem($typeId);
                my_Assert($mo != null, ErrCode::err_const_no);

                $tag = false;
                if (in_array($typeId, $user->privateState->cashShopReceived)) {
                    $tag = true;
                }

                $reward = $mo->reward;
                if (!$tag) {
                    $reward = $mo->reward . ';' . $mo->reward;
                }

                StoreProc::AddMultiItemInStore($reward);
                $user->baseInfo->charge_amt += $mo->price;
                $user->privateState->cashShopReceived[] = $typeId;
                TaskProc::OnRecharge();
                break;
            case EnumShopGift::Gold_Shop://商城-金币--可以多次购买
                $mo = GameConfig::shop_gold_getItem($typeId);
                my_Assert($mo != null, ErrCode::err_const_no);

                $tempNum = 0;
                foreach ($user->privateState->goldShopReceived as $key) {
                    if ($key == $typeId) {
                        $tempNum += 1;
                    }
                }

                if ($tempNum >= $mo->freeNum) {
                    $ts = 0;
                    switch ($typeId) {
                        case 1:
                            $ts = $user->privateState->goldShop_CoolDownTs_1;
                            break;
                        case 2:
                            $ts = $user->privateState->goldShop_CoolDownTs_2;
                            break;
                        case 3:
                            $ts = $user->privateState->goldShop_CoolDownTs_3;
                            break;
                    }

                    //收费买
                    if ($typeId == 1 && $user->privateState->goldShop_GuangGaoNum < $mo->guanggaoNum) {
                        $user->privateState->goldShop_GuangGaoNum += 1;
                    } else {
                        my_Assert($user->baseInfo->cash >= $mo->price, ErrCode::notenough_cash_msg);
                        ctx()->baseInfo->Consume_Cash($mo->price);
                    }

                    if ($ts == 0) {
                        switch ($typeId) {
                            case 1:
                                $user->privateState->goldShop_CoolDownTs_1 = now();
                                break;
                            case 2:
                                $user->privateState->goldShop_CoolDownTs_2 = now();
                                break;
                            case 3:
                                $user->privateState->goldShop_CoolDownTs_3 = now();
                                break;
                        }

                        //$user->privateState->goldShopReceived[] = $typeId;
                    } else {
                        my_Assert(now() - $ts >= $mo->downTs, ErrCode::user_shop_DownTsLimit);
                        switch ($typeId) {
                            case 1:
                                $user->privateState->goldShop_CoolDownTs_1 = now();
                                break;
                            case 2:
                                $user->privateState->goldShop_CoolDownTs_2 = now();
                                break;
                            case 3:
                                $user->privateState->goldShop_CoolDownTs_3 = now();
                                break;
                        }
                    }

                    if ($typeId == 1 && $user->privateState->goldShop_GuangGaoNum >= $mo->guanggaoNum) {
                        $user->privateState->goldShop_CoolDownTs_1 = 0;
                    }
                }


                $user->privateState->goldShopReceived[] = $typeId;
                StoreProc::AddMultiItemInStore($mo->reward);

                break;

            case EnumShopGift::MonthCard_Shop:
                $mo = GameConfig::shop_monthcard_getItem($typeId);
                my_Assert($mo != null, ErrCode::err_const_no);

                //$user->privateState->monthCardShop_Received[] = $typeId;                             
                if ($typeId == 1) {
                    my_Assert($user->privateState->monthCardShop_ts == 0, ErrCode::err_const_no);
                    $user->privateState->monthCardShop_ts = now();
                    StoreProc::AddMultiItemInStore($mo->buy_reward);
                    EmailProc::SendMonthCardRewardMail(req()->zoneid, req()->uid, $mo->daily_reward);
                    
                } else {
                    my_Assert($user->privateState->honourCardShop_ts == 0, ErrCode::err_const_no);
                    $user->privateState->honourCardShop_ts = now();
                }
                break;
            default:
                break;
        }

//        if (ctx()->baseInfo->charge_amt > 0 && ctx()->baseInfo->fRechargePriceReceived == 0) {
//            StoreProc::AddMultiItemInStore(GameConfig::globalsettings()->FirstRechargePrice);
//            ctx()->baseInfo->fRechargePriceReceived = 1;
//        }


        ctx($user);
        UserProc::updateUserInfo();
        return Resp::ok(array(
                    'gemBox' => $resultArr,
                    'gateGift' => $gateGift,
                    'cash' => $user->baseInfo->cash,
                    'gold' => $user->baseInfo->gold,
                    'privateState' => $user->privateState,
                    'store' => $user->store,
                    'task' => ctx()->task,
                    'reward' => StoreProc::$reward,
        ));
    }

    /**
     * 商城每日重置
     */
    public static function ShopDailyClear() {
        ctx()->privateState->dailyShopReceived = array();
        ctx()->privateState->goldShopReceived = array();
        $num = count(ctx()->privateState->goldShopReceived);

        $arr = ctx()->privateState->goldShopReceived;
        for ($i = 0; $i < $num; $i++) {
            if ($arr[$i] == 1) {
                StlUtil::arrayRemoveAt($arr, $i);
            }
        }

        ctx()->privateState->goldShop_CoolDownTs_1 = 0;
        ctx()->privateState->goldShop_GuangGaoNum = 0;

        ctx()->privateState->junbeiShopNumRecord = new \stdClass();

        ctx()->privateState->dailyShop_GuangGaoNum = 0;
        ctx()->privateState->dailyShop_GuangGaoTs = 0;

        ctx()->privateState->guanggaoGetTiliNum = 0;
        ctx()->privateState->buyTiliNum = 0;

        self::ShopMonthClear();
    }

    /**
     * 月卡按照时间记录的一个月后清理
     */
    public static function ShopMonthClear() {
        $monthTs = 30 * 24 * 60 * 60;

        if (ctx()->privateState->monthCardShop_ts > 0) {
            if (now() - ctx()->privateState->monthCardShop_ts >= $monthTs) {
                ctx()->privateState->monthCardShop_ts = 0;
            } else {
                $mo = GameConfig::shop_monthcard_getItem(1);
                EmailProc::SendMonthCardRewardMail(req()->zoneid, req()->uid, $mo->daily_reward);
            }
        }

        if (ctx()->privateState->honourCardShop_ts > 0 && now() - ctx()->privateState->honourCardShop_ts >= $monthTs) {
            ctx()->privateState->honourCardShop_ts = 0;
        }
    }

    /**
     * 每日商城随机6个道具
     * @return type
     */
    public static function DailyShopItemRand() {
        $dataDic = new \stdClass();

        $dic = GameConfig::shop_daily();
        if ($dic == null) {
            return;
        }

        foreach ($dic as $typeId => $mo) {
            $type = $mo->type;
            if (StlUtil::dictHasProperty($dataDic, $type)) {
                $list = $dataDic->$type;
                $list[] = $typeId;
                $dataDic->$type = $list;
            } else {
                $list = array();
                $list[] = $typeId;
                $dataDic->$type = $list;
            }
        }
        $result = array();
        $arrType = array(1, 2, 3, 2, 4, 3);
        foreach ($arrType as $k) {
            if (StlUtil::dictHasProperty($dataDic, $k) && count($dataDic->$k) > 0) {
                $arr2 = $dataDic->$k;
                if ($k == 1) {
                    $result[] = $arr2[0];
                    continue;
                }

                $allNum = 0;
                foreach ($arr2 as $giftTypeId) {
                    $allNum += GameConfig::shop_daily_getItem($giftTypeId)->per;
                }

                $randNum = rand(1, $allNum);
                $start = 0;
                $end = 0;
                $index = 0;
                foreach ($arr2 as $itemId) {
                    $per = GameConfig::shop_daily_getItem($itemId)->per;
                    $end += $per;
                    if ($randNum >= $start && $randNum < $end) {
                        $result[] = $itemId;
                        break;
                    }
                    $start = $end;
                    $index += 1;
                }
                unset($arr2[$index]);

                $dataDic->$k = array_values($arr2);
            }
        }


        ctx()->privateState->dailyShopRandItems = $result;
        UserProc::updateUserInfo();
    }

}
