<?php

/**
 * 战令 索要/赠送
 */

namespace Game\Controller\Task;

use Framework\Define\ErrorDefine;
use Framework\Lib\Utils;
use Framework\Log\LogMark;
use Framework\MVC\ControllerBase;
use Framework\MVC\ModelManager;
use Framework\Network\SendMessage;
use Game\Constant\ClientErrorCode;
use Game\Constant\ConstTemplate\TemplateConst;
use Game\Constant\GameConstantDefine;
use Game\Constant\GameErrorCode;
use Game\Constant\ModelTypeDefine;
use Game\Constant\TemplateDefine;
use Game\Data\WarTokenData;
use Game\Logic\SeasonLogic;
use Game\Logic\WarTokenLogic;
use Game\Model\MailModel;
use Game\Model\Task\WarTokenModel;
use Game\Protobuf\CGZLOption;
use Game\Protobuf\GCZLOption;
use Game\Protobuf\PacketId;
use Game\Logic\ShieldWordsLogic;
use Game\Logic\MailLogic;

class ZLOption extends ControllerBase
{
    use WarTokenLogic;
    use ShieldWordsLogic;
    use MailLogic;
    use SeasonLogic;

    private GCZLOption $sendMessage;

    public function __construct()
    {
        $this->message = new CGZLOption();
        $this->sendMessage = new GCZLOption();
    }

    public function run(): int
    {
        $option = $this->message->getOption();
        $id = $this->message->getID();
        $info = $this->message->getInfo();
        $toPlayerID = $this->message->getToPlayerID();

        //检查赛季状态
        if ($this->getSeasonStatus() == GameConstantDefine::SEASON_STATUS_CLOSE) {
            $this->sendZLOptionMsg(ClientErrorCode::SEASON_CLOSE, $option);
            return ErrorDefine::SUCCESS;
        }
        // 判断购买本人 与 赠送人 是否开启了战令
        $code = $this->verifyIsBuyZL($option, $toPlayerID);
        if($code != ClientErrorCode::CLIENT_SUCCESS) {
            $this->sendZLOptionMsg($code, $option);
            return ErrorDefine::SUCCESS;
        }

        // 屏蔽字服务器二次处理
        $infoMsg = $this->replaceFuckWord($info);

        // 发送邮件
        // TODO::跨区给不同区服发送邮件 （暂时单区）
        if(!$this->sendZLMail($option, $id, $infoMsg, $toPlayerID)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_CREATE_ERROR, '[ZL option ctrl] send mail error!',
                ['option' => $option, 'id' => $id, 'infoMsg' => $infoMsg, 'toPlayerID' => $toPlayerID]
            );
        }
        $this->sendZLOptionMsg(ClientErrorCode::CLIENT_SUCCESS, $option);
        return ErrorDefine::SUCCESS;
    }

    public function sendZLMail(int $option, int $id, string $infoMsg, $toPlayerID):bool {
        $zlItemID = $this->getZLItemID($id);
        switch ($option) {
            // 索要
            case WarTokenData::ZL_DEMAND:
                //索要邮件 给对方
                $demandMailID = $this->getTerm(TemplateDefine::TYPE_CONST,
                    TemplateConst::Const_ZL_Demand_Mail_ID, TemplateConst::ConstNum);
                //替换邮件内容
                $replaceString = $this->replaceMailContent($demandMailID, array(
                    GameConstantDefine::MAIL_KEY_PLAYER_NAME => $this->playerId,
                    GameConstantDefine::MAIL_KEY_ITEM_ID => $zlItemID
                ));
                $this->createPlayerMail(
                    $demandMailID,
                    Utils::getServerTimestamp(),
                    [$zlItemID => 1],
                    0,
                    $toPlayerID,
                    $this->playerId,
                    $infoMsg,
                    $replaceString
                );
                //索要邮件 给自己
                $demandMsgMailID = $this->getTerm(TemplateDefine::TYPE_CONST,
                    TemplateConst::Const_ZL_Demand_Send_Msg, TemplateConst::ConstNum);
                //替换邮件内容
                $replaceString = $this->replaceMailContent($demandMsgMailID, array(
                    GameConstantDefine::MAIL_KEY_OTHER_NAME => $toPlayerID,
                ));
                $this->createPlayerMail(
                    $demandMsgMailID,
                    Utils::getServerTimestamp(),
                    array(),
                    0,
                    $this->playerId,
                    0,
                    "",
                    $replaceString
                );
                break;
            // 赠送
            case WarTokenData::ZL_GIVE:
                //赠送邮件 给对方
                $giveMailID = $this->getTerm(TemplateDefine::TYPE_CONST,
                    TemplateConst::Const_ZL_To_My_Give_Mail_ID, TemplateConst::ConstNum);
                $replaceString = $this->replaceMailContent($giveMailID, array(
                    GameConstantDefine::MAIL_KEY_PLAYER_NAME => $this->playerId,
                    GameConstantDefine::MAIL_KEY_ITEM_ID => $zlItemID
                ));
                $this->createPlayerMail(
                    $giveMailID,
                    Utils::getServerTimestamp(),
                    [$zlItemID => 1],
                    0,
                    $toPlayerID,
                    $this->playerId,
                    $infoMsg,
                    $replaceString
                );
                //赠送邮件 给自己
                $msgMailID = $this->getTerm(TemplateDefine::TYPE_CONST,
                    TemplateConst::Const_ZL_My_Give_Mail_ID, TemplateConst::ConstNum);
                //替换邮件内容
                $replaceString = $this->replaceMailContent($msgMailID, array(
                    GameConstantDefine::MAIL_KEY_OTHER_NAME => $toPlayerID,
                    GameConstantDefine::MAIL_KEY_ITEM_ID => $zlItemID
                ));
                $this->createPlayerMail(
                    $msgMailID,
                    Utils::getServerTimestamp(),
                    array(),
                    0,
                    $this->playerId,
                    0,
                    "",
                    $replaceString
                );
                break;
        }

        return true;
    }

    private function getZLItemID(int $id): int {
        $itemID = 0;
        switch ($id) {
            case WarTokenData::EXPERT_FLAG_PRIMARY:
                $itemID = $this->getTerm(TemplateDefine::TYPE_CONST,
                    TemplateConst::Const_ZL_Primary_Item_ID, TemplateConst::ConstNum);
                break;
            case WarTokenData::EXPERT_FLAG_EXPERT:
                $itemID = $this->getTerm(TemplateDefine::TYPE_CONST,
                    TemplateConst::Const_ZL_Expert_Item_ID, TemplateConst::ConstNum);
                break;
            default:
                LogMark::getInstance()->markError(
                    GameErrorCode::DATA_SEARCH_ERROR,
                    '[ZL option ctrl] get zl itemId error!', ['id' => $id]);
        }
        return $itemID;
    }

    public function verifyIsBuyZL(int $option, int $toPlayerID): int {
        switch ($option) {
            case WarTokenData::ZL_DEMAND:
                /**
                 * @var WarTokenModel $warTokenModel
                 */
                $warTokenModel = ModelManager::getInstance()->getModel(ModelTypeDefine::WAR_TOKEN);
                $warTokenData =  $warTokenModel->getWarTokenData();
                if($warTokenData->expertFlag != WarTokenData::EXPERT_FLAG_DEFAULT) {
                    return ClientErrorCode::ZL_DEMAND_REPEATED_ERROR;
                }
                break;
            case WarTokenData::ZL_GIVE:
                // TODO::跨区查找好友的战令开启记录
                /**
                 * @var WarTokenModel $warTokenModel
                 */
                $warTokenModel = ModelManager::getInstance()->getModel(ModelTypeDefine::WAR_TOKEN);
                $minePlayerID = $this->playerId;
                $warTokenModel->setPlayerId($toPlayerID);
                $warTokenData =  $warTokenModel->getWarTokenData();
                if($warTokenData->expertFlag != WarTokenData::EXPERT_FLAG_DEFAULT) {
                    return ClientErrorCode::ZL_GIVE_REPEATED_ERROR;
                }
                $warTokenModel->setPlayerId($minePlayerID);
                break;
        }
        return ClientErrorCode::CLIENT_SUCCESS;
    }

    private function sendZLOptionMsg(int $code, $option) {
        $this->sendMessage->setCode(ClientErrorCode::CLIENT_SUCCESS);
        $this->sendMessage->setOption($option);
        SendMessage::getInstance()->sendClient(PacketId::GC_ZLOption, $this->sendMessage);
    }
}
