<?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\GameConstantDefine;
use Game\Constant\ModelTypeDefine;
use Game\Constant\TemplateDefine;
use Game\Logic\CommonConstLogic;

trait CommonScuffleLogic
{
    use TemplateHelp;

    use CommonTimerLogic;
    use CommonDBHandler;
    use CommonDataLogic;
    use CommonConstLogic;

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

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

    //开启活动
    public function openScuffle(int $activityId)
    {
        //设置CommonData数据
        $this->addCommonData($this->getActivityModelName(), $activityId);
        LogMark::getInstance()->markInfo(
            "[CommonScuffleLogic] openScuffle",
            array(
                "activityId" => $activityId
            )
        );
        //设置CommonConst开启活动状态
        $data = array(
            GameConstantDefine::COMMON_KEY_ACTIVITY_SCUFFLE => $activityId,
            GameConstantDefine::COMMON_KEY_ACTIVITY_SCUFFLE_STATUS => ActivityDefine::ACTIVITY_STATUS_DOING,
            GameConstantDefine::COMMON_KEY_ACTIVITY_SCUFFLE_START_TIME => date("Y-m-d")." 00:00:00"
        );
        $this->saveCommonConstData($data);
    }

    //关闭活动
    public function closeScuffle(int $activityId)
    {
        //解析活动id
        [$year, $yearWeek, $week] = $this->analysisScuffleActivityId($activityId);
        //获取下一个活动
        $config = $this->getTitle(TemplateDefine::TYPE_ACTIVITY_TIME, ActivityDefine::ACTIVITY_NAME_SCUFFLE);
        if (is_null($config)) {
            //没有后续活动,关闭当前活动
            $data = array(
                GameConstantDefine::COMMON_KEY_ACTIVITY_SCUFFLE => $activityId,
                GameConstantDefine::COMMON_KEY_ACTIVITY_SCUFFLE_STATUS => ActivityDefine::ACTIVITY_STATUS_CLOSE,
            );
            $this->saveCommonConstData($data);
            LogMark::getInstance()->markInfo(
                "[CommonScuffleLogic] closeScuffle, not found next activityId",
                array(
                    "activityId" => $activityId,
                )
            );
            return;
        }
        $config = $config[0];
        //有后续活动,检查开启后续活动
        if (in_array($week, $config[TemplateActivityTime::TimeParameter])) {
            $idx = array_search($week, $config[TemplateActivityTime::TimeParameter]);
            if (isset($config[TemplateActivityTime::TimeParameter][$idx + 1])) {
                //本周有活动
                $nextWeek = $config[TemplateActivityTime::TimeParameter][$idx + 1];
            } else {
                //下周有活动
                $nextWeek = $config[TemplateActivityTime::TimeParameter][0];
            }
        } else {
            $nextWeek = null;
            foreach ($config[TemplateActivityTime::TimeParameter] as $openWeek) {
                if ($openWeek <= $week) {
                    //已过去的时间
                    continue;
                }
                if ($openWeek > $week) {
                    //还未开启
                    $nextWeek = $openWeek;
                    break;
                }
            }
            if (is_null($nextWeek)) {
                //当前时间错过了全部的开启时间,选第一个开启时间
                $nextWeek = $config[TemplateActivityTime::TimeParameter][0];
            }
        }
        $startTime = strtotime(Utils::getWeekEn($nextWeek), strtotime(date("Y-m-d")));
        $nextActivityId = $this->markScuffleActivityId($nextWeek, $startTime);
        LogMark::getInstance()->markInfo(
            "[CommonScuffleLogic] closeScuffle, wait to open new Activity",
            array(
                "activityId" => $activityId,
                "nextActivityId" => $nextActivityId,
                "nextOpenTime" => $startTime
            )
        );
        //设置开启时间
        $this->setScuffleOpenTime($nextActivityId, $startTime);
        $endTime = $startTime + $config[TemplateActivityTime::TimeGap] * 86400 -1;
        $this->setScuffleCloseTime($nextActivityId, $endTime);
    }

    //处理大乱斗过期事件
    public function dealScuffleExipre(int $status, int $activityId)
    {
        switch ($status)
        {
            case ActivityDefine::ACTIVITY_STATUS_UNOPENED:
                //到期开启活动
                $this->openScuffle($activityId);
                break;
            case ActivityDefine::ACTIVITY_STATUS_CLOSE:
                //到期关闭活动
                $this->closeScuffle($activityId);
                break;
        }
    }

    //返回 年(两位).当年的第X周.活动开始周
    public function markScuffleActivityId(int $week, int $time = 0): string
    {
        if ($time == 0) {
            $time = Utils::getServerTimestamp();
        }
        return date("yW", $time).$week;
    }

    public function analysisScuffleActivityId(string $activityId): array
    {
        return array(
            substr($activityId, 0, 2),  //year
            substr($activityId, 2, 2),  //week of year
            $activityId[strlen($activityId) - 1]   //week
        );
    }

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

    private function getActivityModelName(): int
    {
        return ModelTypeDefine::SCUFFLE;
    }
}
