<?php

/**
 * 赛季商城
 */

namespace Game\Model\Shop;

use Framework\Lib\Utils;
use Framework\Log\LogMark;
use Framework\Logic\TemplateHelp;
use Game\Constant\ConstTemplate\TemplateMatchTime;
use Game\Constant\ConstTemplate\TemplateSeasonStore;
use Game\Constant\GameErrorCode;
use Game\Constant\TemplateDefine;
use Game\Data\Shop\ShopSeasonData;
use Game\Logic\SeasonLogic;
use Game\Protobuf\ShopItem;

class ShopSeasonModel
{
    use TemplateHelp;
    use SeasonLogic;

    private int $playerId;
    private array $sendShopItem = array();

    public function setPlayerId($playerId)
    {
        $this->playerId = $playerId;
    }

    //获取商城道具
    public function getShopItem(): array
    {
        $shopSeasonData = new ShopSeasonData($this->playerId);
        $shopItem = $shopSeasonData->searchDB();
        if (empty($shopItem)) {
            return $this->initShopItem();
        }
        return $shopItem;
    }

    //初始赛季商城
    private function initShopItem(): array
    {
        $seasonId = $this->getSeasonId();
        if ($seasonId == 0) {
            LogMark::getInstance()->markError(
                GameErrorCode::SEASON_ID_NOT_FOUND,
                "[ShopSeasonModel] season error",
                array(
                    "season" => $seasonId
                )
            );
            return array();
        }
        $seasonShopConfig = $this->getTitle(TemplateDefine::TYPE_MATCH_TIME, $seasonId);
        if (is_null($seasonShopConfig) || empty($seasonShopConfig[TemplateMatchTime::ShopItemIds])) {
            LogMark::getInstance()->markError(
                GameErrorCode::SHOP_CONFIG_NOT_FOUND,
                "[ShopSeasonModel] not found shop item",
                array(
                    "season" => $seasonId
                )
            );
            return array();
        }
        $shopItem = array(
            ShopSeasonData::RefreshDate => Utils::getServerTimestamp(),
            ShopSeasonData::SeasonId => $seasonId,
        );
        foreach ($seasonShopConfig[TemplateMatchTime::ShopItemIds] as $itemId) {
            $shopItem[$itemId] = 0;
        }
        $shopSeasonData = new ShopSeasonData($this->playerId);
        if (false == $shopSeasonData->updateDB($shopItem)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                "[ShopSeasonModel] init shop date error",
                $shopItem
            );
            return array();
        }
        return $shopItem;
    }

    //重置每日限购
    public function resetDailyLimit()
    {
        $shopSeasonData = new ShopSeasonData($this->playerId);
        $shopItem = $shopSeasonData->searchDB();
        if (empty($shopItem)) {
            $this->initShopItem();
            return;
        }
        $seasonId = $this->getSeasonId();
        if ($seasonId == 0) {
            LogMark::getInstance()->markError(
                GameErrorCode::SEASON_ID_NOT_FOUND,
                "[ShopSeasonModel] season error",
                array(
                    "season" => $seasonId
                )
            );
            return;
        }
        $seasonShopConfig = $this->getTitle(TemplateDefine::TYPE_MATCH_TIME, $seasonId);
        if (is_null($seasonShopConfig)) {
            LogMark::getInstance()->markError(
                GameErrorCode::SHOP_CONFIG_NOT_FOUND,
                "[ShopSeasonModel] not found shop item",
                array(
                    "season" => $seasonId
                )
            );
            return;
        }
        if (empty($seasonShopConfig[TemplateMatchTime::ShopItemDailyResetIds])) {
            //检查跨周重置
            $this->resetWeekLimit($seasonShopConfig);
            //没有需要重置道具
            return;
        }
        foreach ($seasonShopConfig[TemplateMatchTime::ShopItemDailyResetIds] as $itemId) {
            $shopItem[$itemId] = 0;
        }
        if (false == $this->updateBuyNum($shopItem)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                "[ShopSeasonModel] reset shop daily date error",
                $shopItem
            );
        }
        //检查跨周重置
        $this->resetWeekLimit($seasonShopConfig);
    }

    //每周重置限购
    private function resetWeekLimit(array $seasonShopConfig)
    {
        if (empty($seasonShopConfig[TemplateMatchTime::ShopItemWeekResetIds])) {
            //没有需要重置道具
            return;
        }
        //检查是否跨周
        $shopSeasonData = new ShopSeasonData($this->playerId);
        if (Utils::checkIsCrossWeek($shopSeasonData->getFreshDate())) {
            $shopItem = array(
                ShopSeasonData::RefreshDate => Utils::getServerTimestamp()
            );
            foreach ($seasonShopConfig[TemplateMatchTime::ShopItemWeekResetIds] as $itemId) {
                $shopItem[$itemId] = 0;
            }
            if (false == $this->updateBuyNum($shopItem)) {
                LogMark::getInstance()->markError(
                    GameErrorCode::DATA_UPDATE_ERROR,
                    "[ShopSeasonModel] reset shop week date error",
                    $shopItem
                );
            }
        }
    }

    //赛季更新,重置赛季商城
    public function resetShopSeasonData(int $newSeasonId)
    {
        $shopSeasonData = new ShopSeasonData($this->playerId);
        $shopItem = $shopSeasonData->searchDB();
        if (empty($shopItem)) {
            $this->initShopItem();
            return;
        }
        //删除非永久道具
        $delItemIds = array();
        foreach ($shopItem as $itemId => $num) {
            if (is_numeric($itemId)) {
                //检查限购类型
                $itemTerm = $this->getTerm(
                    TemplateDefine::TYPE_SHOP_SEASON,
                    $itemId,
                    TemplateSeasonStore::Term);
                if (is_null($itemTerm) || $itemTerm != TemplateSeasonStore::TERM_TYPE_FOREVER) {
                    $delItemIds[] = $itemId;
                    unset($shopItem[$itemId]);
                }
            }
        }
        $shopSeasonData->delItemId($delItemIds);
        //检查上次同步赛季到当前赛季需要添加的道具
        for ($i = $shopItem[ShopSeasonData::SeasonId] + 1; $i <= $newSeasonId; $i++) {
            $seasonConfig = $this->getTitle(TemplateDefine::TYPE_MATCH_TIME, $i);
            if (is_null($seasonConfig)) {
                continue;
            }
            foreach ($seasonConfig[TemplateMatchTime::ShopItemIds] as $itemId) {
                if (!isset($shopItem[$itemId])) {
                    $shopItem[$itemId] = 0;
                }
            }
        }
        $shopItem[ShopSeasonData::SeasonId] = $newSeasonId;
        $shopItem[ShopSeasonData::RefreshDate] = Utils::getServerTimestamp();
        $shopSeasonData->updateDB($shopItem);
    }

    public function addSendShopItem(array $shopItem)
    {
        foreach ($shopItem as $key => $value) {
            if (is_numeric($key)) {
                $sItem = new ShopItem();
                $sItem->setId($key);
                $sItem->setBuyNum($value);
                $this->sendShopItem[] = $sItem;
            }
        }
    }

    //获取已购买数量
    public function getHasBuyNum(int $id): int
    {
        $shopItem = $this->getShopItem();
        return $shopItem[$id] ?? 0;
    }

    //更新购买数量
    public function updateBuyNum(array $data): bool
    {
        if (empty($data)) {
            return true;
        }
        return (new ShopSeasonData($this->playerId))->updateDB($data);
    }

    public function getSendShopItem(): array
    {
        return $this->sendShopItem;
    }
}
