<?php

/***
 *
 */

namespace Game\Logic;

use Framework\Log\LogMark;
use Framework\Logic\TemplateHelp;
use Framework\MVC\ModelManager;
use Game\Constant\ConstTemplate\TemplateConst;
use Game\Constant\ConstTemplate\TemplateLevel;
use Game\Constant\ConstTemplate\TemplateRankActive;
use Game\Constant\ConstTemplate\TemplateRankStraightWin;
use Game\Constant\ConstTemplate\TemplateRankWinRatio;
use Game\Constant\ModelTypeDefine;
use Game\Constant\TemplateDefine;
use Game\Data\PaiWei\PaiweiLevelData;
use Game\Data\RoomData;
use Game\Model\PaiweiLevelModel;

trait PaiweiLevelLogic
{
    use TemplateHelp;

    /***
     * 比赛结束后,更新积分
     * @param int $addScore     正数为增加积分,负数为扣除积分
     * @param int $addGuardScore
     * @param bool $isWin           胜负标志
     */
    public function updateRankingData(int $addScore, int $addGuardScore, bool $isWin = true)
    {
        /**
         * @var PaiweiLevelModel $levelModel
         */
        $levelModel = ModelManager::getInstance()->getModel(ModelTypeDefine::PAIWEI_LEVEL);
        $levelModel->changeScore($addScore, $addGuardScore, $isWin);
        $levelModel->sendMessage();
    }

    /***
     * @return PaiweiLevelData
     */
    public function getPaiweiLevel(): PaiweiLevelData
    {
        /**
         * @var PaiweiLevelModel $levelModel
         */
        $levelModel = ModelManager::getInstance()->getModel(ModelTypeDefine::PAIWEI_LEVEL);
        return $levelModel->searchLevelData();
    }

    //查询他人数据
    public function getTargetPaiWeiLevel(int $targetPlayerId): PaiweiLevelData
    {
        /**
         * @var PaiweiLevelModel $levelModel
         */
        $levelModel = ModelManager::getInstance()->getModel(ModelTypeDefine::PAIWEI_LEVEL);
        return $levelModel->searchTargetLevelData($targetPlayerId);
    }

    //修改他人数据
    public function updateTargetPlayerLevelData(int $targetPlayerId, array $data)
    {
        /**
         * @var PaiweiLevelModel $levelModel
         */
        $levelModel = ModelManager::getInstance()->getModel(ModelTypeDefine::PAIWEI_LEVEL);
        $levelModel->updateTargetLevelData($targetPlayerId, $data);
    }

    public function gmChangeScore(int $addScore, int $addGuardScore)
    {
        /**
         * @var PaiweiLevelModel $levelModel
         */
        $levelModel = ModelManager::getInstance()->getModel(ModelTypeDefine::PAIWEI_LEVEL);
        $levelModel->gmChangeScore($addScore, $addGuardScore);
    }

    public function gmChangeSeasonScore(int $addScore, int $playerID = 0)
    {
        /**
         * @var PaiweiLevelModel $levelModel
         */
        $levelModel = ModelManager::getInstance()->getModel(ModelTypeDefine::PAIWEI_LEVEL);
        $levelModel->addSeasonScore($addScore, $playerID);
    }

    //检查房间内玩家是否符合段位需求
    public function checkRoomPlayerLevel(array $roomPlayer): bool
    {
        if (count($roomPlayer) == 1) {
            return true;
        }
        //段位间隔
        $gapLevel = $this->getTerm(TemplateDefine::TYPE_CONST,
                                           TemplateConst::Const_Ranking_Room_Level_Gap,
                                           TemplateConst::ConstNum);
        $ownerLv = 1;   //房主段位
        $ownerPlayerId = 0;
        $joinTime = 0;
        $levelDic = array();    //playerId=>level
        foreach($roomPlayer as $pid => $data) {
            $paiWeiData = $this->getTargetPaiWeiLevel($pid);
            $levelDic[$pid] = $paiWeiData->levelId;
            //查找房主
            if ($joinTime == 0) {
                $joinTime = $data[RoomData::JOIN_TIME];
                $ownerLv = $paiWeiData->levelId;
                $ownerPlayerId = $pid;
            }
            if ($joinTime < $data[RoomData::JOIN_TIME]) {
                $joinTime = $data[RoomData::JOIN_TIME];
                $ownerLv = $paiWeiData->levelId;
                $ownerPlayerId = $pid;
            }
        }
        $levelRange = [$ownerLv - $gapLevel, $ownerLv + $gapLevel];
        foreach ($levelDic as $pid => $level) {
            if ($pid == $ownerPlayerId) {
                continue;
            }
            if ($level < $levelRange[0] || $level > $levelRange[1]) {
                return false;
            }
        }
        return true;
    }

    //检查首选位场次,匹配结果的位置与首选是否一致
    public function updateTeamFirstChoice(int $position)
    {
        /**
         * @var PaiweiLevelModel $levelModel
         */
        $levelModel = ModelManager::getInstance()->getModel(ModelTypeDefine::PAIWEI_LEVEL);
        $levelData = $levelModel->searchLevelData();
        $positionList = json_decode($levelData->positionOrder, true);
        if ($position == $positionList[0]) {
            //命中首选,场次+1
            $levelData->firstChoiceNum++;
        } else {
            //未命中首选,场次归1
            $levelData->firstChoiceNum = 1;
        }
        $levelData->saveLevel();
    }

    //获取匹配分--匹配使用
    //公式 匹配分=段位分*权重+胜率分*权重+连胜分*权重+活跃分*权重
    public function getRankingScore(int $playerId): int
    {
        /**
         * @var PaiweiLevelModel $levelModel
         */
        $levelModel = ModelManager::getInstance()->getModel(ModelTypeDefine::PAIWEI_LEVEL);
        $paiWeiData = $levelModel->searchTargetLevelData($playerId);
        $score = 0;
        $config = $this->getTitle(TemplateDefine::TYPE_PAIWEI_LEVEL, $paiWeiData->levelId);
        //匹配分
        if (!is_null($config)) {
            $score += $config[TemplateLevel::Num] * $config[TemplateLevel::Weight];
        }
        //胜率分--最近30场比赛胜率,不足10场不算
        $tmpScore = 0;
        $tmpWeight = 0;
        $minRecord = $this->getTerm(
            TemplateDefine::TYPE_CONST,
            TemplateConst::Const_Ranking_Season_Record_Min,
            TemplateConst::ConstNum
        );
        $seasonRecord = json_decode($paiWeiData->seasonMatchRecord, true);
        if (count($seasonRecord) > $minRecord) {
            $ratio = (int)(array_sum($seasonRecord) / count($seasonRecord) * 10000);
            //查询对应胜率分
            $ratioConfig = $this->getTable(TemplateDefine::TYPE_RANK_WIN_RATIO);
            foreach ($ratioConfig as $id => $data) {
                if ($ratio >= $data[TemplateRankWinRatio::Ratio]) {
                    $tmpScore = $data[TemplateRankWinRatio::Num];
                    $tmpWeight = $data[TemplateRankWinRatio::Weight];
                }
            }
            $score += $tmpScore * $tmpWeight;
        }
        //连胜分
        $tmpScore = 0;
        $tmpWeight = 0;
        if ($paiWeiData->record == 0) {
            $straightWinConfig = $this->getTitle(
                TemplateDefine::TYPE_RANK_STRAIGHT_WIN,
                TemplateRankStraightWin::ID_ZERO
            );
            if (!is_null($straightWinConfig)) {
                $tmpScore = $straightWinConfig[TemplateRankStraightWin::Num];
                $tmpWeight = $straightWinConfig[TemplateRankStraightWin::Weight];
            }
        } elseif ($paiWeiData->record > 0) {
            //连胜
            $straightWinConfig = $this->getTitle(
                TemplateDefine::TYPE_RANK_STRAIGHT_WIN,
                TemplateRankStraightWin::ID_POSITIVE
            );
            if (!is_null($straightWinConfig)) {
                foreach ($straightWinConfig as $id => $data) {
                    if ($paiWeiData->record >= $data[TemplateRankStraightWin::WinNum]) {
                        $tmpScore = $data[TemplateRankStraightWin::Num];
                        $tmpWeight = $data[TemplateRankStraightWin::Weight];
                    }
                }
            }
        } else {
            //连败
            $straightWinConfig = $this->getTitle(
                TemplateDefine::TYPE_RANK_STRAIGHT_WIN,
                TemplateRankStraightWin::ID_NEGATIVE
            );
            if (!is_null($straightWinConfig)) {
                foreach ($straightWinConfig as $id => $data) {
                    if ($paiWeiData->record <= $data[TemplateRankStraightWin::WinNum]) {
                        $tmpScore = $data[TemplateRankStraightWin::Num];
                        $tmpWeight = $data[TemplateRankStraightWin::Weight];
                    }
                }
            }
        }
        $score += $tmpScore * $tmpWeight;
        //活跃分
        $tmpScore = 0;
        $tmpWeight = 0;
        $effectNum = 0;
        $activeConfig = $this->getTable(TemplateDefine::TYPE_RANK_ACTIVE);
        foreach ($activeConfig as $id => $data) {
            if ($paiWeiData->gapDay >= $data[TemplateRankActive::Day]) {
                $effectNum = $data[TemplateRankActive::EffectNum];
                $tmpScore = $data[TemplateRankActive::Num];
                $tmpWeight = $data[TemplateRankActive::Weight];
            }
        }
        //检查生效场次
        if ($paiWeiData->dailyMatchNum <= $effectNum) {
            $score += $tmpScore * $tmpWeight;
        }
        if ($score <= 0) {
            LogMark::getInstance()->markDebug(
                "[PaiweiLogic] getRankingScore less zero",
                array(
                    "score" => $score,
                    "id" => $paiWeiData->levelId,
                    "seasonRecordSum" => array_sum($seasonRecord),
                    "seasonRecordNum" => count($seasonRecord),
                    "record" => $paiWeiData->record,
                    "gapDay" => $paiWeiData->gapDay,
                )
            );
        }
        return $score;
    }

}
