<?php

/**
 * 段位Model
 */

namespace Game\Model;

use Framework\Lib\Utils;
use Framework\Log\LogMark;
use Framework\Logic\CommonTimerLogic;
use Framework\Network\SendMessage;
use Framework\Logic\PacketCacheLogic;
use Game\Constant\ClientErrorCode;
use Game\Constant\ConstTemplate\TemplateConst;
use Game\Constant\ConstTemplate\TemplateItem;
use Game\Constant\ConstTemplate\TemplateSeasonReward;
use Game\Constant\ConstTemplate\TemplateSeasonRewardCondition;
use Game\Constant\GameConstantDefine;
use Game\Constant\GameErrorCode;
use Game\Constant\ModelTypeDefine;
use Game\Constant\TemplateDefine;
use Game\Data\PaiWei\PaiWeiGoldData;
use Game\Data\PaiWei\PaiweiLevelData;
use Game\Constant\ConstTemplate\TemplateLevel;
use Framework\Logic\TemplateHelp;
use Game\Logic\EventConditionLogic;
use Game\Logic\Friend\FriendRandomLogic;
use Game\Logic\ItemLogic;
use Game\Logic\RankLogic;
use Game\Logic\Room\RoomLogic;
use Game\Logic\SeasonLogic;
use Game\Model\Rank\RankModel;
use Game\Protobuf\GCReceiveSeasonReward;
use Game\Protobuf\GCUpdateSeason;
use Game\Protobuf\PacketId;
use Game\Protobuf\GCPaiweiLevelInfo;

class PaiweiLevelModel
{
    use TemplateHelp;
    use PacketCacheLogic;
    use EventConditionLogic;
    use RankLogic;
    use SeasonLogic;
    use RoomLogic;
    use ItemLogic;
    use CommonTimerLogic;
    use FriendRandomLogic;

    public PaiweiLevelData $data;

    private GCPaiweiLevelInfo $sendMessage;

    private int $playerId;

    public function __construct()
    {
        $this->data = new PaiweiLevelData();
    }

    public function setPlayerId($playerId)
    {
        $this->playerId = $playerId;
    }

    /***
     * 初始化段位信息
     * @param int $playerId
     */
    private function initLevel(int $playerId)
    {
        //赛季信息获取
        $seasonId = $this->getSeasonId();
        $this->data->playerId = $playerId;
        $this->data->levelId = 1;
        $this->data->score = 0;
        $this->data->maxLevelId = 1;
        $this->data->guardScore = 0;
        $this->data->record = 0;
        $this->data->seasonScore = (int)$this->getTerm(
            TemplateDefine::TYPE_SEASON_REWARD_CONDITION,
            TemplateSeasonRewardCondition::LOGIN_DAY,
            TemplateSeasonRewardCondition::Number
        );  //初始赛季分,第一次登陆分
        $this->data->seasonReward = [];
        $this->data->overFlowExp = 0;
        $this->data->haveRewardNum = 0;
        $this->data->rewardNum = 0;

        $positionArr = array(
            PaiweiLevelData::POSITION_RACE,
            PaiweiLevelData::POSITION_JAM,
            PaiweiLevelData::POSITION_HELP,
        );
        //初始时随机位置
        shuffle($positionArr);
        $this->data->positionOrder = json_encode($positionArr);
        $this->data->seasonId = $seasonId;
        $this->data->createDB();
    }

    /***
     * @return array
     * 获取校验数据,键名升序
     */
    public function getSignData():array
    {
        $data = $this->searchLevelData();
        return array(
            array(
                "Id" => $data->seasonId,
                "LevelId" => $data->levelId,
                "Season" => $data->seasonId,
                "SeasonStatus" => $this->getSeasonStatus(),
                "MaxGrade" => $data->maxLevelId,
                "CurrentScore" => $data->score,
                "ProtectScore" => $data->guardScore
            )
        );
    }

    /***
     * 查询段位信息
     * @return PaiweiLevelData
     */
    public function searchLevelData(): PaiweiLevelData
    {
        $this->data->playerId = $this->playerId;
        if (false == $this->data->getLevelFromDB()) {
            LogMark::getInstance()->markInfo(
                "[PaiweiModel] register search data",
                array(
                    "playerId" => $this->playerId
                )
            );
            //初始信息
            $this->initLevel($this->playerId);
        }
        if ($this->data->seasonId == 0) {
            //初始信息
            $this->initLevel($this->playerId);
        }
        return $this->data;
    }

    //查询他人排位信息
    public function searchTargetLevelData(int $targetPlayerId): PaiweiLevelData
    {
        $data = new PaiweiLevelData();
        $data->playerId = $targetPlayerId;
        $data->getLevelFromDB();
        return $data;
    }

    //修改他人信息
    public function updateTargetLevelData(int $targetPlayerId, array $data)
    {
        $levelData = new PaiweiLevelData();
        $levelData->saveTargetLevel($targetPlayerId, $data);
    }

    /***
     * 更新积分
     * @param int $addScore         变化的积分,正数为增加,负数减少
     * @param int $addGuardScore    增加的保护分
     * @param bool $isWin           胜负标志
     */
    public function changeScore(int $addScore, int $addGuardScore, bool $isWin = true)
    {
        LogMark::getInstance()->markDebug(
            "[PaiweiModel] start changeScore",
            array(
                "playerId" => $this->playerId,
                "addScore" => $addScore,
                "addGuardScore" => $addGuardScore,
                "nowInfo" => $this->data
            )
        );
        $this->searchLevelData();
        $this->data->guardScore += $addGuardScore;
        $oldLevel = $this->data->levelId;
        //保护分上限
        $configGuardMax = $this->getTerm(TemplateDefine::TYPE_CONST,
                                   TemplateConst::Const_1_GuardScoreMax,
                                    TemplateConst::ConstNum);
        if (is_null($configGuardMax)) {
            LogMark::getInstance()->markWarn(
                GameErrorCode::TEMPLATE_ID_NOT_FOUND,
                "[PaiweiModel] get Tpl table const, id not found",
                array(
                    "id" => TemplateConst::Const_1_GuardScoreMax,
                    "TemplateTable" => TemplateDefine::TYPE_CONST
                )
            );
            return ;
        }
        if ($this->data->guardScore >= $configGuardMax) {
            $this->data->guardScore = $configGuardMax;
        }
        if ($addScore > 0) {
            $this->addLevelScore($addScore);
        } else {
            $this->subLevelScore($addScore);
        }

        $this->changeRecord($isWin);
        $this->data->saveLevel();
        // 发送消息
        $this->addSendMessage();
        if ($this->data->levelId != $oldLevel) {
            //段位变化,修改好友随机搜索表
            $this->updateRandomScore($this->data->levelId);
        }
        LogMark::getInstance()->markDebug(
            "[PaiweiModel] end changeScore",
            array(
                "playerId" => $this->playerId,
                "addScore" => $addScore,
                "addGuardScore" => $addGuardScore,
                "newInfo" => $this->data
            )
        );
    }

    // 更新赛季排行榜数据
    private function updateRankSeason(int $score) {
        $rankType = RankModel::RANK_SEASON;
        $seasonID = $this->getSeasonId();
        if(in_array($rankType, RankModel::RANK_SEASON_TYPE)) {
            if($seasonID == 0) {
                return false;
            }
        }
        $this->addEventConditionValue(
            $this->getRankingKey($rankType, $seasonID, 0),
            $score
        );
        return $this->data->score;
    }

    // 更新全服排行榜数据
    private function updateRankFullServer(int $score) {
        $rankType = RankModel::RANK_FULL;
        $seasonID = 0;

        // 获取当前段位积分
        $realScore = $this->data->score;

        // 获取全服的score
        $oldScore = $this->getSingleEventConditionValue(
            $this->getRankingKey($rankType, $seasonID, 0)
        );
        // 如果相加大于全服的积分 则更新
        if($realScore > $oldScore) {
            return $this->addEventConditionValue(
                $this->getRankingKey($rankType, $seasonID, 0),
                $realScore - $oldScore
            );
        }
        // 无需更新
        return true;
    }

    /***
     * @param int $addScore
     * 增加积分,判断段位上升
     */
    private function addLevelScore(int $addScore)
    {
        //更新积分和等级
        $this->data->score += $addScore;
        $configLevelData = $this->getTable(TemplateDefine::TYPE_PAIWEI_LEVEL);
        $configLevelData = array_slice($configLevelData, $this->data->levelId - 1, null, true);
        foreach ($configLevelData as $id => $data) {
            if ($this->data->score >= $data[TemplateLevel::BpMax] && isset($configLevelData[$this->data->levelId +1])) {
                $this->data->levelId = $id + 1;
            }
            if ($this->data->score < $data[TemplateLevel::BpMin]) {
                break;
            }
        }

        //历史最高段位检查
        if ($this->data->levelId > $this->data->maxLevelId) {
            $this->data->maxLevelId = $this->data->levelId;
        }

        //更新排位赛金牌选手排行
        $this->updatePaiWeiGoldPlayerRank();

        // TODO：更新赛季榜 更新全服榜
        $nowScore = $this->updateRankFullServer($addScore);
        if(!is_bool($nowScore)) {
            $this->changeRankScore(RankModel::RANK_FULL, $nowScore);
        }

        $nowSeasonScore = $this->updateRankSeason($addScore);
        if(!is_bool($nowSeasonScore)) {
            $this->changeRankScore(RankModel::RANK_SEASON, $nowSeasonScore);
        }
    }

    /***
     * @param int $addScore 为负数
     * 减分,判断段位下降
     * @param bool $isGm
     */
    private function subLevelScore(int $addScore, bool $isGm = false)
    {
        if ($isGm) {
            if(($this->data->score + $addScore) < 0) {
                $this->data->score = 0;
            }
        } else {
            //新手保护,不减分
            $configGuardLevel = $this->getTerm(TemplateDefine::TYPE_CONST,
                                               TemplateConst::Const_10_GuardLevel,
                                               TemplateConst::ConstNum);
            if ($this->data->levelId <= $configGuardLevel) {
                return ;
            }
            //检查触发保护,触发保护后,本次不扣分,保护分清零
            //保护分触发值
            $configGuardMax = $this->getTerm(TemplateDefine::TYPE_CONST,
                                             TemplateConst::Const_1_GuardScoreMax,
                                             TemplateConst::ConstNum);

            if ($this->data->guardScore >= $configGuardMax) {
                $this->data->guardScore = 0;
                return ;
            }
            //掉段保护
            //当段位分为0「当前段位」时，如果下一局再次扣分则降级。（当玩家输掉比赛扣分时，最多扣至当前段位0分）
            $levelMinExp = (int)$this->getTerm(
                TemplateDefine::TYPE_PAIWEI_LEVEL,
                $this->data->levelId,
                TemplateLevel::BpMin
            );
            if ($this->data->score + $addScore < $levelMinExp && $this->data->score > $levelMinExp) {
                $this->data->score = $levelMinExp;
            } else {
                $this->data->score += $addScore;
            }

            //检查排位保护卡,扣道具不减分
            $itemId = TemplateItem::ITEM_ID_PAI_WEI_GUARD_CARD;
            if ($this->getItemNumByTplID($itemId) > 0) {
                //扣除道具
                $this->setLogConsumeItemSource(GameConstantDefine::ITEM_CONSUME_SOURCE_PAI_WEI_GUARD);
                $this->subItemByTID($itemId, 1);
                return;
            }
        }

        //更新积分和等级
        $configLevelData = $this->getTable(TemplateDefine::TYPE_PAIWEI_LEVEL);
        $configLevelData = array_slice($configLevelData, 0, $this->data->levelId, true);
        krsort($configLevelData);
        foreach ($configLevelData as $id => $data) {
            if ($this->data->score >= $data[TemplateLevel::BpMin] && $this->data->score <= $data[TemplateLevel::BpMax]) {
                $this->data->levelId = $id;
                break;
            }
        }
        if ($this->data->levelId <= 0) {
            $this->data->levelId = 1;
            if ($this->data->score < 0) {
                $this->data->score = 0;
            }
        }
        //更新排位赛金牌选手排行
        $this->updatePaiWeiGoldPlayerRank();
    }

    /***
     * 更新连胜记录
     * @param bool $isWin
     */
    public function changeRecord($isWin = true)
    {
        $seasonMatchRecord = json_decode($this->data->seasonMatchRecord, true);
        //连胜或连败记录 >0为连胜 <0为连败
        $record = $this->data->record;
        if ($isWin) {
            $record = $record >= 0 ? $record + 1 : 1;
            $this->data->dailyWinNum++;
            $seasonMatchRecord[] = 1;
        } else {
            $record = $record <= 0 ? $record - 1 : -1;
            $seasonMatchRecord[] = 0;
        }
        //记录30场比赛胜负
        $maxRecord = $this->getTerm(
            TemplateDefine::TYPE_CONST,
            TemplateConst::Const_Ranking_Season_Record_Max,
            TemplateConst::ConstNum
        );
        if (count($seasonMatchRecord) > $maxRecord) {
            $seasonMatchRecord = array_slice($seasonMatchRecord, -$maxRecord, $maxRecord);
        }
        $this->data->seasonMatchRecord = json_encode($seasonMatchRecord);
        $this->data->dailyMatchNum++;
        $this->data->record = $record;
    }

    public function gmChangeScore(int $addScore, int $addGuardScore)
    {
        $this->searchLevelData();
        if ($this->playerId == 0 || $this->data->seasonId == 0) {
            return;
        }
        $this->data->guardScore += $addGuardScore;
        //保护分上限
        $configGuardMax = $this->getTerm(TemplateDefine::TYPE_CONST,
                                         TemplateConst::Const_1_GuardScoreMax,
                                         TemplateConst::ConstNum);
        if ($this->data->guardScore > $configGuardMax) {
            $this->data->guardScore = intval($configGuardMax);
        }
        if ($this->data->guardScore < 0) {
            $this->data->guardScore = 0;
        }
        // 积分
        if ($addScore > 0) {
            $this->addLevelScore($addScore);
        } else {
            $this->subLevelScore($addScore, true);
        }
        $this->data->saveLevel();
        //发送消息
        $this->addSendMessage();
        $this->addPacketMessage();
    }

    public function updatePositionOrder(array $positionOrder)
    {
        $this->searchLevelData();
        $this->data->positionOrder = json_encode($positionOrder);
        $this->data->saveLevel();
        //发送消息
        $this->addSendMessage();
        $this->sendMessage();
        //通知房间其他人
        $this->syncPlayerPosition($this->data);
    }

    //更新间隔时间
    public function updateGapDay(int $day)
    {
        $this->searchLevelData();
        $this->data->gapDay = $day;
        //赛季奖励分--登录
        $this->updateSeasonScore(TemplateSeasonRewardCondition::LOGIN_DAY, $this->playerId);
    }

    public function addSendMessage()
    {
        $sendMessage = new GCPaiweiLevelInfo();
        $sendMessage->setLevelId($this->data->levelId);
        $sendMessage->setScore($this->data->score);
        $sendMessage->setMaxLevelId($this->data->maxLevelId);
        $sendMessage->setGuardScore($this->data->score);
        $sendMessage->setSeasonId($this->data->seasonId);
        $sendMessage->setPositionOrder(json_decode($this->data->positionOrder, true));
        $sendMessage->setIsRandom(PaiweiLevelData::POSITION_RANDOM_CLOSE);
        $this->sendMessage = $sendMessage;
    }

    public function sendMessage()
    {
        SendMessage::getInstance()->sendClient(PacketId::GC_PaiweiLevelInfo, $this->sendMessage);
    }

    public function addPacketMessage()
    {
        $this->addPacket(PacketId::GC_MailUpdate, $this->sendMessage);
    }

    //积分等数据重置
    public function resetPaiweiLevel(int $newSeasonId)
    {
        $this->searchLevelData();
        LogMark::getInstance()->markDebug(
            "[PaiweiLevelModel] season change,Reset Paiwei data,old data",
            (array)$this->data
        );
        $this->data->seasonId = $newSeasonId;

        //赛季积分重置逻辑:段位置为ResetLevel,积分置为ResetLevel对应等级积分下限
        $configLevelData = $this->getTable(TemplateDefine::TYPE_PAIWEI_LEVEL);
        $this->data->levelId = $configLevelData[$this->data->levelId][TemplateLevel::ResetLevel];
        $this->data->score = $configLevelData[$this->data->levelId][TemplateLevel::BpMin];

        $this->data->seasonScore = 0;
        $this->data->seasonReward = [];
        $this->data->overFlowExp = 0;
        $this->data->haveRewardNum = 0;
        $this->data->rewardNum = 0;
        //保存
        $this->data->saveLevel();
        LogMark::getInstance()->markDebug(
            "[PaiWeiLevelModel] season change,Reset PaiWei data,new data",
            (array)$this->data
        );
        //通知赛季更新
        $message = new GCUpdateSeason();
        $message->setSeasonId($newSeasonId);
        $message->setSeasonStatus($this->getSeasonStatus());
        $message->setLevelId($this->data->levelId);
        $message->setScore($this->data->score);
        $message->setMaxLevelId($this->data->maxLevelId);
        $message->setGuardScore($this->data->guardScore);
        SendMessage::getInstance()->sendClient(PacketId::GC_UpdateSeason, $message);
    }

    public function addSeasonScore(int $addScore, int $playerID = 0) {
        if(!empty($playerID)) {
            $this->data->playerId = $playerID;
        }
        $this->searchLevelData();
        // 最大经验值
        $scoreMax = $this->getTerm(TemplateDefine::TYPE_CONST, TemplateConst::Const_Season_Score_Max,
            TemplateConst::ConstNum);
        if(is_null($scoreMax)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                'update season score tplID const not found error!'
            );
            return ;
        }
        // 溢出上限
        $maxOverFlow = $this->getTerm(TemplateDefine::TYPE_CONST,
            TemplateConst::Const_Season_Loop_Max_Exp, TemplateConst::ConstNum);
        $num = 0;
        if($this->data->seasonScore >= $scoreMax) {
            $val = $this->data->overFlowExp + $addScore;
            $num = intdiv($val, $maxOverFlow);
            $extra = $val % $maxOverFlow;
            $this->data->overFlowExp = $extra;
        } else {
            $this->data->seasonScore += $addScore;
            if($this->data->seasonScore >= $scoreMax) {
                $val = $this->data->seasonScore - $scoreMax;
                $num = intdiv($val, $maxOverFlow);
                $extra = $val % $maxOverFlow;
                $this->data->overFlowExp = $extra;
                $this->data->seasonScore = $scoreMax;
            }
        }

        // 处理增加次数限制
        if(!empty($num)) {
            // 溢出上限
            $maxNum = (int)$this->getTerm(TemplateDefine::TYPE_CONST,
                TemplateConst::Const_Season_Loop_Num_Max, TemplateConst::ConstNum);
            $rewardNum = $this->data->haveRewardNum + $num + $this->data->rewardNum;
            if($rewardNum >= $maxNum) {
                $this->data->haveRewardNum = $maxNum - $this->data->rewardNum;
            } else {
                $this->data->haveRewardNum = $num + $this->data->haveRewardNum;
            }
        }

        $this->data->saveLevel();
    }

    // 赛季积分更新
    public function updateSeasonScore(int $type, int $playerID) {
        if(!empty($playerID)) {
            $this->data->playerId = $playerID;
        }
        $this->searchLevelData();
        // 最大经验值
        $scoreMax = $this->getTerm(
            TemplateDefine::TYPE_CONST,
            TemplateConst::Const_Season_Score_Max,
            TemplateConst::ConstNum);
        if(is_null($scoreMax)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                'update season score tplID const not found error!', ['type' => $type]
            );
            return ;
        }
        // 溢出上限
        $maxOverFlow = $this->getTerm(
            TemplateDefine::TYPE_CONST,
            TemplateConst::Const_Season_Loop_Max_Exp,
            TemplateConst::ConstNum);

        $addScore = $this->getTerm(
            TemplateDefine::TYPE_SEASON_REWARD_CONDITION,
            $type,
            TemplateSeasonRewardCondition::Number
        );

        $num = 0;
        if($this->data->seasonScore >= $scoreMax) {
            $val = $this->data->overFlowExp + $addScore;
            $num = intdiv($val, $maxOverFlow);
            $extra = $val % $maxOverFlow;
            $this->data->overFlowExp = $extra;
        } else {
            $this->data->seasonScore += $addScore;
            if($this->data->seasonScore >= $scoreMax) {
                $val = $this->data->seasonScore - $scoreMax;
                $num = intdiv($val, $maxOverFlow);
                $extra = $val % $maxOverFlow;
                $this->data->overFlowExp = $extra;
                $this->data->seasonScore = $scoreMax;
            }
        }

        // 处理增加次数限制
        if(!empty($num)) {
            // 溢出上限
            $maxNum = (int)$this->getTerm(TemplateDefine::TYPE_CONST,
                TemplateConst::Const_Season_Loop_Num_Max, TemplateConst::ConstNum);
            $rewardNum = $this->data->haveRewardNum + $num + $this->data->rewardNum;
            if($rewardNum >= $maxNum) {
                $this->data->haveRewardNum = $maxNum - $this->data->rewardNum;
            } else {
                $this->data->haveRewardNum = $num + $this->data->haveRewardNum;
            }
        }

        $this->data->saveLevel();
    }

    // 领取循环奖励
    public function receiveLoopReward() {
        $this->searchLevelData();
        // 没有可领取
        if($this->data->haveRewardNum == 0) {
            return ;
        }
        // 领取奖励
        $itemID = (int)$this->getTerm(TemplateDefine::TYPE_CONST,
            TemplateConst::Const_Season_Loop_Item_ID, TemplateConst::ConstNum);
        $itemNum = (int)$this->getTerm(TemplateDefine::TYPE_CONST,
            TemplateConst::Const_Season_Loop_Item_Num, TemplateConst::ConstNum);

        $num = $itemNum * $this->data->haveRewardNum;
        $this->setLogAddItemSource(GameConstantDefine::ITEM_ADD_SOURCE_SEASON_REWARD);
        $this->gainItemArr([$itemID => $num]);
        $this->data->rewardNum += $this->data->haveRewardNum;
        $this->data->haveRewardNum = 0;
        $this->data->saveLevel();
    }

    // 领取单个赛季奖励
    public function receive(int $tplID) {
        $this->searchLevelData();
        // 分数是否可以领取
        $cfg = $this->getTitle(TemplateDefine::TYPE_SEASON_REWARD, $tplID);
        if(is_null($cfg)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                'receive season reward tplID not found error!', ['tplID' => $tplID]
            );
            $this->sendSeasonReceiveMsg(ClientErrorCode::SEASON_REWARD_ERROR, []);
            return ;
        }

        $score = $cfg[TemplateSeasonReward::DemandExp];
        if($this->data->seasonScore < $score) {
            $this->sendSeasonReceiveMsg(ClientErrorCode::SEASON_REWARD_NOT_SATE_ERROR, []);
            return ;
        }

        // 检测是否已经领取
        if(in_array($tplID, $this->data->seasonReward)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR, 'season repeated receive error!');
            $this->sendSeasonReceiveMsg(ClientErrorCode::SEASON_REWARD_REPEATED_ERROR, []);
            return ;
        }

        // 发送奖励道具
        if(!$this->gainItemArr([$cfg[TemplateSeasonReward::ItemId]=> $cfg[TemplateSeasonReward::ItemNum]])) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_CREATE_ERROR, 'season receive gain item error!');
            $this->sendSeasonReceiveMsg(ClientErrorCode::SEASON_REWARD_ERROR, []);
            return ;
        }

        // 保存领取奖励
        $this->data->seasonReward[] = $tplID;
        $this->data->saveLevel();
        $this->sendSeasonReceiveMsg(ClientErrorCode::CLIENT_SUCCESS, $this->data->seasonReward);
    }

    // 领取多个赛季奖励（一键领取）
    public function fastReceive() {
        $this->searchLevelData();
        $cfgArr = $this->getTable(TemplateDefine::TYPE_SEASON_REWARD);
        $itemArr = [];
        foreach ($cfgArr as $item) {
            if($item[TemplateSeasonReward::DemandExp] <= $this->data->seasonScore &&
            !in_array($item[TemplateSeasonReward::Id], $this->data->seasonReward)) {
                $this->data->seasonReward[] = (int)$item[TemplateSeasonReward::Id];
                isset($itemArr[$item[TemplateSeasonReward::ItemId]]) ?
                    $itemArr[$item[TemplateSeasonReward::ItemId]] += $item[TemplateSeasonReward::ItemNum] :
                    $itemArr[$item[TemplateSeasonReward::ItemId]] = $item[TemplateSeasonReward::ItemNum];
            }
        }

        // 一键领取循环奖励
        if($this->data->haveRewardNum != 0) {
            // 领取奖励
            $itemID = (int)$this->getTerm(TemplateDefine::TYPE_CONST,
                TemplateConst::Const_Season_Loop_Item_ID, TemplateConst::ConstNum);
            $itemNum = (int)$this->getTerm(TemplateDefine::TYPE_CONST,
                TemplateConst::Const_Season_Loop_Item_Num, TemplateConst::ConstNum);
            isset($itemArr[$itemID]) ?
                $itemArr[$itemID] += $itemNum * $this->data->haveRewardNum :
                $itemArr[$itemID] = $itemNum * $this->data->haveRewardNum;
            $this->data->rewardNum += $this->data->haveRewardNum;
            $this->data->haveRewardNum = 0;
        }

        // 没有需要领取的奖励
        if(empty($itemArr)) {
            $this->sendSeasonReceiveMsg(ClientErrorCode::SEASON_REWARD_NOT_FOUND_ERROR, []);
            return ;
        }

        // 发送奖励道具
        $this->setLogAddItemSource(GameConstantDefine::ITEM_ADD_SOURCE_SEASON_REWARD);
        if(!$this->gainItemArr($itemArr)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_CREATE_ERROR, 'fast season receive gain item error!');
            $this->sendSeasonReceiveMsg(ClientErrorCode::SEASON_REWARD_ERROR, []);
            return ;
        }

        // 保存领取奖励
        $this->data->saveLevel();
        $this->sendSeasonReceiveMsg(ClientErrorCode::CLIENT_SUCCESS, $this->data->seasonReward);

    }

    public function sendSeasonReceiveMsg(int $code, array $reward) {
        $msg = new GCReceiveSeasonReward();
        $msg->setCode($code);
        $msg->setReward($reward);
        SendMessage::getInstance()->sendClient(PacketId::GC_ReceiveSeasonReward, $msg);
    }

    /**
     * 排位赛金牌选手
     */
    //更新排行
    private function updatePaiWeiGoldPlayerRank()
    {
        $goldId = (int)$this->getTerm(
            TemplateDefine::TYPE_CONST,
            TemplateConst::Const_Ranking_Gold_Player_Level,
            TemplateConst::ConstNum
        );
        //荣耀段位就可进入 获取排行时,最低分取王牌车手最低分
        if ($this->data->levelId >= $goldId -2) {
            $goldData = new PaiWeiGoldData();
            $goldData->setPlayerId($this->playerId);
            $goldData->updateGoldPlayerRankScore($this->data->score);
        }
    }

    public function commonTimerExpire(array $expireData)
    {
        if(empty($expireData)) {
            LogMark::getInstance()->markError(
                GameErrorCode::COMMON_TIMER_EXPIRE_DATA_ERROR,
                '[PaiweiLevelModel] timerExpire array empty!');
            return false;
        }
        LogMark::getInstance()->markInfo("[PaiweiLevelModel] start tidy pai wei gold rank");
        //查询前100名
        $goldData = new PaiWeiGoldData();
        $top100 = $goldData->getTop100GoldPlayer();
        if (empty($top100)) {
            return true;
        }
        $minScore = (int)$this->getTerm(
            TemplateDefine::TYPE_CONST,
            TemplateConst::Const_Ranking_Gold_Player_Min_Score,
            TemplateConst::ConstNum
        );
        //人数不足100
        $data = array();
        if (count($top100) < 1) {
            foreach ($top100 as $pId => $score) {
                if ($score >= $minScore) {
                    $data[$pId] = $score;
                }
            }
        } else {
            //人数超100,根据第100名分数,找同分的人一起获得称号
            $t100Score = array_values($top100)[99];
            $maxScore = max($minScore, $t100Score);
            $result = $goldData->getTopGoldPlayer($maxScore);
            foreach ($result as $pId => $score) {
                if ($score >= $minScore) {
                    $data[$pId] = $score;
                }
            }
        }
        $this->updateGoldPlayer($data);
        //更新下次执行时间
        $time = strtotime(date("Ymd", strtotime("+1 day", Utils::getServerTimestamp()))) +1;
        return $this->addCommonTimer(
            ModelTypeDefine::PAIWEI_LEVEL,
            0,
            $time
        );
    }

    //更新金牌车手信息
    private function updateGoldPlayer(array $data)
    {
        $goldData = new PaiWeiGoldData();
        $goldData->delGoldPlayer();
        $goldData->updateGoldPlayer($data);
    }

}
