<?php

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

namespace Game\Model\Task\Manager;

use Framework\Lib\Utils;
use Framework\Log\LogMark;
use Framework\DB\Handler\PlayerDBHandler;
use Framework\Logic\TimerLogic;
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;
use Game\Logic\ActiveLogic;
use Game\Logic\MailLogic;
use Game\Method\Player\AddPlayerExp;

class DailyTaskManager extends TaskMangerModelBase
{
    use MailLogic;
    use ActiveLogic;
    use TimerLogic;
    use PlayerDBHandler;
    use AddPlayerExp;

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

    //初始日常任务 注册完成后
    public function initDailyTaskOnRegisterOver()
    {
        $this->setIsRegister();
        $this->initDailyTask($this->getDailyTaskConfig());
    }

    //初始日常任务
    private function initDailyTask(array $dailyTaskListConfig)
    {
        foreach ($dailyTaskListConfig as $taskId)
        {
            if (false == $this->createTask($taskId)) {
                LogMark::getInstance()->markError(
                    GameErrorCode::TASK_DAILY_CREATE_ERROR,
                    "[DailyTaskManager] daily task create error",
                    array(
                        "taskId" => $taskId
                    )
                );
                continue;
            }
        }
    }

    //获取全部日常任务
    public function getDailyTask(): array
    {
        //检查是否需要初始化
        if (is_null($this->allDailyTaskDic)) {
            $this->getDailyTaskDic();
        }
        if (empty($this->allDailyTaskDic)) {
            //初始化数据
            $this->initActiveInfo();
            //初始任务
            $this->initDailyTask($this->getDailyTaskConfig());
            $this->getDailyTaskDic();
        }
        $taskList = array();
        $completeTaskList = array();
        foreach ($this->allDailyTaskDic 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);
    }

    //每日重置日常任务
    public function resetDailyTaskByDay()
    {
        //检查完成未领取任务奖励,发邮件
        $this->sendDoneDailyTaskRewardMail();
        $this->resetDailyTaskData();
    }

    //每周重置日常任务
    public function resetDailyTaskByWeek()
    {
        $this->getDailyTaskDic();
        $this->resetDailyTaskData();
    }

    //重置日常任务
    private function resetDailyTaskData()
    {
        $hasTaskIds = array_keys($this->allDailyTaskDic);
        //获取表日常任务
        $dailyTaskListConfig = $this->getDailyTaskConfig();
        //检查 任务是否有新增 删除
        $delTaskIds = array_diff($hasTaskIds, $dailyTaskListConfig);
        foreach ($delTaskIds as $taskId) {
            //删除任务
            if (!$this->delTask($taskId)) {
                LogMark::getInstance()->markError(
                    GameErrorCode::TASK_DEL_ERROR,
                    "[DailyTaskManager] del task fail",
                    array(
                        "taskId" => $taskId
                    )
                );
                continue;
            }
        }
        foreach ($dailyTaskListConfig as $taskId)
        {
            if (array_key_exists($taskId, $this->allDailyTaskDic)) {
                //重置老任务
                if (!$this->resetTask($taskId)) {
                    LogMark::getInstance()->markError(
                        GameErrorCode::TASK_RESET_ERROR,
                        "[DailyTaskManager] reset task fail",
                        array(
                            "taskId" => $taskId
                        )
                    );
                    continue;
                }
            } elseif (!$this->createTask($taskId)) {
                LogMark::getInstance()->markError(
                    GameErrorCode::TASK_DAILY_CREATE_ERROR,
                    "[DailyTaskManager] daily task create error",
                    array(
                        "taskId" => $taskId
                    )
                );
                continue;
            }
        }
    }

    /**
     * 查询完成未领取的任务
     * @return array [taskId,..]
     */
    public function getDoneTaskIds(): array
    {
        if (is_null($this->allDailyTaskDic)) {
            $this->getDailyTaskDic();
        }
        $doneTaskIds = array();
        foreach ($this->allDailyTaskDic as $taskId => $status) {
            if ($status == TaskData::STATUS_DONE) {
                $doneTaskIds[] = $taskId;
            }
        }
        return $doneTaskIds;
    }

    //查询当前全部的日常任务id
    public function getDailyTaskDic()
    {
        if (is_null($this->allDailyTaskDic)) {
            $this->allDailyTaskDic = array();
        }
        $this->getTitleList(
            $this->getDBTable(),
            $this->playerId,
            $this->allDailyTaskDic
        );
    }


    //每日完成未领取的任务 发邮件
    private function sendDoneDailyTaskRewardMail()
    {
        $taskIds = $this->getDoneTaskIds();
        if (empty($taskIds)) {
            return;
        }
        foreach ($taskIds as $taskId) {
            //添加日常完成未领取奖励
            $this->addTaskRewardByTaskId($taskId);
        }
        [$itemReward, $numReward, $exp] = $this->getCompleteReward();
        //完成未领取的任务,增加活跃度
        if ($numReward > 0) {
            $this->addActivePoint($numReward);
        }
        if (!empty($itemReward)) {
            $this->sendDailyUnReceiveMail($itemReward);
        }
        //加玩家经验
        $this->addPlayerExp($exp);
    }

    //发送日常未领奖邮件
    public function sendDailyUnReceiveMail(array $reward)
    {
        $mailTplId = $this->getTerm(TemplateDefine::TYPE_CONST,
                                           TemplateConst::Const_Task_Daily_Reward_Mail_id,
                                           TemplateConst::ConstNum);
        $this->createPlayerMail($mailTplId, Utils::getServerTimestamp(), $reward);
    }

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

    private function getDailyTaskConfig(): array
    {
        $configInitData = $this->getTitle(TemplateDefine::TYPE_INIT_PLAYER, TemplateInitPlayer::DEFAULT_ID);
        $dailyTaskListConfig = $configInitData[TemplateInitPlayer::DailyTaskList];
        if (empty($dailyTaskListConfig)) {
            LogMark::getInstance()->markError(
                GameErrorCode::TASK_DAILY_NOT_FOUND,
                "[DailyTaskManager] daily task not found"
            );
            return array();
        }
        return $dailyTaskListConfig;
    }
}
