<?php

/**
 * 战令任务
 */

namespace Game\Model\Task\Manager;

use Framework\DB\Handler\PlayerDBPipe;
use Framework\Log\LogMark;
use Framework\DB\Handler\PlayerDBHandler;
use Framework\MVC\ModelManager;
use Game\Constant\ConstTemplate\TemplateInitPlayer;
use Game\Constant\DBTableDefine;
use Game\Constant\GameConstantDefine;
use Game\Constant\GameErrorCode;
use Game\Constant\ModelTypeDefine;
use Game\Constant\TemplateDefine;
use Game\Data\TaskData;
use Game\Logic\CommonConstLogic;
use Game\Model\Task\WarTokenModel;

//0周为赛季任务 大于0为对应周任务
class SeasonTaskManager extends TaskMangerModelBase
{
    use PlayerDBHandler;
    use CommonConstLogic;

    private ?int $openWeek = null;          //已开启的周
    private ?array $seasonTaskListConfig = null;    //任务id配置 0战令赛季,x对应周=>[taskId,..]
    private array $doneTaskList = array();  //完成未领取的任务id

    //初始任务 注册完成后
    public function initSeasonTaskOnRegisterOver(int $openWeek)
    {
        $this->setIsRegister();
        $this->initSeasonTask();
        if ($openWeek > 0) {
            for ($i = 1; $i <= $openWeek; $i++) {
                $this->initSeasonWeekTask($i);
            }
        }
    }

    //初始赛季任务
    private function initSeasonTask()
    {
        $taskList = $this->getSeasonTaskConfigByWeek(0);
        foreach ($taskList as $taskId) {
            $this->createSeasonTask($taskId, 0);
        }
        //批量创建的,创建任务索引
        if ($this->isRegister) {
            $taskIndexList = array();
            $tempTaskList = $this->getPipeTempTaskList();
            foreach ($taskList as $taskId) {
                if (isset($tempTaskList[$taskId])) {
                    $taskIndexList[$taskId] = $tempTaskList[$taskId]->status;
                }
            }
            $this->initSeasonIndex(0, $taskIndexList);
            $this->clearPipeTempTaskList();
        }
    }

    private function initSeasonIndex(int $week, array $data): bool
    {
        return PlayerDBPipe::getInstance()->createTitle(
            $this->getDBTable(),
            $this->playerId,
            $week,
            $data,
        );
    }

    //初始战令周任务
    private function initSeasonWeekTask(int $week)
    {
        $taskList = $this->getSeasonTaskConfigByWeek($week);
        foreach ($taskList as $taskId) {
            $this->createSeasonTask($taskId, $week);
        }
        //批量创建的,创建任务索引
        if ($this->isRegister) {
            $taskIndexList = array();
            $tempTaskList = $this->getPipeTempTaskList();
            foreach ($taskList as $taskId) {
                if (isset($tempTaskList[$taskId])) {
                    $taskIndexList[$taskId] = $tempTaskList[$taskId]->status;
                }
            }
            $this->initSeasonIndex($week, $taskIndexList);
            $this->clearPipeTempTaskList();
        }
    }

    //赛季周更新 开启新的周任务
    public function syncCommonData(int $myIndex, int $commonIndex)
    {
        if ($myIndex == $commonIndex) {
            return;
        }
        for ($week = $myIndex + 1; $week <= $commonIndex; $week++) {
            $this->initSeasonWeekTask($myIndex);
        }
        //重置战令日常任务周经验
        /**
         * @var WarTokenModel $warTokenModel
         */
        $warTokenModel = ModelManager::getInstance()->getModel(ModelTypeDefine::WAR_TOKEN);
        $warTokenModel->resetWeekExp();
    }

    //创建任务
    private function createSeasonTask(int $taskId, int $week)
    {
        $param = array(
            "Week" => $week,
            "IsSync" => true
        );
        if (false == $this->createTask($taskId, $param)) {
            LogMark::getInstance()->markError(
                GameErrorCode::TASK_SEASON_CREATE_ERROR,
                "[SeasonTaskManager] season task create error",
                array(
                    "taskId" => $taskId
                )
            );
        }
    }

    //查询任务 未开启的周 返回空
    public function getSeasonTaskByWeek(int $week): array
    {
        $this->getNowSeasonWeek();
        if ($week > $this->openWeek) {
            return array([], []);
        }
        $weekTaskList = $this->searchSeasonTaskFromDBByWeek($week);
        //检查是否需要初始
        if (empty($weekTaskList)) {
            if ($week == 0) {
                //初始赛季任务
                $this->initSeasonTask();
            } else {
                //初始战令周任务
                $this->initSeasonWeekTask($week);
            }
            $weekTaskList = $this->searchSeasonTaskFromDBByWeek($week);
        }

        $taskList = array();
        $completeTaskList = array();
        foreach ($weekTaskList as $taskId => $status) {
            if ($status == TaskData::STATUS_OVER) {
                $completeTaskList[] = $taskId;
            } else {
                $taskData = $this->getTask($taskId);
                if (!is_null($taskData) && $taskData->taskId != 0) {
                    $taskList[] = $taskData;
                }
            }
        }
        return array($taskList, $completeTaskList);
    }

    private function searchSeasonTaskFromDBByWeek(int $week): array
    {
        $result = array();
        $this->searchTitle(
            $this->getDBTable(),
            $this->playerId,
            $week,
            $result,
        );
        return $result;
    }

    private function getDBTable(): int
    {
        return DBTableDefine::TABLE_TASK_SEASON;
    }

    //获取配置赛季任务id
    private function getSeasonTaskConfigByWeek(int $week): array
    {
        if (is_null($this->seasonTaskListConfig)) {
            $configInitData = $this->getTitle(TemplateDefine::TYPE_INIT_PLAYER, TemplateInitPlayer::DEFAULT_ID);
            $seasonListConfig = $configInitData[TemplateInitPlayer::SeasonTaskList];
            if (empty($seasonListConfig)) {
                LogMark::getInstance()->markError(
                    GameErrorCode::TASK_SEASON_NOT_FOUND,
                    "[SeasonTaskManager] not found season task",
                );
            }
            $this->seasonTaskListConfig = $seasonListConfig;
        }
        if (!isset($this->seasonTaskListConfig[$week])) {
            LogMark::getInstance()->markError(
                GameErrorCode::TASK_SEASON_NOT_FOUND,
                "[SeasonTaskManager] not found season task",
                array(
                    "week" => $week
                )
            );
            return array();
        }
        return $this->seasonTaskListConfig[$week];
    }

    //获取当前是赛季第几周
    private function getNowSeasonWeek()
    {
        if (is_null($this->openWeek)) {
            $result = $this->getCommonConstData();
            if (!array_key_exists(GameConstantDefine::COMMON_KEY_SEASON_WEEK, $result)) {
                //未找到
                $this->openWeek = 0;
            } else {
                $this->openWeek = (int)$result[GameConstantDefine::COMMON_KEY_SEASON_WEEK];
            }
        }
    }

    public function getOpenSeasonWeek(): int
    {
        if (is_null($this->openWeek)) {
            $this->getNowSeasonWeek();
        }
        return $this->openWeek;
    }

    //----------赛季重置------------

    //完成未领取的任务奖励
    public function getDoneNotGetTaskReward(): array
    {
        if (is_null($this->seasonTaskListConfig)) {
            $this->getSeasonTaskConfigByWeek(0);
        }
        foreach ($this->seasonTaskListConfig as $week => $taskIds) {
            $this->checkDoneTaskIds($week);
        }
        //检查加道具
        foreach ($this->doneTaskList as $taskId) {
            //添加完成未领取奖励
            $this->addTaskRewardByTaskId($taskId);
        }
        return $this->getCompleteReward();
    }

    //查询完成未领取的任务
    private function checkDoneTaskIds(int $week)
    {
        $taskList = $this->searchSeasonTaskFromDBByWeek($week);
        foreach ($taskList as $taskId => $status) {
            if ($status == TaskData::STATUS_DONE) {
                $this->doneTaskList[] = $taskId;
            }
        }
    }

    //重置赛季任务
    public function resetSeasonTask()
    {
        $taskList = $this->getSeasonTaskConfigByWeek(0);
        $hasSeasonTaskDic = $this->searchSeasonTaskFromDBByWeek(0);
        $hasSeasonTaskList = array_keys($hasSeasonTaskDic);
        //检查 任务是否有新增 删除
        $delTaskIds = array_diff($hasSeasonTaskList, $taskList);
        foreach ($delTaskIds as $taskId) {
            if (false == $this->delTask($taskId)) {
                LogMark::getInstance()->markError(
                    GameErrorCode::TASK_DEL_ERROR,
                    "[SeasonTaskManager] del task fail",
                    array(
                        "taskId" => $taskId
                    )
                );
                continue;
            }
        }
        foreach ($taskList as $taskId) {
            if (array_key_exists($taskId, $hasSeasonTaskDic)) {
                //重置老任务
                if (false == $this->resetTask($taskId)) {
                    LogMark::getInstance()->markError(
                        GameErrorCode::TASK_RESET_ERROR,
                        "[SeasonTaskManager] reset task fail",
                        array(
                            "taskId" => $taskId
                        )
                    );
                    continue;
                }
            } else {
                //添加新任务
                $this->createSeasonTask($taskId, 0);
            }
        }
        $this->delAllSeasonWeekTask();
    }

    //删除全部的周任务
    public function delAllSeasonWeekTask()
    {
        if (is_null($this->seasonTaskListConfig)) {
            $this->getSeasonTaskConfigByWeek(0);
        }
        foreach ($this->seasonTaskListConfig as $week => $taskIds) {
            if ($week == 0) {
                continue;
            }
            foreach ($taskIds as $taskId) {
                if (false == $this->delTask($taskId)) {
                    LogMark::getInstance()->markError(
                        GameErrorCode::TASK_DEL_ERROR,
                        "[SeasonTaskManager] del task fail",
                        array(
                            "taskId" => $taskId
                        )
                    );
                    continue;
                }
            }
        }
    }

}
