<?php

/**
 * pve比赛结算
 */

namespace Game\Logic\PVE;

use Framework\Log\LogMark;
use Framework\Logic\TemplateHelp;
use Framework\MVC\ModelManager;
use Game\Constant\ClientErrorCode;
use Game\Constant\ConstTemplate\TemplateTale;
use Game\Constant\EventTypeDefine;
use Game\Constant\GameConstantDefine;
use Game\Constant\ModelTypeDefine;
use Game\Constant\TemplateDefine;
use Game\Data\EventConditionData;
use Game\Data\PVE\LevelData;
use Game\Data\RaceResultData;
use Game\Logic\CarLogic;
use Game\Logic\EventConditionLogic;
use Game\Logic\EventLogic;
use Game\Model\PVE\PveModel;
use Game\Operation\EventLog\CompletePVELog;
use Game\Operation\EventLog\EventLog_Manager;
use Game\Operation\EventLog\EventLogType;
use Game\Protobuf\MatchOperation;
use Game\Protobuf\PlayerMark;
use Game\Protobuf\RaceResult;
use Game\Protobuf\RecordBreakingInfo;
use Game\Protobuf\SettlementParameter;
use Game\Protobuf\TaleTarget;

trait PveSettlementLogic
{
    use TemplateHelp;
    use DrivingLicenseLogic;
    use PveTargetLogic;
    use EventLogic;
    use EventConditionLogic;
    use DrivingPermitLogic;
    use TeachingSkillLogic;
    use CareerLogic;
    use CarLogic;

    //通用检查--进入关卡和结算检查
    public function checkPveLevel(int $levelId, int $carTplId): int
    {
        //检查关卡是否存在
        if ($levelId <= 0) {
            return ClientErrorCode::PVE_LEVEL_NOT_FOUND;
        }
        $levelConfig = $this->getLevelConfig($levelId);
        if (empty($levelConfig)) {
            return ClientErrorCode::PVE_LEVEL_NOT_FOUND;
        }
        //检查车辆是否符合
        if ($levelConfig[TemplateTale::Car] != 0 && $levelConfig[TemplateTale::Car] != $carTplId) {
            return ClientErrorCode::PVE_LEVEL_CAR_ERROR;
        }
        switch ($levelConfig[TemplateTale::Type])
        {
            case TemplateTale::TYPE_MAIN:
            case TemplateTale::TYPE_BRANCH:
                //剧情关卡检查
                return $this->checkCareerLevel($levelId);
            case TemplateTale::TYPE_DRIVING_LICENSE_EXAM:
                //驾照关卡检查
                return $this->checkDrivingLicenseLevel($levelId);
            case TemplateTale::TYPE_DRIVING_PERMIT:
                //行驶证关卡检查
                return $this->checkDrivingPermitLevel($levelId);
            case TemplateTale::TYPE_TEACHING_SKILL:
                //技巧教学关卡
                return $this->checkTeachingSkillLevel($levelId);
            default:
                LogMark::getInstance()->markDebug(
                    "[PveSettlementLogic] level type error",
                    array(
                        "levelId" => $levelId
                    )
                );
                return ClientErrorCode::PVE_LEVEL_NOT_FOUND;
        }
    }

    //获取关卡配置
    public function getLevelConfig(int $levelId): array
    {
        $levelConfig = $this->getTitle(TemplateDefine::TYPE_TALE, $levelId);
        if (is_null($levelConfig)) {
            LogMark::getInstance()->markDebug(
                "[PveSettlementLogic] not found level config",
                array(
                    "levelId" => $levelId,
                )
            );
            return array();
        }
        return $levelConfig;
    }

    //关卡通关检查
    public function checkCompleteLevel(LevelData $levelData, TaleTarget $taleTarget, MatchOperation $matchOperation, PlayerMark $playerMark)
    {
        $levelConfig = $this->getLevelConfig($levelData->levelId);
        $compTarget = $this->getTargetCompleteInfo($levelConfig, $taleTarget, $matchOperation);
        LogMark::getInstance()->markDebug(
            "[PveSettlementLogic] checkCompleteLevel:{$levelData->levelId}",
            $compTarget
        );
        $matchType = 0;
        $taskNeedIsWin = false;     //任务使用 比赛胜利标志
        $bestTimeFlag = 0;
        switch ($levelConfig[TemplateTale::Type])
        {
            case TemplateTale::TYPE_MAIN:
            case TemplateTale::TYPE_BRANCH:
                /**
                 * @var PveModel $pveModel
                 */
                $pveModel = ModelManager::getInstance()->getModel(ModelTypeDefine::PVE);
                $careerLevelData = $pveModel->getCareerLevelData($levelData->levelId);
                $bestTime = $careerLevelData->bestTime;
                //剧情关卡检查
                $this->checkCompleteCareerLevel($levelData->levelId, $taleTarget, $levelConfig, $compTarget);
                if ($compTarget[0] == 1) {
                    $taskNeedIsWin = true;
                }
                $careerLevelData = $pveModel->getCareerLevelData($levelData->levelId);
                if ($careerLevelData->bestTime != 0 && $careerLevelData->bestTime != $bestTime) {
                    $bestTimeFlag = 1;
                }
                break;
            case TemplateTale::TYPE_DRIVING_LICENSE_EXAM:
                //驾照关卡检查
                $this->checkCompleteDrivingLicenseLevel($levelData, $levelConfig, $compTarget);
                if (array_sum($compTarget) == 3) {
                    $taskNeedIsWin = true;
                }
                break;
            case TemplateTale::TYPE_DRIVING_PERMIT:
                //行驶证关卡
                $this->checkCompleteDrivingPermitLevel($levelData, $levelConfig, $compTarget);
                if (array_sum($compTarget) == 3) {
                    $taskNeedIsWin = true;
                }
                break;
            case TemplateTale::TYPE_TEACHING_SKILL:
                //技巧教学关卡
                $this->checkCompleteTeachingSkillLevel($levelData, $levelConfig, $compTarget);
                if (array_sum($compTarget) == 3) {
                    $taskNeedIsWin = true;
                }
                break;
            default:
                LogMark::getInstance()->markDebug(
                    "[PveSettlementLogic] level type error",
                    array(
                        "levelId" => $levelData->levelId
                    )
                );
                break;
        }
        //是否胜利,任务需要,个人赛胜利为前3名,团队赛胜利为队伍胜利
        $isWin = false;
        //优先检查是否完成pve条件,再检查名次
        if ($taskNeedIsWin && $taleTarget->getRank() <= 3) {
            $isWin = true;
        }
        //完成比赛相关任务
        $param = array(
            GameConstantDefine::EVENT_KEY_MATCH_TIME => $taleTarget->getCostTime(),
            GameConstantDefine::EVENT_KEY_MATCH_MAP => 0,
            GameConstantDefine::EVENT_KEY_MATCH_TYPE => $matchType,
            GameConstantDefine::EVENT_KEY_CAR_ID => $playerMark->getCarId(),
            GameConstantDefine::EVENT_KEY_MATCH_WIN => $isWin,
            GameConstantDefine::EVENT_KEY_MVP => false,
        );
        $this->triggerEvent(EventTypeDefine::EVENT_TYPE_TASK_COMPLETE_MATCH, $param);
        //排名任务
        $param = array(
            GameConstantDefine::EVENT_KEY_MATCH_RANK => $taleTarget->getRank(),
            GameConstantDefine::EVENT_KEY_MATCH_TYPE => $matchType,
        );
        $this->triggerEvent(EventTypeDefine::EVENT_TYPE_TASK_MATCH_RANK, $param);
        //通关任务
        if ($taskNeedIsWin) {
            $param = array(
                GameConstantDefine::EVENT_KEY_PVE_LEVEL_ID => $levelData->levelId,
            );
            $this->triggerEvent(EventTypeDefine::EVENT_TYPE_TASK_COMPLETE_PVE_LEVEL, $param);
        }
        //打点
        $this->addCompletaPVEMatchLog($levelConfig, $compTarget, $bestTimeFlag, $playerMark, $matchOperation);
    }

    //记录打点日志
    private function addCompletaPVEMatchLog(array $levelConfig, array $compTarget, int $bestTimeFlag, PlayerMark $playerMark, MatchOperation $matchOperation)
    {
        $log = EventLog_Manager::getInstance()->getEventLog(EventLogType::CompletePVE);
        if (is_null($log)) {
            return;
        }
        if (array_sum($compTarget) == 3) {
            $pveUnCompleteTask = 0;
        } else {
            $tmp = "";
            foreach ($compTarget as $idx => $value) {
                if ($value == 0) {
                    $tmp .= (string)($idx + 1);
                }
            }
            $pveUnCompleteTask = (int)$tmp;
        }
        /**
         * @var CompletePVELog $log
         */
        $log->matchType = $levelConfig[TemplateTale::Type];
        $log->levelId = $levelConfig[TemplateTale::Id];
        $log->pveUnCompleteTask = $pveUnCompleteTask;
        $log->newRecord = $bestTimeFlag;
        $log->playerCarId = $playerMark->getCarId();
        $car = $this->searchCarDataByCarID($playerMark->getCarId());
        if (is_null($car)) {
            $log->playerCarPerformance = 0;
            $log->playerCarLv = 0;
            $log->playerCarProficiencyLv = 0;
        } else {
            $log->playerCarPerformance = $car->performance;
            $log->playerCarLv = $car->level;
            $log->playerCarProficiencyLv = $car->proficiencyLv;
        }
        $log->playerId = $playerMark->getPlayerId();
        $log->playerMark = $playerMark;
        $log->matchOperation = $matchOperation;
        $log->markLog();
    }
}
