<?php
/**
 * 排行榜
 */

namespace Game\Logic;

use Framework\Define\ErrorDefine;
use Framework\Log\LogMark;
use Framework\MVC\ModelManager;
use Game\Constant\ConstTemplate\TemplateConst;
use Game\Constant\GameErrorCode;
use Game\Constant\ModelTypeDefine;
use Game\Constant\TemplateDefine;
use Game\Data\Rank\RankCacheData;
use Game\Data\Rank\RankData;
use Game\Data\Rank\RankLikesData;
use Game\Model\Rank\RankModel;
use Game\Logic\SeasonLogic;

trait RankLogic {
    use SeasonLogic;
    // 获取排行榜信息
    public function findRankData(int $rankType, int $mapID = 0, $page = 0): bool {
        /**
         * @var RankModel $rankModel
         */
        $rankModel = ModelManager::getInstance()->getModel(ModelTypeDefine::RANKING);
        if(!$rankModel->findRankData($rankType, $mapID, $page)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[rank logic] find rank data error!',
                ['rankType' => $rankType, 'mapID' => $mapID]
            );
            return false;
        }
        // send msg
        return true;
    }

    // 修改排行榜信息
    public function changeRankScore(int $rankType, int $score, int $mapID = 0, bool $sort = false): bool {
        /**
         * @var RankModel $rankModel
         */
        $rankModel = ModelManager::getInstance()->getModel(ModelTypeDefine::RANKING);
        if(!$rankModel->changeRankScore($rankType, $score, $mapID, $sort)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[rank logic] change rank data error!',
                ['rankType' => $rankType, 'mapID' => $mapID]
            );
            return false;
        }
        return true;
    }

    // 登录修改排行榜时间
    public function updateLoginRankTime():bool {
        /**
         * @var RankModel $rankModel
         */
        $rankModel = ModelManager::getInstance()->getModel(ModelTypeDefine::RANKING);
        if(!$rankModel->updateLoginSyncTime()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[rank logic] change login rank time error!',
            );
            return false;
        }
        return true;
    }

    // 点赞
    public function rankLike(int $playerID):bool {
        /**
         * @var RankModel $rankModel
         */
        $rankModel = ModelManager::getInstance()->getModel(ModelTypeDefine::RANKING);
        if(!$rankModel->rankLike($playerID)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_CREATE_ERROR,
                '[rank logic] rank like error!',
            );
            return false;
        }
        $rankModel->sendRankLike();
        return true;
    }

    // 查询点赞列表
    public function getRankLike(&$result, int $playerID = 0): bool {
        /**
         * @var RankModel $rankModel
         */
        $rankModel = ModelManager::getInstance()->getModel(ModelTypeDefine::RANKING);
        if(!$rankModel->getRankLike( $result, $playerID)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_CREATE_ERROR,
                '[rank logic] rank like error!',
            );
            return false;
        }
        return true;
    }

    // 个人信息更新 同步至排行榜
    public function syncMineRankInfo(): bool {
        /**
         * @var RankModel $rankModel
         */
        $rankModel = ModelManager::getInstance()->getModel(ModelTypeDefine::RANKING);
        if(!$rankModel->syncMineRankInfo()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[rank logic] sync mine rank info error!',
            );
            return false;
        }
        return true;
    }

    // 登录更新长时间不上线玩家排行榜信息
    public function loginTimeOutUpdateRank(){
        /**
         * @var RankModel $rankModel
         */
        $rankModel = ModelManager::getInstance()->getModel(ModelTypeDefine::RANKING);
        $rankModel->loginTimeOutUpdateRank();
    }

    // gm删除单个排行榜单个玩家信息（删除排行榜玩家数据）
    public function clearRankPlayerInfoByPID(int $playerID, int $rankType, int $mapID) {
        ModelManager::getInstance()->clearModelList();
        ModelManager::getInstance()->setPlayerId($playerID);
        if(in_array($rankType, RankModel::RANK_SEASON_TYPE)) {
            $seasonID = $this->getSeasonId();
        } else {
            $seasonID = 0;
        }
        if(in_array($rankType, RankModel::RANK_SEASON_TYPE)) {
            if($seasonID === 0) {
                LogMark::getInstance()->markError(
                    GameErrorCode::DATA_DELETE_ERROR,
                    '[rank data] gm clear player rank seasonID error!',
                );
            }
        }
        // 删除rank 排行榜
        $rankData = new RankData($rankType, $seasonID, $mapID);
        $rankData->setKey($playerID);
        if(!$rankData->deleteRankPlayer()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_DELETE_ERROR,
                '[rank data] gm clear player rank error!',
                ['rankType' => $rankType, 'seasonID' => $seasonID, 'mapID' => $mapID, 'key' => $playerID]
            );
        }

        // 删除缓存
        $rankCacheData = new RankCacheData($rankType, $seasonID, $mapID);
        $rankCacheData->delRankingCacheData();

        // 删除点赞
        $rankLike = new RankLikesData();
        $rankLike->delRankLikesCacheData();

        // 删除个人排行榜记录
        $this->changeRankEventPooled($rankType, $mapID);
    }

    // gm删除单个排行榜所有玩家信息（清空单个排行榜）
    public function clearRankInfo(int $rankType, int $mapID) {
        $res = [];
        if(in_array($rankType, RankModel::RANK_SEASON_TYPE)) {
            $seasonID = $this->getSeasonId();
        } else {
            $seasonID = 0;
        }
        $rankData = new RankData($rankType, $seasonID, $mapID);
        if(!$rankData->findRankData($res)) {
            logMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[rank model] find rank data error!',
                (array)$rankData
            );
        }
        $players = array_keys($res);
        foreach($players as $pid) {
            $this->clearRankPlayerInfoByPID($pid, $rankType, $mapID);
        }
    }

    private function changeRankEventPooled($type, int $mapID = 0)
    {
        if(in_array($type, RankModel::RANK_SEASON_TYPE)) {
            $seasonID = $this->getSeasonId();
        } else {
            $seasonID = 0;
        }
        $this->delEventConditionkey(
            $this->getRankingKey($type, $seasonID, $mapID)
        );
    }

    //获取地图挑战赛自己排名
    public function getMapChallengeRank(int $mapId): int
    {
        /**
         * @var RankModel $rankModel
         */
        $rankModel = ModelManager::getInstance()->getModel(ModelTypeDefine::RANKING);
        return $rankModel->getMapChallengeRankNum($mapId);
    }
}