<?php

/**
 * 日常任务
 */

namespace Game\Logic\Task;

use Framework\Lib\Utils;
use Framework\Log\LogMark;
use Framework\MVC\ModelManager;
use Game\Constant\ClientErrorCode;
use Game\Constant\ConstTemplate\TemplateTask;
use Game\Constant\EventTypeDefine;
use Game\Constant\GameConstantDefine;
use Game\Constant\GameErrorCode;
use Game\Constant\ModelTypeDefine;
use Game\Data\ActiveData;
use Game\Data\TaskData;
use Game\Logic\ActiveLogic;
use Game\Logic\EventLogic;
use Game\Logic\ItemLogic;
use Game\Method\Player\AddPlayerExp;
use Game\Model\Task\ActiveModel;
use Game\Model\Task\Manager\DailyChallengeTaskManager;
use Game\Model\Task\Manager\DailyTaskManager;
use Game\Model\Task\Manager\TaskMangerModelBase;

trait DailyTaskLogic
{
    use ItemLogic;
    use EventLogic;
    use AddPlayerExp;
    use ActiveLogic;

    // 获取日常信息
    public function getDailyActiveInfo(): ActiveData
    {
        /**
         * @var ActiveModel $activeModel
         */
        $activeModel = ModelManager::getInstance()->getModel(ModelTypeDefine::TASK_ACTIVE);
        return $activeModel->getActiveData();
    }

    // 查询完成未领取的任务
    public function getDoneDailyTask(): array
    {
        /**
         * @var DailyTaskManager $dailyTaskModel
         */
        $dailyTaskModel = ModelManager::getInstance()->getModel(ModelTypeDefine::TASK_DAILY);
        return $dailyTaskModel->getDoneTaskIds();
    }

    //一键提交任务
    public function submitDailyTask(array $taskIds): ActiveData
    {
        /**
         * @var TaskMangerModelBase $taskBaseModel
         */
        $taskBaseModel = ModelManager::getInstance()->getModel(ModelTypeDefine::TASK_BASE);
        $compTaskType = array();    //[完成任务类型=>数量]
        //查询任务
        /**
         * @var TaskData $taskData
         */
        foreach ($taskIds as $taskId) {
            $taskData = $taskBaseModel->getTask($taskId);
            if (is_null($taskData)) {
                LogMark::getInstance()->markError(
                    GameErrorCode::TASK_NOT_FOUND_IN_DB,
                    "[DailyTaskLogic] task not found",
                    array(
                        "taskId" => $taskId
                    )
                );
                continue;
            }
            if ($taskData->status == TaskData::STATUS_DOING) {
                LogMark::getInstance()->markError(
                    GameErrorCode::TASK_STATUS_ERROR,
                    "[DailyTaskLogic] task status error,can not submit",
                    (array)$taskData
                );
                continue;
            }
            if ($taskData->status == TaskData::STATUS_OVER) {
                LogMark::getInstance()->markError(
                    GameErrorCode::TASK_STATUS_ERROR,
                    "[DailyTaskLogic] task status error,can not submit",
                    (array)$taskData
                );
                continue;
            }
            $taskBaseModel->completeTask($taskData);
            $type = $taskData->taskConfig[TemplateTask::TaskType];
            isset($compTaskType[$type]) ?
                $compTaskType[$type] += 1 :
                $compTaskType[$type] = 1;
        }
        if (!empty($compTaskType)) {
            //触发完成任务数量
            $param = array(
                GameConstantDefine::EVENT_KEY_COMP_TASK_TYPE => $compTaskType
            );
            $this->triggerEvent(EventTypeDefine::EVENT_TYPE_TASK_COMP_NUM, $param);
        }
        //加道具
        [$itemReward, $numReward, $exp] = $taskBaseModel->getCompleteReward();
        $this->setLogAddItemSource(GameConstantDefine::ITEM_ADD_SOURCE_TASK);
        $this->gainItemArr($itemReward);
        //任务变化消息
        $taskBaseModel->sendChangeTaskMessage();
        //加活跃度
        /**
         * @var ActiveModel $activeModel
         */
        $activeModel = ModelManager::getInstance()->getModel(ModelTypeDefine::TASK_ACTIVE);
        //加玩家经验
        $this->addPlayerExp($exp);
        return $activeModel->addActivePoint($numReward);
    }

    // 获取当前活跃度奖励
    public function getActiveLvReward(int $start, int $end): ActiveData
    {
        /**
         * @var ActiveModel $activeModel
         */
        $activeModel = ModelManager::getInstance()->getModel(ModelTypeDefine::TASK_ACTIVE);
        $reward = $activeModel->getActiveReward($start, $end);
        //加道具
        $this->setLogAddItemSource(GameConstantDefine::ITEM_ADD_SOURCE_ACTIVE_REWARD);
        $this->gainItemArr($reward);

        //修改领取进度
        return $activeModel->setActiveId($end);
    }

    //刷新日常挑战任务
    public function refreshDailyChallengeTask(int $taskId): array
    {
        /**
         * @var ActiveModel $activeModel
         */
        $activeModel = ModelManager::getInstance()->getModel(ModelTypeDefine::TASK_ACTIVE);
        $activeData = $activeModel->getActiveData();
        if ($activeData->refreshNum <= 0) {
            //刷新次数不足
            return [
                ClientErrorCode::TASK_DAILY_CHALLENGE_REFRESH_NUM_NOT_ENOUGH,
                $activeData->refreshNum,
                null
                ];
        }
        /**
         * @var DailyChallengeTaskManager $dayChallengeTaskManager
         */
        $dayChallengeTaskManager = ModelManager::getInstance()->getModel(ModelTypeDefine::TASK_DAILY_CHALLENGE);
        //检查刷新任务类型
        $taskData = $dayChallengeTaskManager->getTask($taskId);
        if (is_null($taskData)) {
            return [
                ClientErrorCode::TASK_NOT_FOUND,
                $activeData->refreshNum,
                null
            ];
        }
        if ($taskData->taskConfig[TemplateTask::TaskType] != TemplateTask::TASK_TYPE_DAILY_CHALLENGE) {
            //任务类型错误
            return [
                ClientErrorCode::TASK_DAILY_CHALLENGE_TYPE_ERROR,
                $activeData->refreshNum,
                null
            ];
        }
        if ($taskData->status != TaskData::STATUS_DOING) {
            //进行中的任务 才能刷新
            return [
                ClientErrorCode::TASK_DAILY_CHALLENGE_CAN_NOT_REFRESH,
                $activeData->refreshNum,
                null
            ];
        }
        //刷新任务
        $newTaskId = $dayChallengeTaskManager->resetDailyChallengeTask();
        if (is_null($newTaskId)) {
            return [
                ClientErrorCode::TASK_DAILY_CHALLENGE_REFRESH_FAIL,
                $activeData->refreshNum,
                null
            ];
        }
        //删除要刷新的任务
        if (false == $dayChallengeTaskManager->delTask($taskId)) {
            LogMark::getInstance()->markError(
                GameErrorCode::TASK_DEL_ERROR,
                "[DailyTaskLogic] refreshDailyChallengeTask,del task fail",
                array(
                    "taskId" => $taskId
                )
            );
            return [
                ClientErrorCode::TASK_DAILY_CHALLENGE_REFRESH_FAIL,
                $activeData->refreshNum,
                null
            ];
        }
        if (false == $dayChallengeTaskManager->createTask($newTaskId)) {
            LogMark::getInstance()->markError(
                GameErrorCode::TASK_DAILY_CREATE_ERROR,
                "[DailyTaskLogic] refreshDailyChallengeTask,create new task fail",
                array(
                    "taskId" => $taskId
                )
            );
            return [
                ClientErrorCode::TASK_DAILY_CHALLENGE_REFRESH_FAIL,
                $activeData->refreshNum,
                null
            ];
        }
        $newTask = $dayChallengeTaskManager->getTask($newTaskId);
        //修改刷新次数
        $activeData->subRefreshNum();
        $activeData->updateDB();
        return [
            ClientErrorCode::CLIENT_SUCCESS,
            $activeData->refreshNum,
            $newTask
        ];
    }

    //日常任务和日常挑战任务,跨周跨天重置
    public function resetDailyTask()
    {
        //获取任务刷新时间
        /**
         * @var ActiveModel $activeModel
         */
        $activeModel = ModelManager::getInstance()->getModel(ModelTypeDefine::TASK_ACTIVE);
        $activeData = $activeModel->getActiveData();
        /**
         * @var DailyChallengeTaskManager $dayChallengeTaskManager
         */
        $dayChallengeTaskManager = ModelManager::getInstance()->getModel(ModelTypeDefine::TASK_DAILY_CHALLENGE);
        /**
         * @var DailyTaskManager $dailyTaskManager
         */
        $dailyTaskManager = ModelManager::getInstance()->getModel(ModelTypeDefine::TASK_DAILY);
        if (Utils::checkIsCrossWeek($activeData->refreshTime)) {
            //跨周,领取日常和日常挑战任务完成未领取的奖励发送邮件
            //更新活跃度,领取活跃度未领取的奖励发邮件
            //重置日常任务
            $doneTaskIds = array_merge(
                $dailyTaskManager->getDoneTaskIds(),
                $dayChallengeTaskManager->getDoneTaskIds()
            );
            foreach ($doneTaskIds as $taskId) {
                //添加日常完成未领取奖励
                $dailyTaskManager->addTaskRewardByTaskId($taskId);
            }
            [$itemReward, $numReward, $exp] = $dailyTaskManager->getCompleteReward();
            //完成未领取的任务,增加活跃度
            if ($numReward > 0) {
                $this->addActivePoint($numReward);
            }
            if (!empty($itemReward)) {
                $dailyTaskManager->sendDailyUnReceiveMail($itemReward);
            }
            //加玩家经验
            $this->addPlayerExp($exp);
            //领取活跃度未领取的奖励发邮件
            $this->sendActiveRewardMail();
            //跨周重置活跃度
            $activeModel->reset();
            //重置日常任务
            $dailyTaskManager->resetDailyTaskByWeek();
            //重置日常挑战任务
            $dayChallengeTaskManager->resetDailyChallengeTaskByWeek();
            return;
        }
        //正常跨天,重置日常任务,完成未领取的奖励发邮件
        //重置日常挑战刷新次数,刷新日常挑战任务
        $dailyTaskManager->resetDailyTaskByDay();
        $activeModel->resetRefreshNum();
        $dayChallengeTaskManager->refreshDailyChallengeTaskByDay();
    }
}
