<?php

/**
 * 修改昵称
 */

namespace Game\Controller\Account;

use Framework\Define\ErrorDefine;
use Framework\Lib\Utils;
use Framework\Model\CommonModel;
use Framework\MVC\ControllerBase;
use Framework\MVC\ModelManager;
use Framework\Network\SendMessage;
use Game\Constant\ClientErrorCode;
use Game\Constant\ConstTemplate\TemplateConst;
use Game\Constant\ConstTemplate\TemplateItem;
use Game\Constant\GameConstantDefine;
use Game\Constant\ModelTypeDefine;
use Game\Constant\TemplateDefine;
use Game\Data\AccountData;
use Game\Logic\AccountLogic;
use Game\Logic\ItemLogic;
use Game\Logic\ShieldWordsLogic;
use Game\Model\Rank\RankModel;
use Game\Protobuf\CGChangeNickName;
use Game\Protobuf\GCChangeNickName;
use Game\Protobuf\PacketId;

class CG_ChangeNickName extends ControllerBase
{
    use AccountLogic;
    use ShieldWordsLogic;
    use ItemLogic;

    private GCChangeNickName $sendMessage;

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

    public function run(): int
    {
        $nickName = $this->message->getNickName();
        //检查敏感词
        if ($this->checkFuckWord($nickName)) {
            return $this->sendMessage(ClientErrorCode::NICKNAME_HAS_SHIELD_WORD);
        }
        //检查昵称长度
        $code = $this->checkNicknameLen($nickName);
        if ($code != ClientErrorCode::CLIENT_SUCCESS) {
            return $this->sendMessage($code);
        }
        //检查是否被占用
        if (!$this->checkRoleName($nickName)) {
            return $this->sendMessage(ClientErrorCode::NICKNAME_HAS_USED);
        }
        //检查道具
        $itemId = TemplateItem::ITEM_ID_CHANGE_NICKNAME_CARD;
        if ($this->getItemNumByTplID($itemId) <= 0) {
            return $this->sendMessage(ClientErrorCode::ITEM_NOT_ENOUGH);
        }
        //检查时间
        $param = [
            AccountData::DB_NICK_NAME,
            AccountData::DB_CHANGE_NICKNAME_TIME,
        ];
        $playerInfo = $this->getAccountPropertyArr($this->playerId, $param);
        if (!is_null($playerInfo[AccountData::DB_CHANGE_NICKNAME_TIME]) &&
            $playerInfo[AccountData::DB_CHANGE_NICKNAME_TIME] != 0 &&
            $playerInfo[AccountData::DB_CHANGE_NICKNAME_TIME] > Utils::getServerTimestamp()) {
            return $this->sendMessage(ClientErrorCode::NICKNAME_CD);
        }

        $oldNickname = $playerInfo[AccountData::DB_NICK_NAME];
        //替换Common昵称
        /**
         * @var CommonModel $common
         */
        $common = ModelManager::getInstance()->getModel(ModelTypeDefine::COMMON);
        if (!$common->replaceNickname($oldNickname, $nickName, $this->playerId)) {
            return $this->sendMessage(ClientErrorCode::NICKNAME_HAS_USED);
        }
        //扣除道具
        $this->setLogConsumeItemSource(GameConstantDefine::ITEM_CONSUME_SOURCE_CHANGE_NICKNAME);
        $this->subItemByTID($itemId, 1);

        $cdDay = $this->getTerm(
            TemplateDefine::TYPE_CONST,
            TemplateConst::Const_Change_Nickname_CD,
            TemplateConst::ConstNum
        );
        $data = array(
            AccountData::DB_NICK_NAME => $nickName,
            AccountData::DB_CHANGE_NICKNAME_TIME => Utils::getServerTimestamp() + $cdDay * 86400,
        );
        $this->saveAccountData($data);
        $this->sendMessage->setNickName($nickName);
        //通知好友更新
        $this->upRoleStatus(GameConstantDefine::PLAYER_STATUS_ONLINE, $this->playerId);
        //更新排行榜信息
        /**
         * @var RankModel $rankModel
         */
        $rankModel = ModelManager::getInstance()->getModel(ModelTypeDefine::RANKING);
        $rankModel->syncMineRankInfo();
        return $this->sendMessage(ClientErrorCode::CLIENT_SUCCESS);
    }

    private function sendMessage(int $code): int
    {
        $this->sendMessage->setCode($code);
        SendMessage::getInstance()->sendClient(PacketId::GC_ChangeNickName, $this->sendMessage);
        return ErrorDefine::SUCCESS;
    }
}
