<?php

/**
 * 地图挑战赛活动
 * 每期活动数据单独存储,新活动开始直接初始,上一期活动数据保留
 */

namespace Framework\Logic\Activity;

use Framework\DB\Handler\CommonDBHandler;
use Framework\Lib\Utils;
use Framework\Log\LogMark;
use Framework\Logic\CommonDataLogic;
use Framework\Logic\CommonTimerLogic;
use Framework\Logic\TemplateHelp;
use Game\Constant\ActivityDefine;
use Game\Constant\ConstTemplate\TemplateActivityTime;
use Game\Constant\ConstTemplate\TemplateChallengeTime;
use Game\Constant\GameConstantDefine;
use Game\Constant\GameErrorCode;
use Game\Constant\ModelTypeDefine;
use Game\Constant\TemplateDefine;
use Game\Logic\CommonConstLogic;
use Game\Logic\RankLogic;
use Game\Model\Rank\RankModel;

trait CommonMapChallengeLogic
{
    /**
     * 注:每日10点开启新地图
     */

    use TemplateHelp;
    use CommonTimerLogic;
    use CommonDBHandler;
    use CommonDataLogic;
    use RankLogic;
    use CommonConstLogic;

    //设置活动开启时间
    public function setMapChallengeOpenTime(int $activityId, int $time): bool
    {
        $titleId = ActivityDefine::makeActivityTitleKey(
            ActivityDefine::ACTIVITY_NAME_MAP_CHALLENGE,
            ActivityDefine::ACTIVITY_STATUS_UNOPENED,
            $activityId
        );
        //设置CommonConst开启活动状态
        $data = array(
            GameConstantDefine::COMMON_KEY_ACTIVITY_MAP_CHALLENGE => $activityId,
            GameConstantDefine::COMMON_KEY_ACTIVITY_MAP_CHALLENGE_STATUS => ActivityDefine::ACTIVITY_STATUS_UNOPENED,
            GameConstantDefine::COMMON_KEY_ACTIVITY_MAP_CHALLENGE_START_TIME => date("Y-m-d H:i:s", $time)
        );
        $this->saveCommonConstData($data);
        return $this->addCommonTimer($this->getModelName(), $titleId, $time);
    }

    //设置活动关闭时间
    public function setMapChallengeCloseTime(int $activityId, int $time): bool
    {
        $titleId = ActivityDefine::makeActivityTitleKey(
            ActivityDefine::ACTIVITY_NAME_MAP_CHALLENGE,
            ActivityDefine::ACTIVITY_STATUS_CLOSE,
            $activityId
        );
        $data = array(
            GameConstantDefine::COMMON_KEY_ACTIVITY_MAP_CHALLENGE_END_TIME => date("Y-m-d H:i:s", $time)
        );
        $this->saveCommonConstData($data);
        return $this->addCommonTimer($this->getModelName(), $titleId, $time);
    }

    //开启活动
    public function openMapChallenge(int $activityId)
    {
        //获取地图配置
        $config = $this->getTitle(TemplateDefine::TYPE_CHALLENGE_TIME, $activityId);
        if (is_null($config)) {
            LogMark::getInstance()->markError(
                GameErrorCode::ACTIVITY_CONFIG_NOT_FOUND,
                "[MapChallengeLogic] ChallengeTime config not found",
                array(
                    "id" => $activityId
                )
            );
            return;
        }
        //检查当前时间和开启时间间隔,开启地图
        $activityConfig = $this->getTerm(
            TemplateDefine::TYPE_ACTIVITY_TIME,
            ActivityDefine::ACTIVITY_NAME_MAP_CHALLENGE,
            $activityId);
        $gapDay = Utils::getGapDay(Utils::getServerTimestamp(), $activityConfig[TemplateActivityTime::StartTime]);
        $maxMapNum = count($config[TemplateChallengeTime::MapId]);
        $openMap = array();
        for ($i = 0; $i <= $gapDay; $i++) {
            if ($i >= $maxMapNum) {
                break;
            }
            $openMap[] = $config[TemplateChallengeTime::MapId][$i];
        }
        if (count($openMap) < $maxMapNum) {
            //设置明天开启新地图时间
            $this->setMapChallengeDailyUpdateTime($activityId);
        }
        //设置CommonConst开启活动id和地图
        $data = array(
            GameConstantDefine::COMMON_KEY_ACTIVITY_MAP_CHALLENGE => $activityId,
            GameConstantDefine::COMMON_KEY_ACTIVITY_MAP_CHALLENGE_MAP => json_encode($openMap),
            GameConstantDefine::COMMON_KEY_ACTIVITY_MAP_CHALLENGE_STATUS => ActivityDefine::ACTIVITY_STATUS_DOING,
            GameConstantDefine::COMMON_KEY_ACTIVITY_MAP_CHALLENGE_START_TIME => date("Y-m-d H:i:s", $activityConfig[TemplateActivityTime::StartTime])
        );
        $this->saveCommonConstData($data);
        //设置结束时间
        $this->setMapChallengeCloseTime($activityId, $activityConfig[TemplateActivityTime::EndTime]);

        LogMark::getInstance()->markInfo(
            "[CommonMapChallengeLogic] openMapChallenge",
            array(
                "activityId" => $activityId
            )
        );
    }

    //设置活动每日开启新地图时间
    //每天10点开启新地图
    private function setMapChallengeDailyUpdateTime(int $activityId): bool
    {
        $titleId = ActivityDefine::makeActivityTitleKey(
            ActivityDefine::ACTIVITY_NAME_MAP_CHALLENGE,
            ActivityDefine::ACTIVITY_STATUS_DOING,
            $activityId
        );
        $nextUpdateTime = strtotime(date("Y-m-d 10:00:00", strtotime("+1 day")));
        return $this->addCommonTimer($this->getModelName(), $titleId, $nextUpdateTime);
    }

    //每日更新,开启新地图
    private function dailyUpdateNewMap(int $activityId)
    {
        $commonConstData = $this->getCommonConstData();
        //获取地图配置
        $config = $this->getTitle(TemplateDefine::TYPE_CHALLENGE_TIME, $activityId);
        if (is_null($config)) {
            LogMark::getInstance()->markError(
                GameErrorCode::ACTIVITY_CONFIG_NOT_FOUND,
                "[MapChallengeLogic] ChallengeTime config not found",
                array(
                    "id" => $activityId
                )
            );
            return;
        }
        //检查activeId
        if (isset($commonConstData[GameConstantDefine::COMMON_KEY_ACTIVITY_MAP_CHALLENGE]) &&
            $commonConstData[GameConstantDefine::COMMON_KEY_ACTIVITY_MAP_CHALLENGE] != $activityId
        ) {
            LogMark::getInstance()->markError(
                GameErrorCode::ACTIVITY_CONFIG_NOT_FOUND,
                "[MapChallengeLogic] Challenge expire activeId is not equal Now ActiveId",
                array(
                    "expireId" => $activityId,
                    "nowActiveId" => $commonConstData[GameConstantDefine::COMMON_KEY_ACTIVITY_MAP_CHALLENGE]
                )
            );
            return;
        }
        //获取当前已开启的地图
        $openMapList = isset($commonConstData[GameConstantDefine::COMMON_KEY_ACTIVITY_MAP_CHALLENGE_MAP]) ?
            json_decode($commonConstData[GameConstantDefine::COMMON_KEY_ACTIVITY_MAP_CHALLENGE_MAP], true) :
            [];
        $idx = count($openMapList);
        if (isset($config[TemplateChallengeTime::MapId][$idx])) {
            //有能开启的新地图,开启新地图
            $openMapList[] = $config[TemplateChallengeTime::MapId][$idx];
            //设置CommonConst开启活动id和地图
            $data = array(
                GameConstantDefine::COMMON_KEY_ACTIVITY_MAP_CHALLENGE_MAP => json_encode($openMapList),
                GameConstantDefine::COMMON_KEY_ACTIVITY_MAP_CHALLENGE_STATUS => ActivityDefine::ACTIVITY_STATUS_DOING,
            );
            $this->saveCommonConstData($data);
            //设置明天开启新地图时间
            $this->setMapChallengeDailyUpdateTime($activityId);
            LogMark::getInstance()->markInfo(
                "[CommonMapChallengeLogic] dailyUpdateNewMap",
                array(
                    "activityId" => $activityId,
                    "newMap" => $openMapList
                )
            );
            return;
        }
        LogMark::getInstance()->markInfo(
            "[CommonMapChallengeLogic] dailyUpdateNewMap no new map to open",
            array(
                "activityId" => $activityId,
                "map" => $openMapList
            )
        );
    }

    //到期关闭活动
    private function closeMapChallenge(int $activityId)
    {
        //获取下个活动配置
        $config = $this->getTerm(
            TemplateDefine::TYPE_ACTIVITY_TIME,
            ActivityDefine::ACTIVITY_NAME_MAP_CHALLENGE,
            $activityId + 1);
        if (is_null($config)) {
            //没有后续活动,关闭当前活动
            $data = array(
                GameConstantDefine::COMMON_KEY_ACTIVITY_MAP_CHALLENGE => $activityId,
                GameConstantDefine::COMMON_KEY_ACTIVITY_MAP_CHALLENGE_STATUS => ActivityDefine::ACTIVITY_STATUS_CLOSE,
            );
            $this->saveCommonConstData($data);
            LogMark::getInstance()->markInfo(
                "[CommonMapChallengeLogic] closeMapChallenge, not found next activityId",
                array(
                    "activityId" => $activityId,
                )
            );
            return;
        }
        //有后续活动,检查开启后续活动
        LogMark::getInstance()->markInfo(
            "[CommonMapChallengeLogic] closeMapChallenge, wait to open new Activity",
            array(
                "activityId" => $activityId,
                "nextActivityId" => $activityId + 1,
                "nextOpenTime" => $config[TemplateActivityTime::StartTime]
            )
        );
        //设置下个活动开启 关闭时间
        $this->setMapChallengeOpenTime($activityId + 1, $config[TemplateActivityTime::StartTime]);
        $this->setMapChallengeCloseTime($activityId + 1, $config[TemplateActivityTime::EndTime]);
        //删除排行榜
        $config = $this->getTitle(TemplateDefine::TYPE_CHALLENGE_TIME, $activityId);
        foreach ($config[TemplateChallengeTime::MapId] as $mapId) {
            $this->clearRankInfo(RankModel::MAP_CHALLENGE, $mapId);
        }
    }

    //处理地图挑战赛过期事件
    public function dealMapChallengeExipre(int $status, int $activityId)
    {
        switch ($status)
        {
            case ActivityDefine::ACTIVITY_STATUS_UNOPENED:
                //到期开启活动
                $this->openMapChallenge($activityId);
                break;
            case ActivityDefine::ACTIVITY_STATUS_DOING:
                //每日开启新地图
                $this->dailyUpdateNewMap($activityId);
                break;
            case ActivityDefine::ACTIVITY_STATUS_CLOSE:
                //到期关闭活动
                $this->closeMapChallenge($activityId);
                break;
        }
    }

    private function getModelName(): int
    {
        return ModelTypeDefine::COMMON_ACTIVITY;
    }
}
