<?php

/**
 * 日常挑战任务管理
 */

namespace Game\Model\Task\Manager;

use Framework\DB\Handler\PlayerDBHandler;
use Framework\Log\LogMark;
use Game\Constant\ConstTemplate\TemplateConst;
use Game\Constant\ConstTemplate\TemplateInitPlayer;
use Game\Constant\DBTableDefine;
use Game\Constant\GameErrorCode;
use Game\Constant\TemplateDefine;
use Game\Data\TaskData;

class DailyChallengeTaskManager extends TaskMangerModelBase
{
    use PlayerDBHandler;

    private ?array $allDailyChallengeTaskDic = null;   //taskId->status

    //初始日常挑战任务 注册完成后
    public function initDailyChallengeTaskOnRegisterOver()
    {
        $this->setIsRegister();
        $this->initDailyChallengeTask($this->getDailyChallengeTaskConfig());
    }

    //初始日常挑战任务
    private function initDailyChallengeTask(array $configTaskList)
    {
        //随机3个任务
        $freshNum = (int)$this->getTerm(
            TemplateDefine::TYPE_CONST,
            TemplateConst::Const_Task_Daily_Challenge_Num,
            TemplateConst::ConstNum);
        $keyList = array_rand($configTaskList, $freshNum);
        foreach ($keyList as $key) {
            $taskId = $configTaskList[$key];
            if (false == $this->createTask($taskId)) {
                LogMark::getInstance()->markError(
                    GameErrorCode::TASK_DAILY_CREATE_ERROR,
                    "[DailyChallengeTaskManager] daily challenge task create error",
                    array(
                        "taskId" => $taskId
                    )
                );
                continue;
            }
        }
    }

    //获取全部日常挑战任务
    public function getDailyChallengeTask(): array
    {
        //检查是否需要初始化
        if (is_null($this->allDailyChallengeTaskDic)) {
            $this->getDailyChallengeTaskDic();
        }
        if (empty($this->allDailyChallengeTaskDic)) {
            //初始任务
            $this->initDailyChallengeTask($this->getDailyChallengeTaskConfig());
            $this->getDailyChallengeTaskDic();
        }
        $taskList = array();
        $completeTaskList = array();
        foreach ($this->allDailyChallengeTaskDic 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);
    }

    //重置日常挑战任务
    //每次刷新3个(不能重复),最多9个
    public function refreshDailyChallengeTaskByDay()
    {
        if (is_null($this->allDailyChallengeTaskDic)) {
            $this->getDailyChallengeTaskDic();
        }
        if (empty($this->allDailyChallengeTaskDic)) {
            //初始任务
            $this->initDailyChallengeTask($this->getDailyChallengeTaskConfig());
            $this->getDailyChallengeTaskDic();
            return;
        }
        $doingTaskNum = 0;
        //删除完成的任务
        foreach ($this->allDailyChallengeTaskDic as $taskId => $status) {
            if ($status == TaskData::STATUS_OVER) {
                $this->delTask($taskId);
            } else {
                $doingTaskNum++;
            }
        }
        $maxNum = (int)$this->getTerm(
            TemplateDefine::TYPE_CONST,
            TemplateConst::Const_Task_Daily_Challenge_Max_Num,
            TemplateConst::ConstNum);
        if ($doingTaskNum >= $maxNum) {
            //超过最大数量,不需要刷新
            return;
        }
        $num = (int)$this->getTerm(
            TemplateDefine::TYPE_CONST,
            TemplateConst::Const_Task_Daily_Challenge_Num,
            TemplateConst::ConstNum);
        $freshNum = $maxNum - $doingTaskNum >= $num ? $num : $maxNum - $doingTaskNum;
        //刷新新任务,不能有重复的
        $config = $this->getDailyChallengeTaskConfig();
        shuffle($config);
        foreach ($config as $taskId) {
            if ($freshNum <= 0) {
                break;
            }
            if (!array_key_exists($taskId, $this->allDailyChallengeTaskDic)) {
                if (false == $this->createTask($taskId)) {
                    LogMark::getInstance()->markError(
                        GameErrorCode::TASK_DAILY_CREATE_ERROR,
                        "[DailyChallengeTaskManager] daily challenge task create error",
                        array(
                            "taskId" => $taskId
                        )
                    );
                    continue;
                }
                $freshNum--;
            }
        }
    }

    //每周重置日常挑战任务,先删除全部任务,再刷新
    //重置为3个
    public function resetDailyChallengeTaskByWeek()
    {
        if (is_null($this->allDailyChallengeTaskDic)) {
            $this->getDailyChallengeTaskDic();
        }
        if (empty($this->allDailyChallengeTaskDic)) {
            //初始任务
            $this->initDailyChallengeTask($this->getDailyChallengeTaskConfig());
            return;
        }
        foreach ($this->allDailyChallengeTaskDic as $taskId => $status) {
            $this->delTask($taskId);
        }
        $this->initDailyChallengeTask($this->getDailyChallengeTaskConfig());
    }

    //刷新挑战任务--只刷新任务,在其他条件检查完成后调用
    public function resetDailyChallengeTask(): ?int
    {
        if (is_null($this->allDailyChallengeTaskDic)) {
            $this->getDailyChallengeTaskDic();
        }
        $config = $this->getDailyChallengeTaskConfig();
        shuffle($config);
        $refreshTaskId = null;
        foreach ($config as $taskId) {
            if (!is_null($refreshTaskId)) {
                break;
            }
            if (!array_key_exists($taskId, $this->allDailyChallengeTaskDic)) {
                $refreshTaskId = $taskId;
                break;
            }
        }
        if (is_null($refreshTaskId)) {
            LogMark::getInstance()->markError(
                GameErrorCode::TASK_DAILY_CHALLENGE_REFRESH_FAIL,
                "[DailyChallengeTaskManager] refresh daily challenge Task Fail",
                array(
                    "taskId" => $refreshTaskId
                )
            );
            return null;
        }
        return $refreshTaskId;
    }

    //获取全部完成未领取的任务Id
    public function getDoneTaskIds(): array
    {
        $this->getDailyChallengeTaskDic();
        $doneTaskIds = array();
        foreach ($this->allDailyChallengeTaskDic as $taskId => $status) {
            if ($status == TaskData::STATUS_OVER) {
                $doneTaskIds[] = $taskId;
            }
        }
        return $doneTaskIds;
    }

    //查询当前全部的日常任务id
    private function getDailyChallengeTaskDic()
    {
        if (is_null($this->allDailyChallengeTaskDic)) {
            $this->allDailyChallengeTaskDic = array();
        }
        $this->getTitleList(
            DBTableDefine::TABLE_TASK_DAILY_CHALLENGE,
            $this->playerId,
            $this->allDailyChallengeTaskDic
        );
    }

    private function getDailyChallengeTaskConfig(): array
    {
        $configInitData = $this->getTerm(
            TemplateDefine::TYPE_INIT_PLAYER,
            TemplateInitPlayer::DEFAULT_ID,
            TemplateInitPlayer::DailyChallengeTaskList
        );
        if (empty($configInitData)) {
            LogMark::getInstance()->markError(
                GameErrorCode::TASK_DAILY_NOT_FOUND,
                "[DailyChallengeTaskManager] daily challenge task not found"
            );
            return array();
        }
        return $configInitData;
    }
}
