<?php

/**
 * 生涯
 */

namespace Game\Logic\PVE;

use Framework\Logic\TemplateHelp;
use Framework\MVC\ModelManager;
use Game\Constant\ClientErrorCode;
use Game\Constant\ConstTemplate\TemplateChapterReward;
use Game\Constant\ConstTemplate\TemplateInitPlayer;
use Game\Constant\ConstTemplate\TemplateTale;
use Game\Constant\EventTypeDefine;
use Game\Constant\GameConstantDefine;
use Game\Constant\ModelTypeDefine;
use Game\Constant\TemplateDefine;
use Game\Data\PVE\CareerChapterData;
use Game\Data\PVE\CareerLevelData;
use Game\Logic\EventLogic;
use Game\Logic\ItemLogic;
use Game\Method\Player\AddPlayerExp;
use Game\Model\PVE\PveModel;
use Game\Protobuf\GameStar;
use Game\Protobuf\TaleTarget;

trait CareerLogic
{
    use TemplateHelp;
    use ItemLogic;
    use EventLogic;
    use AddPlayerExp;

    //获取章节下已开启的全部关卡数据 [CareerLevelData,..]
    public function getAllCareerLevels(int $chapterId): array
    {
        /**
         * @var PveModel $pveModel
         */
        $pveModel = ModelManager::getInstance()->getModel(ModelTypeDefine::PVE);
        $chapterData = $pveModel->getCareerChapterData($chapterId);
        $result = array();
        foreach ($chapterData as $key => $value) {
            if (is_numeric($key)) {
                $result[] = $pveModel->getCareerLevelData($key);
            }
        }
        return $result;
    }

    //关卡检查--进入场景和结算时检查
    public function checkCareerLevel(int $levelId): int
    {
        /**
         * @var PveModel $pveModel
         */
        $pveModel = ModelManager::getInstance()->getModel(ModelTypeDefine::PVE);
        $levelData = $pveModel->getCareerLevelData($levelId);
        /**
         * @var CareerLevelData $levelData
         */
        if ($levelData->levelId == 0) {
            return ClientErrorCode::PVE_LEVEL_UNLOCK;
        }

        return ClientErrorCode::CLIENT_SUCCESS;
    }

    //检查是否通关--生涯关卡要求完成一项条件就可以通关
    public function checkCompleteCareerLevel(int $levelId, TaleTarget $taleTarget, array $levelConfig, array $compTarget)
    {
        //检查关卡有几个条件(几颗星)
        $levelMaxStar = $this->getLevelMaxStar($levelConfig);
        /**
         * @var PveModel $pveModel
         */
        $pveModel = ModelManager::getInstance()->getModel(ModelTypeDefine::PVE);
        $careerLevelData = $pveModel->getCareerLevelData($levelId);
        //检查未完成情况
        if ($levelMaxStar == 1 && $compTarget[0] == 0) {
            //未完成
            $pveModel->sendCareerLeveleMessage([$careerLevelData]);
            return;
        }
        if ($levelMaxStar == 2 && $compTarget[0] + $compTarget[1] == 0) {
            //未完成
            $pveModel->sendCareerLeveleMessage([$careerLevelData]);
            return;
        }
        if (array_sum($compTarget) == 0) {
            //未完成
            $pveModel->sendCareerLeveleMessage([$careerLevelData]);
            return;
        }
        $isUpdate = false;
        //更新最佳时间
        if ($taleTarget->getCostTime() > 0) {
            if ($careerLevelData->bestTime == 0) {
                $careerLevelData->bestTime = $taleTarget->getCostTime();
                $isUpdate = true;
            }
            if ($taleTarget->getCostTime() < $careerLevelData->bestTime) {
                $careerLevelData->bestTime = $taleTarget->getCostTime();
                $isUpdate = true;
            }
        }
        if ($careerLevelData->starNum >= $levelMaxStar) {
            //已通关的关卡
            if ($isUpdate) {
                $careerLevelData->saveDB();
            }
            $pveModel->sendCareerLeveleMessage([$careerLevelData]);
            return;
        }
        //首次完成关卡,加经验
        if ($careerLevelData->starNum == 0) {
            $this->addPlayerExp($levelConfig[TemplateTale::EXP]);
        }
        $chapterId = $levelConfig[TemplateTale::Chapters];
        //检查完成条件 领取奖励 完成的立即领取奖励
        $this->getCareerLevelReward($careerLevelData, $levelConfig, $compTarget);
        //更新星数
        if ($levelMaxStar == 1) {
            $compStar = $compTarget[0];
        } elseif ($levelMaxStar == 2) {
            $compStar = $compTarget[0] + $compTarget[1];
        } else {
            $compStar = array_sum($compTarget);
        }
        if ($compStar > $careerLevelData->starNum) {
            $addStar = $compStar - $careerLevelData->starNum;
            $careerLevelData->starNum = $compStar;
            //更新关卡章节星数--支线关卡不记录章节总星数
            if ($levelConfig[TemplateTale::Type] == TemplateTale::TYPE_MAIN) {
                $pveModel->updateCareerChapterData(
                    $chapterId,
                    array(
                        $levelId => $careerLevelData->starNum
                    )
                );
                //触发任务
                $param = array(
                    GameConstantDefine::EVENT_KEY_NUM => $addStar,  //增加的星数
                    GameConstantDefine::EVENT_KEY_PVE_LEVEL_ID => $levelId,
                );
                $this->triggerEvent(EventTypeDefine::EVENT_TYPE_TASK_CAREER_LEVEL_STAR, $param);
            }
        }
        $careerLevelData->saveDB();
        $sendLevelMessage = array(
            $careerLevelData
        );
        $allStarNum = $pveModel->getAllStarNum($chapterId);
        //检查解锁新关卡
        $initPlayerConfig = $this->getTitle(TemplateDefine::TYPE_INIT_PLAYER, TemplateInitPlayer::DEFAULT_ID);
        if (isset($initPlayerConfig[TemplateInitPlayer::CareerLevel][$chapterId][$levelId])) {
            //有下一关
            foreach ($initPlayerConfig[TemplateInitPlayer::CareerLevel][$chapterId][$levelId] as $nextLevelId) {
                //检查是否已解锁
                $levelData = $pveModel->getCareerLevelData($nextLevelId);
                if ($levelData->levelId != 0) {
                    continue;
                }
                $nextLevelConfig = $this->getTitle(TemplateDefine::TYPE_TALE, $nextLevelId);
                //主线关卡
                if ($nextLevelConfig[TemplateTale::Type] == TemplateTale::TYPE_MAIN) {
                    //判断是否是最后一关,解锁新章节
                    if ($nextLevelConfig[TemplateTale::Chapters] != $chapterId) {
                        //通关最后一关
                        $data = array(
                            CareerChapterData::UnlockNextChapterFlag => CareerChapterData::FLAG_STATUS_CAN_LOCK
                        );
                        //判断是否满足星级解锁
                        if ($allStarNum < $nextLevelConfig[TemplateTale::Unlock2]) {
                            //未解锁下一章 更新章节状态
                            $data[CareerChapterData::NextLevelId] = $nextLevelId;
                        } else {
                            //解锁新章节
                            $data = array(
                                CareerChapterData::UnlockNextChapterFlag => CareerChapterData::FLAG_STATUS_OVER,
                                CareerChapterData::NextLevelId => $nextLevelId
                            );
                            $pveModel->createCareerChapter($nextLevelConfig[TemplateTale::Chapters]);
                            $sendLevelMessage[] = $pveModel->createCareerLevel($nextLevelId);
                            $pveModel->updateCareerChapterLevelStar($nextLevelConfig[TemplateTale::Chapters], $nextLevelId, 0);
                        }
                        $pveModel->updateCareerChapterData($chapterId, $data);
                    } else {
                        //解锁下一关
                        $sendLevelMessage[] = $pveModel->createCareerLevel($nextLevelId);
                        $pveModel->updateCareerChapterLevelStar($chapterId, $nextLevelId, 0);
                    }
                } else {
                    //支线关卡
                    $sendLevelMessage[] = $pveModel->createCareerLevel($nextLevelId);
                    $pveModel->updateCareerChapterLevelStar($chapterId, $nextLevelId, 0);
                }
            }
        }
        //检查能否解锁新章节--已通关最后一关,但是之前星数不足未能解锁
        if (isset($initPlayerConfig[TemplateInitPlayer::CareerLevel][$chapterId + 1])) {
            $careerChapterData = $pveModel->getCareerChapterData($chapterId);
            if (isset($careerChapterData[CareerChapterData::UnlockNextChapterFlag]) &&
                $careerChapterData[CareerChapterData::UnlockNextChapterFlag] == CareerChapterData::FLAG_STATUS_CAN_LOCK &&
                $nextLevelId != 0
            ) {
                //检查是否已经解锁
                $nextChapterData = $pveModel->getCareerChapterData($chapterId + 1);
                if (empty($nextChapterData)) {
                    //检查星数
                    $newLevelData = $this->getTitle(TemplateDefine::TYPE_TALE, $nextLevelId);
                    if (!is_null($newLevelData) && $allStarNum >= $newLevelData[TemplateTale::Unlock2]) {
                        //解锁新章节
                        $pveModel->createCareerChapter($chapterId + 1);
                        $sendLevelMessage[] = $pveModel->createCareerLevel($nextLevelId);
                        $pveModel->updateCareerChapterLevelStar($chapterId + 1, $nextLevelId, 0);
                    }
                } else {
                    //已解锁,但未更新上一章解锁状态
                    $data = array(
                        CareerChapterData::UnlockNextChapterFlag => CareerChapterData::FLAG_STATUS_OVER,
                    );
                    $pveModel->updateCareerChapterData($chapterId, $data);
                }
            }
        }
        $pveModel->sendCareerLeveleMessage($sendLevelMessage);
    }

    //领取达成目标奖励
    private function getCareerLevelReward(CareerLevelData $careerLevelData, array $levelConfig, array $compTarget)
    {
        $item = [];
        if ($compTarget[0]) {
            if ($careerLevelData->target1Status != CareerLevelData::STATUS_TARGET_REWARD) {
                //完成条件 领取奖励
                $item[] = $levelConfig[TemplateTale::Reward][0];
                $careerLevelData->target1Status = CareerLevelData::STATUS_TARGET_REWARD;
            }
        } elseif ($careerLevelData->target1Status != CareerLevelData::STATUS_TARGET_REWARD) {
            $careerLevelData->target1Status = CareerLevelData::STATUS_TARGET_UNFINISHED;
        }
        if ($compTarget[1]) {
            if ($careerLevelData->target2Status != CareerLevelData::STATUS_TARGET_REWARD) {
                //奖励数量可能不是3个
                if (isset($levelConfig[TemplateTale::Reward][1])) {
                    $item[] = $levelConfig[TemplateTale::Reward][1];
                }
                $careerLevelData->target2Status = CareerLevelData::STATUS_TARGET_REWARD;
            }
        } elseif ($careerLevelData->target2Status != CareerLevelData::STATUS_TARGET_REWARD) {
            $careerLevelData->target2Status = CareerLevelData::STATUS_TARGET_UNFINISHED;
        }
        if ($compTarget[2]) {
            if ($careerLevelData->target3Status != CareerLevelData::STATUS_TARGET_REWARD) {
                //奖励数量可能不是3个
                if (isset($levelConfig[TemplateTale::Reward][2])) {
                    $item[] = $levelConfig[TemplateTale::Reward][2];
                }
                $careerLevelData->target3Status = CareerLevelData::STATUS_TARGET_REWARD;
            }
        } elseif ($careerLevelData->target3Status != CareerLevelData::STATUS_TARGET_REWARD) {
            $careerLevelData->target3Status = CareerLevelData::STATUS_TARGET_UNFINISHED;
        }
        //发奖励
        $this->setLogAddItemSource(GameConstantDefine::ITEM_ADD_SOURCE_CAREER_LEVEL);
        foreach ($item as $reward) {
            $this->gainItemArr($reward);
        }
    }

    //领取关卡星星奖励
    public function getCareerStarReward(int $chapterId, int $rewardId): int
    {
        $config = $this->getTitle(TemplateDefine::TYPE_CHAPTER_REWARD, $rewardId);
        if (is_null($config)) {
            return ClientErrorCode::ERROR_STAR_REWARD_LEVEL_ERROR;
        }
        //检查章节是否一致
        if ($chapterId != $config[TemplateChapterReward::Chapter]) {
            return ClientErrorCode::ERROR_GAME_LEVEL_STAR_REWARD_ID_NOT_FOUND;
        }
        /**
         * @var PveModel $pveModel
         */
        $pveModel = ModelManager::getInstance()->getModel(ModelTypeDefine::PVE);
        $maxChapterId = $pveModel->getChapterId();
        if ($chapterId > $maxChapterId) {
            return ClientErrorCode::ERROR_STAR_REWARD_LEVEL_ERROR;
        }
        //检查需要星数
        $starNum = $pveModel->getAllStarNum($chapterId);
        if ($starNum < $config[TemplateChapterReward::Number]) {
            return ClientErrorCode::ERROR_GET_STAR_REWARD;
        }
        $chapterData = $pveModel->getCareerChapterData($chapterId);
        $starReward = json_decode($chapterData[CareerChapterData::StarReward], true);
        //检查是否已领取奖励
        if (in_array($rewardId, $starReward)) {
            return ClientErrorCode::ERROR_STAR_REWARD_RECEIVED;
        }
        //发奖励
        $this->setLogAddItemSource(GameConstantDefine::ITEM_ADD_SOURCE_CAREER_STAR_REWARD);
        $this->gainItemArr($config[TemplateChapterReward::Reward]);
        $starReward[] = $rewardId;
        $pveModel->updateCareerChapterData(
            $chapterId,
            array(
                CareerChapterData::StarReward => json_encode($starReward)
            )
        );
        return ClientErrorCode::CLIENT_SUCCESS;
    }

    //获取已领取的星星奖励
    public function getStarRewardMessage(int $chapterId): array
    {
        /**
         * @var PveModel $pveModel
         */
        $pveModel = ModelManager::getInstance()->getModel(ModelTypeDefine::PVE);
        $chapterData = $pveModel->getCareerChapterData($chapterId);
        $starReward = json_decode($chapterData[CareerChapterData::StarReward], true);
        $starMessage = array();
        foreach ($starReward as $id) {
            $gameStar = new GameStar();
            $gameStar->setId($id);
            $gameStar->setStatus(CareerChapterData::STAR_REWARD_GET);
            $starMessage[] = $gameStar;
        }
        return $starMessage;
    }

    //获取关卡有几个条件(几颗星)
    private function getLevelMaxStar(array $levelConfig): int
    {
        $levelMaxStar = 0;
        if ($levelConfig[TemplateTale::VitalTargetType] != 0) {
            $levelMaxStar++;
        }
        if ($levelConfig[TemplateTale::TargetType1] != 0) {
            $levelMaxStar++;
        }
        if ($levelConfig[TemplateTale::TargetType2] != 0) {
            $levelMaxStar++;
        }
        return $levelMaxStar;
    }
}
