<?php

/**
 * 战令商城
 */

namespace Game\Model\Shop;

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

class ShopZLModel
{
    use TemplateHelp;
    use SeasonLogic;

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

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

    //获取商城道具
    public function getShopItem(): array
    {
        $ShopZLData = new ShopZLData($this->playerId);
        $shopItem = $ShopZLData->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,
                "[ShopZLModel] season error",
                array(
                    "season" => $seasonId
                )
            );
            return array();
        }
        $seasonShopConfig = $this->getTitle(TemplateDefine::TYPE_MATCH_TIME, $seasonId);
        if (is_null($seasonShopConfig) || empty($seasonShopConfig[TemplateMatchTime::ShopZLItemIds])) {
            LogMark::getInstance()->markError(
                GameErrorCode::SHOP_CONFIG_NOT_FOUND,
                "[ShopZLModel] not found shop item",
                array(
                    "season" => $seasonId
                )
            );
            return array();
        }
        $shopItem = array(
            ShopZLData::RefreshDate => time(),
            ShopZLData::SeasonId => $seasonId,
        );
        foreach ($seasonShopConfig[TemplateMatchTime::ShopZLItemIds] as $itemId) {
            $shopItem[$itemId] = 0;
        }
        $ShopZLData = new ShopZLData($this->playerId);
        if (false == $ShopZLData->updateDB($shopItem)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                "[ShopZLModel] init shop date error",
                $shopItem
            );
            return array();
        }
        return $shopItem;
    }

    //重置每日限购
    public function resetDailyLimit()
    {
        $ShopZLData = new ShopZLData($this->playerId);
        $shopItem = $ShopZLData->searchDB();
        if (empty($shopItem)) {
            $this->initShopItem();
            return;
        }
        $seasonId = $this->getSeasonId();
        if ($seasonId == 0) {
            LogMark::getInstance()->markError(
                GameErrorCode::SEASON_ID_NOT_FOUND,
                "[ShopZLModel] 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,
                "[ShopZLModel] not found shop item",
                array(
                    "season" => $seasonId
                )
            );
            return;
        }
        if (empty($seasonShopConfig[TemplateMatchTime::ShopZLItemDailyResetIds])) {
            //检查跨周重置
            $this->resetWeekLimit($seasonShopConfig);
            //没有需要重置道具
            return;
        }
        foreach ($seasonShopConfig[TemplateMatchTime::ShopZLItemDailyResetIds] as $itemId) {
            $shopItem[$itemId] = 0;
        }
        if (false == $this->updateBuyNum($shopItem)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                "[ShopZLModel] reset shop daily date error",
                $shopItem
            );
        }
        //检查跨周重置
        $this->resetWeekLimit($seasonShopConfig);
    }

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

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

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