<?php
/**
 * 俱乐部
 */
namespace Game\Model\Club;

use Framework\Log\LogMark;
use Framework\MVC\ModelManager;
use Framework\Network\SendMessage;
use Framework\DB\Handler\PlayerDBHandler;
use Framework\Lib\Utils;
use Game\Config\GameConfig;
use Game\Constant\ClientErrorCode;
use Game\Constant\ConstTemplate\TemplateClubLevel;
use Game\Constant\ConstTemplate\TemplateClubScheduleReward;
use Game\Constant\ConstTemplate\TemplateConst;
use Game\Constant\DBTableDefine;
use Game\Constant\GameConstantDefine;
use Game\Constant\GameErrorCode;
use Game\Constant\ModelTypeDefine;
use Game\Constant\TemplateDefine;
use Game\Data\AccountData;
use Game\Data\Club\BattlePassData;
use Game\Data\Club\ClubData;
use Game\Data\Club\ClubPlayerData;
use Game\Logic\AccountLogic;
use Game\Logic\MoneyLogic;
use Game\Logic\PaiweiLevelLogic;
use Game\Model\AccountModel;
use Game\Model\Car\CarExteriorRefitModel;
use Game\Model\Car\CarModel;
use Game\Protobuf\Club;
use Game\Protobuf\ClubInfo;
use Game\Protobuf\ClubPlayer;
use Game\Protobuf\GCApplyJoinClear;
use Game\Protobuf\GCApprovalJoin;
use Game\Protobuf\GCChangeClub;
use Game\Protobuf\GCChangeNotice;
use Game\Protobuf\GCChangePost;
use Game\Protobuf\GCChangeTag;
use Game\Protobuf\GCClubInfo;
use Game\Protobuf\GCCreateClub;
use Game\Protobuf\GCDelClubMember;
use Game\Protobuf\GCDisbandClub;
use Game\Protobuf\GCExitClub;
use Game\Protobuf\GCFindMyClubID;
use Game\Protobuf\GCImpeachMaster;
use Game\Protobuf\GCImpeachResMsg;
use Game\Protobuf\GCReplaceClubMaster;
use Game\Protobuf\GCRequestJoinClub;
use Game\Protobuf\GCSearchClubFuzzy;
use Game\Protobuf\GCUpdateClubPlayer;
use Game\Protobuf\JoinApplyStruct;
use Game\Protobuf\PacketId;
Use Game\Data\Club\CommCLubData;

class ClubModel {
    use PlayerDBHandler;
    use AccountLogic;
    use PaiweiLevelLogic;
    use MoneyLogic;

    const JOIN_STATE_ALLOWED     = 1;   // 无需审核
    const JOIN_STATE_CHECK       = 2;   // 需要审核
    const JOIN_STATE_NOT_ALLOWED = 3;   // 不许加入

    const POST_MEMBER = 1;   // 成员
    const POST_ADMIN  = 2;   // 管理员
    const POST_LEADER = 3;   // 队长

    const CLUB_ID_MIN             = 10000000;
    const CLUB_ID_MAX             = 99999999;
    const COMMON_CONST_CLUB_ID    = 'ClubID';

    const CLUB_CHANGE_STATE = 5;

    const CLUB_SET_FIELD = [
        1 => ClubData::DB_KEY_MAP[ClubData::IMAGE],
        2 => ClubData::DB_KEY_MAP[ClubData::BG_IMAGE],
        3 => ClubData::DB_KEY_MAP[ClubData::LEVEL_LIMIT],
        4 => ClubData::DB_KEY_MAP[ClubData::RANK_LIMIT],
        5 => ClubData::DB_KEY_MAP[ClubData::JOIN_STATE],
    ];

    public  int                   $playerId;
    public  GCCreateClub          $joinClubMsg;
    public  GCClubInfo            $clubInfoMsg;

    public function __construct() {
        $this->joinClubMsg   = new GCCreateClub();
        $this->clubInfoMsg   = new GCClubInfo();
    }

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

    public function getPlayerID(): int {
        return $this->playerId;
    }

    public function getSignData()
    {
        $clubPlayer = new ClubPlayerData($this->playerId, GameConfig::getInstance()->SERVER_ID());
        if(!$clubPlayer->searchClubPlayer()) {
            return [];
        }
        $club = new ClubData($clubPlayer->clubID);
        if (!$club->searchClubByID()){
            return [];
        }
        $clubData = array();
        $data = [
            ClubData::CLUB_ID => $club->clubID,
            ClubData::CLUB_NAME => $club->clubName,
            ClubData::CLUB_MASTER => $club->clubMaster,
            ClubData::IMAGE => $club->image,
            ClubData::BG_IMAGE => $club->bgImage,
            ClubData::LEVEL => $club->level,
            ClubData::LEVEL_SCORE => $club->levelScore,
            ClubData::LEVEL_LIMIT => $club->levelLimit,
            ClubData::CLUB_NOTICE => $club->clubNotice,
            ClubData::CLUB_TAGS => $club->clubTags,
            ClubData::RANK_LIMIT => $club->rankLimit,
            ClubData::JOIN_APPLY => $club->joinApply,
            ClubData::JOIN_STATE => $club->joinState,
            ClubData::CREATE_TIME => $club->createTime,
            ClubData::IMPEACH_DATA => $club->impeachData,
            ClubData::DONATE => $club->donate,
        ];
        $player = [];
        foreach ($club->playerInfo as $id => $playerInfo){
            $line = new ClubPlayerData($id, $playerInfo[ClubData::SERVER_ID]);
            $line->searchClubPlayer();
            $aAccount = $line->searchOtherServerAccount([AccountData::DB_NICK_NAME, AccountData::DB_GENDER, AccountData::DB_CLOTH_FEMALE, AccountData::DB_CLOTH_MALE]);
            if ($aAccount[AccountData::DB_GENDER] == AccountData::MALE){
                $clot = json_decode($aAccount[AccountData::DB_CLOTH_MALE], true);
            }else{
                $clot = json_decode($aAccount[AccountData::DB_CLOTH_FEMALE], true);
            }

            $player[$id] = [
                ClubData::PLAYER_ID => $playerInfo[ClubData::PLAYER_ID],
                ClubData::SERVER_ID => $playerInfo[ClubData::SERVER_ID],
                AccountData::DB_NICK_NAME => $aAccount[AccountData::DB_NICK_NAME],
                AccountData::DB_GENDER => (int)$aAccount[AccountData::DB_GENDER],
                "Clot" => $clot,
            ];
        }
        $data[ClubData::PLAYER_INFO] = $player;
        $clubData[] = $data;
        return $clubData;
    }

    // 登录检测所在俱乐部是否有弹劾
    public function onLoginExec() {
        // 检测是否有俱乐部
        $clubPlayer = new ClubPlayerData($this->playerId, GameConfig::getInstance()->SERVER_ID());
        if(!$clubPlayer->searchClubPlayer()) {
            // 玩家没有俱乐部
            return ;
        }
        // 检测是否有弹劾
        $club = new ClubData($clubPlayer->clubID);
        if(!$club->searchClubByID()) {
            return ;
        }
        if(empty($club->impeachData)) {
            // 没有弹劾信息
            return ;
        }
        $masterName = $this->getAccountProperty($club->clubMaster, AccountData::DB_NICK_NAME);
        // 自己是否是队长（如果是则删除弹劾）
        if($this->playerId == $club->clubMaster) {
            $subName = $this->getAccountProperty($club->impeachData[ClubData::ID], AccountData::DB_NICK_NAME);
            // 删除弹劾  发送弹劾失败消息
            $club->impeachData = [];
            $club->saveDB();
            foreach($club->playerInfo as $id => $item) {
                $this->GCAddSendImpeachRes($id, false, $subName, $masterName);
            }
            return ;
        }
        // 判断弹劾是否有效
        $timeLimit = $this->getTerm(TemplateDefine::TYPE_CONST,
            TemplateConst::Const_Impeach_Wait_Max_Time, "Const_num");
        if(Utils::getServerTimestamp() > $timeLimit * 24 * 60 * 60) {
            return ;
        }

        // 替换队长（如果发起人离开俱乐部 则职位，活跃度顺位继承）
        $in = false;
        $playerID = 0;
        $serverID = 0;
        $masterID = $club->clubMaster;
        $masterServerID = 0;
        foreach($club->playerInfo as $id => $item) {
            if($id == $item[ClubData::PLAYER_ID]) {
                $playerID = $item[ClubData::PLAYER_ID];
                $serverID = $item[ClubData::SERVER_ID];
                $in = true;
            }
            if($id == $masterID) {
                $masterServerID = $item[ClubData::SERVER_ID];
            }
        }
        if(!$in) {
            // 职位，活跃度顺位继承
            list($playerID, $serverID) = $this->selectMaster($club->playerInfo);
        }

        if(!$this->updateClubMaster($club->clubID, $playerID)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] logic check club impeach update master error!', (array)$club
            );
            return ;
        }
        if(!$this->changePlayerPost($playerID, $serverID, self::POST_LEADER)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] logic check club impeach update player post error!', (array)$club
            );
            return ;
        }
        if(!$this->changePlayerPost($playerID, $serverID, self::POST_LEADER)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] logic check club impeach update player post error!', (array)$club
            );
            return ;
        }
        if(!$this->changePlayerPost($masterID, $masterServerID, self::POST_MEMBER)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] logic check club impeach update player post error!', (array)$club
            );
            return ;
        }
        $subName = $this->getAccountProperty($playerID, AccountData::DB_NICK_NAME);
        // 发送成功 消息
        foreach($club->playerInfo as $id => $item) {
            $this->GCAddSendImpeachRes($id, true, $subName, $masterName);
        }
    }

    private function selectMaster(array $info) :array {
        $admin = [];
        $member = [];
        $playerID = 0;
        $serverID = 0;
        $active = 0;
        foreach ($info as $id => $item) {
            $clubPlayer = new ClubPlayerData($id, $item[ClubData::SERVER_ID]);
            $clubPlayer->searchClubPlayer();
            if($clubPlayer->post == self::POST_ADMIN) {
                $admin[] = [
                    ClubData::PLAYER_ID => $id,
                    ClubData::SERVER_ID => $item[ClubData::SERVER_ID],
                    ClubPlayerData::ACTIVE => $clubPlayer->active
                ];
            }
            if($clubPlayer->post == self::POST_MEMBER) {
                $member[] = [
                    ClubData::PLAYER_ID => $id,
                    ClubData::SERVER_ID => $item[ClubData::SERVER_ID],
                    ClubPlayerData::ACTIVE => $clubPlayer->active
                ];
            }
        }
        if(!empty($admin)) {
            foreach($admin as $item) {
                if($item[ClubPlayerData::ACTIVE] >= $active) {
                    $playerID = $item[ClubData::PLAYER_ID];
                    $serverID = $item[ClubData::SERVER_ID];
                }
            }
            return [$playerID, $serverID];
        }
        foreach($member as $item) {
            if($item[ClubPlayerData::ACTIVE] >= $active) {
                $playerID = $item[ClubData::PLAYER_ID];
                $serverID = $item[ClubData::SERVER_ID];
            }
        }
        return [$playerID, $serverID];
    }

    public function createClub(int $image, int $bgImage, string $name, array $subMoney):bool {
        $club = new ClubData(
            $this->makeClubID(),
            $name,
            $image,
            $bgImage,
            $this->playerId,
            Utils::getServerTimestamp(),
        );

        // 创建名称-clubID ZSet
        $commClubData = new CommCLubData();
        if(!$commClubData->createNameClubID($club->clubName, $club->clubID)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_CREATE_ERROR,
                '[CLubModel] create club name-clubID error!', (array)$club
            );
            $this->GCSendClearApplyJoin(ClientErrorCode::ERROR_EXEC_FAILED);
            return false;
        }

        // 创建random 查询列表
        if(!$commClubData->createRandomClubID($club->clubID)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_CREATE_ERROR,
                '[CLubModel] create club random search error!', (array)$club
            );
            $commClubData->delClubNameByClubID($club->clubName);
            $this->GCSendClearApplyJoin(ClientErrorCode::ERROR_EXEC_FAILED);
            return false;
        }

        $clubPlayer = new ClubPlayerData($this->playerId, GameConfig::getInstance()->SERVER_ID(),Utils::getServerTimestamp(), $club->clubID, self::POST_LEADER);
        if(!$clubPlayer->saveDB()) {
            $this->GCJoinClub(ClientErrorCode::ERROR_CLUB_CREATE_ERROR);
            return false;
        }
        // TODO: 默认服务器ID为 配置项
        if(!$club->CreateClubData($this->playerId, GameConfig::getInstance()->SERVER_ID())) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[CLubModel] create club info error!', (array)$club
            );
            $commClubData->delClubNameByClubID($club->clubID);
            $commClubData->delSearchClubMember($club->clubID);
            $this->GCSendClearApplyJoin(ClientErrorCode::ERROR_EXEC_FAILED);
            return false;
        }
        // 创建 创建时间.活跃表
        if (!$commClubData->addTimeAndActiveClubId($club->clubID, $club->createTime, 0)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_CREATE_ERROR,
                '[CLubModel] create club info error!', (array)$club
            );
            return false;
        }
        $this->setLogConsumeItemSource(GameConstantDefine::ITEM_CONSUME_SOURCE_CREATE_CLUB);
        // 消耗货币
        $this->createClubSubMoney($subMoney);
        $this->GCJoinClub(ClientErrorCode::CLIENT_SUCCESS, $club);
        return true;
    }

    // 查询房间
    public function searchClub(string $search): bool {
        // 通过id查询俱乐部
        if(is_numeric($search)) {
            $club1 = new ClubData((int)$search);
            if(!$club1->searchClubByID()) {
                $club1 = null;
            }
        } else {
            $club1 = null;
        }
        // 通过名称查询俱乐部
        $clubID = (new CommCLubData())->searchClubIDByCLubName($search);
        if(empty($clubID)) {
            $club2 = null;
        } else {
            $club2 = new ClubData($clubID);
            if(!$club2->searchClubByID()) {
                $club2 = null;
            }
        }
        $this->GCSendSearchClub(ClientErrorCode::CLIENT_SUCCESS, $club1, $club2);
        return true;
    }

    // 获取自己俱乐部id
    public function findMyClubID():bool {
        $clubPlayer = new ClubPlayerData($this->playerId, GameConfig::getInstance()->SERVER_ID());
        if(!$clubPlayer->searchClubPlayer()) {
            $this->GCSendFindMyClubID(ClientErrorCode::ERROR_CLUB_NOT_EXIST);
            return false;
        }
        $this->GCSendFindMyClubID(ClientErrorCode::CLIENT_SUCCESS, $clubPlayer->clubID);
        return true;
    }

    // 弹劾队长
    public function impeachMaster(int $clubID, int $serverID): bool {
        $club = new ClubData($clubID);
        if(!$club->searchClubByID()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[CLubModel] impeach master find club info error!', (array)$club
            );
            return false;
        }
        $club->impeachData = [
            ClubData::ID => $this->playerId,
            ClubData::SID => $serverID,
            ClubData::TIME => Utils::getServerTimestamp(),
        ];
        if(!$club->saveDB()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] impeach master ave club error!',
                ['club' => array($club)]
            );
            return false;
        }
        $subName = $this->getAccountProperty($this->playerId, AccountData::DB_NICK_NAME);
        $masterName = $this->getAccountProperty($club->clubMaster, AccountData::DB_NICK_NAME);
        $this->GCSendImpeachMaster(ClientErrorCode::CLIENT_SUCCESS, $subName, $masterName);
        // 同步弹劾消息给俱乐部内成员
        foreach($club->playerInfo as $id => $item) {
            if($id == $this->playerId) {
                continue;
            }
            $this->GCAddSendImpeachMaster($id,ClientErrorCode::CLIENT_SUCCESS, $subName, $masterName);
        }
        return true;
    }

    // 清空审核
    public function clearApplyJoinList(int $clubID): bool {
        $club = new ClubData($clubID);
        if(!$club->searchClubByID()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[CLubModel] clear apply join list find club info error!', (array)$club
            );
            $this->GCSendClearApplyJoin(ClientErrorCode::ERROR_EXEC_FAILED);
            return false;
        }
        // 如果没有请求消息
        if (empty($club->joinApply)) {
            $this->GCSendClearApplyJoin(ClientErrorCode::CLIENT_SUCCESS);
            return true;
        }
        $club->joinApply = [];
        if(!$club->saveDB()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] clear apply join list save club error!',
                ['club' => array($club)]
            );
            $this->GCSendClearApplyJoin(ClientErrorCode::ERROR_EXEC_FAILED);
            return false;
        }
        $this->GCSendClearApplyJoin(ClientErrorCode::CLIENT_SUCCESS);
        return true;
    }

    // 请求加入俱乐部
    public function requestJoin(int $clubID): bool {
        $exitTime = $this->getAccountProperty($this->playerId, AccountData::DB_ClUB_EXIT_TIME);
        if(!is_null($exitTime)) {
            $timeLimit = $this->getTerm(TemplateDefine::TYPE_CONST,
                TemplateConst::Const_Club_Exit_Not_Join_Time, "Const_num");
            $t = Utils::getServerTimestamp() - $exitTime;
            if($t < $timeLimit * 60 * 60) {
                $this->GCSendReqJoin(ClientErrorCode::ERROR_JOIN_TIME_LIMIT);
                return true;
            }
        }

        // 通过id查询俱乐部
        $club = new ClubData($clubID);
        if(!$club->searchClubByID()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[CLubModel] create but club exists error!', (array)$club
            );
            $this->GCSendReqJoin(ClientErrorCode::ERROR_EXEC_FAILED);
            return false;
        }
        $numMax = $this->getTerm(TemplateDefine::TYPE_CONST,
            TemplateConst::Const_Club_Num_Max, "Const_num");
        // 判断俱乐部是否可加入
        if($club->joinState == self::JOIN_STATE_NOT_ALLOWED) {
            $this->GCSendReqJoin(ClientErrorCode::ERROR_NOT_JOIN);
            return true;
        }

        // 判断是否满员
        if(count($club->playerInfo) >= $numMax) {
            $this->GCSendReqJoin(ClientErrorCode::ERROR_CLUB_NUM_IS_MAX);
            return true;
        }

        // TODO: 判断等级 段位 积分是否可加入俱乐部

        // 判断排位积分是否可以加入俱乐部
        $score = $this->getTargetPaiWeiLevel($this->playerId)->score;
        if($club->rankLimit > $score) {
            $this->GCSendReqJoin(ClientErrorCode::ERROR_CLUB_SCORE_NOT_ENOUGH);
            return true;
        }

        //todo  需要增加同步客户端俱乐部消息的操作
        //
        // 无需审核直接加入俱乐部
        if($club->joinState == self::JOIN_STATE_ALLOWED) {
            if(!$this->passApprovalJoin($clubID, $this->playerId, GameConfig::getInstance()->SERVER_ID())) {
                LogMark::getInstance()->markError(
                    GameErrorCode::DATA_UPDATE_ERROR,
                    '[CLubModel] request joni club but save error!', (array)$club
                );
                $this->GCSendReqJoin(ClientErrorCode::ERROR_EXEC_FAILED);
                return false;
            }
            $this->GCSendReqJoin(ClientErrorCode::ERROR_REQUEST_AND_JOIN_SUCCESS);
            return true;
        }

        $numMax = $this->getTerm(TemplateDefine::TYPE_CONST,
            TemplateConst::Const_Club_Join_Apply_Max, "Const_num");

        if(count($club->joinApply) >= $numMax) {
            $this->delJoinFirstData($club->joinApply);
        }

        // 加入到俱乐部请求列表中
        $club->joinApply[$this->playerId] = [
            ClubData::REQUEST_ID => $this->playerId,
            ClubData::REQUEST_TIME => Utils::getServerTimestamp(),
            ClubData::REQUEST_SERVER_ID => GameConfig::getInstance()->SERVER_ID(),
        ];
        if(!$club->saveDB()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] request join save club error!',
                ['club' => array($club)]
            );
            $this->GCSendReqJoin(ClientErrorCode::ERROR_EXEC_FAILED);
            return false;
        }
        $this->GCSendReqJoin(ClientErrorCode::CLIENT_SUCCESS);
        return true;
    }

    // 删除最早请求的信息
    private function delJoinFirstData(array &$joinData) {
        $minTime = Utils::getServerTimestamp();
        $delPlayerID = 0;
        foreach ($joinData as $pid => $item) {
            if($item[ClubData::REQUEST_TIME]  < $minTime) {
                $minTime = $item[ClubData::REQUEST_TIME];
                $delPlayerID = $pid;
            }
        }
        unset($joinData[$delPlayerID]);
    }

    // 创建俱乐部id
    private function makeClubID():int {
        $clubID = 0;
        $this->autoAddTermByClubID($clubID, DBTableDefine::TABLE_FULL_SERVER_CONST,
            self::COMMON_CONST_CLUB_ID, 1
        );
        if($clubID < self::CLUB_ID_MIN || $clubID > self::CLUB_ID_MAX) {
            $this->updateTitle(
                DBTableDefine::TABLE_FULL_SERVER_CONST, 0, 0,
                [self::COMMON_CONST_CLUB_ID => self::CLUB_ID_MIN]
            );
            $clubID = self::CLUB_ID_MIN;
        }
        // TODO: 判断是否还在使用
        return $clubID;
    }

    // 判断管理员数量是否已到上限
    public function checkAdminIsMax(int $clubID):bool {
        $club = new ClubData($clubID);
        if(!$club->searchClubByID()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[CLubModel] change post search club info error!', (array)$club
            );
            $this->GCSendReqJoin(ClientErrorCode::ERROR_EXEC_FAILED);
            return false;
        }
        $clubAdminNum = 0;
        foreach ($club->playerInfo as $id => $item) {
            $clubPlayer = new ClubPlayerData($id, $item[ClubData::SERVER_ID]);
            $clubPlayer->searchClubPlayer($id);
            if($clubPlayer->post == self::POST_ADMIN) {
                $clubAdminNum += 1;
            }
        }
        $numMax = $this->getTerm(TemplateDefine::TYPE_CONST, TemplateConst::Const_Admin_Num_Max, "Const_num");
        if($clubAdminNum >= $numMax) {
            return true;
        }
        return false;
    }

    // 修改玩家职位
    public function changePlayerPost($playerID, $serverID, $post): bool {
        //
        $clubPlayer = new ClubPlayerData($playerID, $serverID);
        if(!$clubPlayer->searchClubPlayer()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[CLubModel] change player post search clubPlayer error!',
                ['playerID' => $playerID, 'post' => $post]
            );
            return false;
        }
        $clubPlayer->setPost($post);
        if(!$clubPlayer->saveDB()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] change player post error!',
                array($clubPlayer)
            );
            return false;
        }
        return true;
    }

    public function createClubSubMoney(array $subMoney): bool {
        foreach ($subMoney as $k=>$v) {
            if(!$this->subMoney($k, $v)) {
                LogMark::getInstance()->markError(
                    GameErrorCode::DATA_UPDATE_ERROR,
                    '[CLubModel] create club sub money error!',
                    ['type' => $k, 'value' => $v]
                );
                return false;
            }
        }
        return true;
    }

    public function clubNameCheck(string $clubName): bool {
        $club = new CommCLubData();
        return $club->clubNameCheckData($clubName);
    }

    public function updateClub(int $clubID, int $type, int $params): bool {
        $club = new ClubData($clubID);
        $commClubData = new commClubData();
        if(!$club->searchClubByID()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[CLubModel] search club by clubID error!',
                ['clubID' => $clubID]
            );
            $this->GCSendChangeClub(ClientErrorCode::ERROR_CLUB_CHANGE_ERROR, $type);
            return false;
        }
        // 修改状态修改返回set表
        if($type == self::CLUB_CHANGE_STATE) {
            if(in_array($club->joinState, [self::JOIN_STATE_ALLOWED, self::JOIN_STATE_CHECK]) &&
                $params == self::JOIN_STATE_NOT_ALLOWED ) {
                $commClubData->delSearchClubMember($club->clubID);
            }
            if($club->joinState == self::JOIN_STATE_NOT_ALLOWED &&
                in_array($params, [self::JOIN_STATE_ALLOWED, self::JOIN_STATE_CHECK])) {
                $commClubData->createRandomClubID($club->clubID);
            }
        }
        $field = self::CLUB_SET_FIELD[$type];
        $club->$field = $params;
        if(!$club->saveDB()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] save club error!',
                ['club' => array($club)]
            );
            $this->GCSendChangeClub(ClientErrorCode::ERROR_CLUB_CHANGE_ERROR, $type);
            return false;
        }
        $this->GCSendChangeClub(ClientErrorCode::CLIENT_SUCCESS, $type);
        return true;
    }

    public function updateClubNotice(int $clubID, string $notice): bool {
        $club = new ClubData($clubID);
        if(!$club->searchClubByID()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[CLubModel] change notice search club by clubID error!',
                ['clubID' => $clubID]
            );
            $this->GCSendChangeNotice(ClientErrorCode::ERROR_CLUB_CHANGE_ERROR);
            return false;
        }
        $club->clubNotice = $notice;
        if(!$club->saveDB()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] change club notice error!',
                ['club' => array($club)]
            );
            $this->GCSendChangeNotice(ClientErrorCode::ERROR_CLUB_CHANGE_ERROR);
            return false;
        }
        $this->GCSendChangeNotice(ClientErrorCode::CLIENT_SUCCESS);
        return true;
    }

    public function updateClubMaster(int $clubID, int $playerID): bool {
        $club = new ClubData($clubID);
        if(!$club->searchClubByID()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[CLubModel] change club master search club by clubID error!',
                ['clubID' => $clubID]
            );
            $this->GCSendReplaceMaster(ClientErrorCode::ERROR_CLUB_CHANGE_ERROR);
            return false;
        }
        $club->clubMaster = $playerID;
        if(!$club->saveDB()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] change club master error!',
                ['club' => array($club)]
            );
            $this->GCSendReplaceMaster(ClientErrorCode::ERROR_CLUB_CHANGE_ERROR);
            return false;
        }
        return true;
    }

    public function updateClubTag(int $clubID, array $tag): bool {
        $club = new ClubData($clubID);
        if(!$club->searchClubByID()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[CLubModel] change tags search club by clubID error!',
                ['clubID' => $clubID]
            );
            $this->GCSendChangeTags(ClientErrorCode::ERROR_CLUB_CHANGE_ERROR);
            return false;
        }
        $club->clubTags = $tag;
        if(!$club->saveDB()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] change club tags error!',
                ['club' => array($club)]
            );
            $this->GCSendChangeTags(ClientErrorCode::ERROR_CLUB_CHANGE_ERROR);
            return false;
        }
        $this->GCSendChangeTags(ClientErrorCode::CLIENT_SUCCESS);
        return true;
    }

    public function getClubInfo(int $clubID):bool {
        $club = new ClubData($clubID);
        if(!$club->searchClubByID()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[CLubModel] search club info by clubID error!',
                ['clubID' => $clubID]
            );
            $this->GCGetClubInfo(ClientErrorCode::ERROR_EXEC_FAILED);
            return false;
        }
        $this->GCGetClubInfo(ClientErrorCode::CLIENT_SUCCESS, $club);
        return true;
    }

    // 俱乐部是否满员
    public function clubMemberIsMax(int $clubID):bool {
        $club = new ClubData($clubID);
        $club->searchClubByID();
        $clubMaxNum = $this->getClubMemberMax($club->level);
        if(count($club->playerInfo) >= $clubMaxNum) {
            return true;
        }
        return false;
//        $numMax = $this->getTerm(TemplateDefine::TYPE_CONST, TemplateConst::Const_Club_Num_Max, "Const_num");
//        // 判断是否满员
//        if(count($club->playerInfo) >= $numMax) {
//            return true;
//        }
    }

    // 查询剩余席位
    public function getClubVacancySeat(ClubData $c): int {
        $clubMaxNum = $this->getClubMemberMax($c->level);
        return $clubMaxNum - count($c->playerInfo);
    }

    public function getClubMemberMax(int $level): int {
        return $this->getTitle(TemplateDefine::TYPE_CLUB_LEVEL, $level)[TemplateClubLevel::PeopleNum];
    }

    // 玩家是否存在俱乐部
    public function playerInClub(int $playerID, int $serverID):bool {
        $playerClub = new ClubPlayerData($playerID, $serverID);
        if(!$playerClub->searchClubPlayer()) {
            return false;
        }
        return true;
    }
    // 玩家是否存在俱乐部
    public function playerAndMeInClub(int $playerID, int $serverID):bool {
        $playerClub = new ClubPlayerData($playerID, $serverID);
        $meClub = new ClubPlayerData($this->playerId, GameConfig::getInstance()->SERVER_ID());
        if(!$playerClub->searchClubPlayer()) {
            return false;
        }
        if(!$meClub->searchClubPlayer()) {
            return false;
        }
        if($playerClub->clubID != $meClub->clubID) {
            return false;
        }
        return true;
    }
    // 删除俱乐部成员
    public  function delClubPlayer(int $playerID, int $serverID):bool {
        $playerClub = new ClubPlayerData($playerID, $serverID);
        if(!$playerClub->deleteClubPlayer()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[CLubModel] del club player error!',
                ['playerID' => $playerID]
            );
            return false;
        }
        return true;
    }
    // 玩家加入俱乐部
    public function passApprovalJoin(int $clubID, int $playerID, int $serverID):bool {
        // 增加玩家俱乐部信息
        $club = new ClubData($clubID);
        if(!$club->searchClubByID()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[CLubModel] pass approval search club info by clubID error!',
                ['clubID' => $clubID]
            );
            return false;
        }

        if(!$this->delJoinData($club, $playerID)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] pass approval join save club error!',
                ['club' => array($club)]
            );
            return false;
        }

        // 增加俱乐部玩家信息
        $club->playerInfo[$playerID] = [
            ClubData::PLAYER_ID => $playerID,
            ClubData::SERVER_ID => $serverID
        ];
        if(!$club->saveDB()){
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] pass approval join save club error!',
                ['club' => array($club)]
            );
            return false;
        }
        $clubPlayer = new ClubPlayerData($playerID, $serverID, Utils::getServerTimestamp(), $clubID);
        if(!$clubPlayer->saveDB()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] pass approval join save club player error!',
                ['club' => array($club)]
            );
            return false;
        }

        return true;
    }
    public function delClubPlayerInfo(int $clubID, int $playerID): bool {
        // 删除俱乐部玩家信息
        $club = new ClubData($clubID);
        if(!$club->searchClubByID()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[CLubModel] del club player info search club error!',
                ['clubID' => $clubID]
            );
            return false;
        }
        foreach ($club->playerInfo as $id => $item) {
            if($id == $playerID) {
                unset($club->playerInfo[$id]);
            }
        }
        if(!$club->saveDB()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] del club player save club error!',
                ['club' => array($club)]
            );
            return false;
        }
        return true;
    }

    // 删除玩家
    public function removeClubPlayer(int $clubID, int $playerID, int $serverID):bool {
        if(!$this->delClubPlayerInfo($clubID, $playerID)) {
            return false;
        }
        return $this->delClubPlayer($playerID, $serverID);
    }

    // 玩家退出俱乐部
    public function exitClub():bool {
        $playerClub = new ClubPlayerData($this->playerId, GameConfig::getInstance()->SERVER_ID());
        if(!$playerClub->searchClubPlayer()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[CLubModel] exit club search player error!',
                ['playerID' => $this->playerId]
            );
            return false;
        }
        if(!$this->delClubPlayerInfo($playerClub->clubID, $this->playerId)) {
            return false;
        }
        // 加入退出俱乐部时间
        $this->savePlayerClubExitDate(Utils::getServerTimestamp());
        return $this->delClubPlayer($this->playerId, GameConfig::getInstance()->SERVER_ID());
    }

    // 删除玩家请求信息
    public function delClubJoinData(int $clubID, int $playerID):bool {
        // 查询俱乐部信息
        $club = new ClubData($clubID);
        if(!$club->searchClubByID()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[CLubModel] pass approval search club info by clubID error!',
                ['clubID' => $clubID]
            );
            return false;
        }
        // 删除请求信息
        foreach ($club->joinApply as $id => $item) {
            if($id == $playerID) {
                unset($club->joinApply[$id]);
            }
        }
        if(!$club->saveDB()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] pass approval join save club error!',
                ['club' => array($club)]
            );
            return false;
        }
        return true;
    }

    // 删除玩家请求信息
    public function delJoinData(ClubData &$club, int $playerID):bool {

        // 删除请求信息
        foreach ($club->joinApply as $id => $item) {
            if($id == $playerID) {
                unset($club->joinApply[$id]);
            }
        }
        if(!$club->saveDB()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[CLubModel] pass approval join save club error!',
                ['club' => array($club)]
            );
            return false;
        }
        return true;
    }

    // 解散俱乐部
    public function disbandClub(int $clubID):bool {
        // 查询俱乐部信息
        $club = new ClubData($clubID);
        $commClubData = new CommCLubData();
        if(!$club->searchClubByID()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[CLubModel] disband search club info by clubID error!',
                ['clubID' => $clubID]
            );
            return false;
        }
        // 删除成员
        foreach($club->playerInfo as $id => $item) {
            if(!$this->delClubPlayer($id, $item[ClubData::SERVER_ID])) {
                LogMark::getInstance()->markError(
                    GameErrorCode::DATA_SEARCH_ERROR,
                    '[CLubModel] disband club del player info error!',
                    ['playerID' => $id]
                );
                return false;
            }
        }
        // 删除俱乐部
        if(!$club->delClubDB()) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_DELETE_ERROR,
                '[CLubModel] disband del club info error!',
                ['clubID' => $clubID]
            );
            return false;
        }
        // 删除名称搜索
        if(!$commClubData->delClubNameByClubID($club->clubID)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_DELETE_ERROR,
                '[CLubModel] disband del club name search error!',
                ['clubID' => $clubID]
            );
            return false;
        }
        // 删除随机
        if(!$commClubData->delSearchClubMember($club->clubID)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_DELETE_ERROR,
                '[CLubModel] disband del club rand search error!',
                ['clubID' => $clubID]
            );
            return false;
        }
        return true;
    }

    //随机搜索俱乐部
    public function searchRandomClubList(&$retCLub): bool
    {
        $day = $this->getTerm(TemplateDefine::TYPE_CONST,TemplateConst::Const_Club_Recommend_List_Time, TemplateConst::ConstNum);
        $time = Utils::makeImmutableTime("-$day days");

        $comm = new CommCLubData();
        $best = $comm->searchCreatedLast($time);
        $retCLub = [];
        if (count($best) > 0){
            $n = 6;
            foreach ($best as $clubId => $active){
                $clubData = new ClubData($clubId, GameConfig::getInstance()->SERVER_ID());
                if ($this->getClubVacancySeat($clubData) > 50){
                    if ($n <= 0){
                        break;
                    }
                    $retCLub[] = $clubId;
                    $n--;
                }
            }
        }
        //筛选容量>50的
        $club = new ClubData();
        $club->playerID = $this->playerId;
        if (!$club->searchRandomList($ret)) {
            $ret = [];
            return false;
        }
        if (!empty($retCLub)){
            $n = 20;
            foreach ($ret as $clubId){
                if (in_array($clubId, $retCLub)){
                    continue;
                }
                if ($n <= 0){
                    break;
                }
                $retCLub[] = $clubId;
                $n--;
            }
        }else{
            $retCLub = $ret;
        }
        return true;
    }

    //搜索俱乐部信息
    public function searchClubData($clubId): array
    {
        $data = [];
        $club = new ClubData($clubId);
        $club->searchClubByID();
        $data[ClubData::CLUB_ID] = $club->clubID;
        $data[ClubData::CLUB_NAME] = $club->clubName;
        $data[AccountData::DB_NICK_NAME] = $this->getAccountProperty($club->clubMaster, AccountData::DB_NICK_NAME, "");
        $data[ClubData::IMAGE] = $club->image;
        $data[ClubData::BG_IMAGE] = $club->bgImage;
        $players = [];
        $carsPerformanceScore = 0;
        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        foreach($club->playerInfo as $id=>$v) {
            $players[] = $id;
            //查车辆性能分
            $accountModel->setPlayerId($id);
            $accountModel->searchAccount($account);
            $carsPerformanceScore += $account[AccountData::DB_CARS_PERFORMANCE_SCORE] ?? 0;
        }
        $data[ClubData::PLAYER_INFO] = $players;
        $data[ClubData::PLAYER_CARS] = $club->playerCars;
        $data[ClubData::LEVEL_SCORE] = $club->levelScore;
        $data[ClubData::CLUB_NOTICE] = $club->clubNotice;
        $data[ClubData::CLUB_TAGS] = $club->clubTags;
        $data[ClubData::LEVEL_LIMIT] = $club->levelLimit;
        $data[ClubData::RANK_LIMIT] = $club->rankLimit;
        $data[ClubData::JOIN_STATE] = $club->joinState;
        $data[ClubData::LEVEL] = $club->level;
        $data[AccountData::DB_CARS_PERFORMANCE_SCORE] = $carsPerformanceScore;
        return $data;
    }
    //获取自己的玩家俱乐部数据
    public function searchClubPlayerData(ClubPlayerData &$clubPlayer)
    {
        $clubPlayer = new ClubPlayerData($this->playerId, GameConfig::getInstance()->SERVER_ID());
        if(!$clubPlayer->searchClubPlayer()) {
            return false;
        }
        return true;
    }

    //活跃点
    public function upActive($score): bool
    {
        //todo 检测活跃点,每周上限 > 增加5代币/20活跃
        $playerClub = new ClubPlayerData($this->playerId, GameConfig::getInstance()->SERVER_ID());
        if (!$playerClub->searchClubPlayer()){
            return false;
        }

        if (!$playerClub->upActivity($score)){
            return false;
        }

        if (!$playerClub->upTotalActive($score)){
            return false;
        }

        if (!$playerClub->upBattlePassActive($score)){
            return false;
        }

        return $this->upClubTotalActive($playerClub->clubID, $score);
    }

    //更新俱乐部的 创建时间和所有玩家总活跃值 表
    public function upClubTotalActive($clubId, $score): bool
    {
        $club = new ClubData($clubId);
        if (!$club->searchClubByID()){
            return false;
        }
        $commClub = new CommCLubData();
        $active = $commClub->searchActiveClubId($clubId);
        return $commClub->addTimeAndActiveClubId($clubId, $club->createTime, $active+$score);
    }

    //领取battlePass可以领取的代币[活跃值转化], 返回要增加的俱乐部代币数量
    public function getBattlePassClubMoney(&$money = 0): int
    {
        $tplActive = $this->getTerm(TemplateDefine::TYPE_CONST, TemplateConst::Const_Club_Battle_Pass_Active, TemplateConst::ConstNum);
        $tplClubMoney = $this->getTerm(TemplateDefine::TYPE_CONST, TemplateConst::Const_Club_Battle_Pass_Money, TemplateConst::ConstNum);

        $tplMaxActive = $this->getTerm(TemplateDefine::TYPE_CLUB_SCHEDULE_REWARD, BattlePassData::MAX_LEVEL, TemplateClubScheduleReward::Active);

        $playerClub = new ClubPlayerData($this->playerId, GameConfig::getInstance()->SERVER_ID());
        if (!$playerClub->searchClubPlayer()){
            return ClientErrorCode::ERROR_CLUB_PLAYER_NOT_JOIN;
        }

        $battlePass = new BattlePassData();
        $battlePass->playerId = $this->playerId;
        if ($battlePass->checkMaxLevel()){
            $clubMoney = ($playerClub->activeBattlePass - $tplMaxActive - ($playerClub->clubMoney * $tplActive)) % $tplActive;
            if ($clubMoney > 0 ){
                $money = $clubMoney * $tplClubMoney;
                //增加到clubMoney字段
                $playerClub->upClubMoney($money);
                return ClientErrorCode::CLIENT_SUCCESS;
            }
        }
        return ClientErrorCode::ERROR_CLUB_BATTLE_PASS_MONEY;
    }


//    //俱乐部升级
//    public function levelUpgrade($score): bool
//    {
//        $playerClub = new ClubPlayerData($this->playerId, GameConfig::getInstance()->SERVER_ID);
//        if (!$playerClub->searchClubPlayer()){
//            return false;
//        }
//        $club = new ClubData($playerClub->clubID);
//        if (!$club->levelUpgrade($score)){
//            return false;
//        }
//        return true;
//    }

    //更新刷新时间
    public function upPlayerData($data): bool
    {
        return (new ClubPlayerData($this->playerId, GameConfig::getInstance()->SERVER_ID()))->updatePlayerDB($data);
    }

    //捐献
    public function donate($score, &$code): bool
    {
        if (!$this->searchClubPlayerData($clubPlayerData)){
            return false;
        }
        if ($clubPlayerData->active < $score){
            $code = ClientErrorCode::ERROR_CLUB_ACTIVE_DONATE;
            return false;
        }
        $clubPlayerData->active -= $score;
        //个人减少积分
        $clubPlayerData = new ClubPlayerData($this->playerId, GameConfig::getInstance()->SERVER_ID());
        $clubPlayerData->updatePlayerDB([ClubPlayerData::ACTIVE => $clubPlayerData->active]);
        //俱乐部增加积分
        return (new ClubData($clubPlayerData->clubID))->updateClubDB([ClubData::LEVEL_SCORE => $score]);
    }

    //俱乐部战令查询
    public function getBattlePass()
    {
        $battle = new BattlePassData();
        $battle->playerId = $this->playerId;
        return $battle->getData();
    }
    //俱乐部战令存储
    public function saveBattlePass($type, $rewardId): bool
    {
        $battle = new BattlePassData();
        $battle->playerId = $this->playerId;
        $battle->rewardId = $rewardId;
        return $battle->saveDB($type);
    }

    //俱乐部战令道具发放 增加经验值
    public function addClubExp($exp): bool
    {
        $playerClub = new ClubPlayerData($this->playerId, GameConfig::getInstance()->SERVER_ID());
        if (!$playerClub->searchClubPlayer()){
            return false;
        }
        $club = new ClubData($playerClub->clubID);
        if (!$club->levelUpgrade($exp)){
            return false;
        }
        return true;
    }

    //重置俱乐部战令
    public function resetBattlePass(): bool
    {
        //todo 如果未领取,需要发邮件, 活跃度转成的代币

        $clubPlayer = new ClubPlayerData($this->playerId, GameConfig::getInstance()->SERVER_ID());
        if(!$clubPlayer->searchClubPlayer()) {
            return false;
        }
        if ($clubPlayer->battlePassRefresh == 0) {
            return true;
        }

        $battlePass = new BattlePassData();
        $battlePass->delDB($clubPlayer->battlePassRefresh);

        return $clubPlayer->updatePlayerDB([
            ClubPlayerData::BATTLE_PASS_REFRESH => $battlePass->mondayIndex(),
            ClubPlayerData::ACTIVE_BATTLE_PASS => 0]);
    }

    //检测俱乐部战令是否满级
    public function checkMaxLevel(): bool
    {
        $battlePass = new BattlePassData();
        $battlePass->playerId = $this->playerId;
        return $battlePass->checkMaxLevel();
    }

    //获取自己的俱乐部数据
    public function getMineClubData($attr, $default = "")
    {
        $clubPlayer = new ClubPlayerData($this->playerId, GameConfig::getInstance()->SERVER_ID());
        if(!$clubPlayer->searchClubPlayer()) {
            return $default;
        }
        $clubData = $this->searchClubData($clubPlayer->clubID);
        if (is_string($attr)){
            if (isset($clubData[$attr])){
                return $clubData[$attr];
            }
            return $default;
        }
        if (is_array($attr)){
            $ret = [];
            foreach ($attr as $str){
                if (isset($clubData[$str])){
                    $ret[$str] = $clubData[$str];
                }else{
                    $ret[$str] = $default;
                }
            }
            return $ret;
        }
        return $default;
    }


    // ------------------------------------ GC MSG -----------------------------------------------------------

    public function GCJoinClub(int $code, ClubData $c = null) {
        $this->joinClubMsg->setCode($code);
        if(!is_null($c)) {
            $clubInfo = new ClubInfo();
            // 查询队长名称
            $account = $this->getAccountProperty($this->playerId, AccountData::DB_NICK_NAME);
            // 查询俱乐部所有成员 返回给client
            $players = [];
            $haveImpeach = false;
            if(!empty($c->impeachData)) {
                $haveImpeach = true;
            }
            foreach ($c->playerInfo as $id => $item) {
                $player = new ClubPlayer();
                $name = $this->getAccountProperty($id, AccountData::DB_NICK_NAME);
                $data = $this->getTargetPaiWeiLevel($id);
                $state = $this->getRoleStatus($id);
                /**
                 * @var CarModel $carModel
                 */
                $carModel = ModelManager::getInstance()->getModel(ModelTypeDefine::CAR);
                $carData = $carModel->getSignData($id);

                /**
                 * @var CarExteriorRefitModel $carErModel
                 */
                $carErModel = ModelManager::getInstance()->getModel(ModelTypeDefine::CAR_EXTERIOR_REFIT);
                $carErData = $carErModel->getSignData($id);
                /**
                 * @var AccountModel $account
                 */
                $account = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
                $rInfo = $account->getAccountAttr([AccountData::DB_LOGOUT_TIME]);
                $player->setStateTime($rInfo[AccountData::DB_LOGOUT_TIME]);
                $line = new ClubPlayerData($id, $item[ClubData::SERVER_ID]);
                $line->searchClubPlayer();
                $player->setPost($line->post);
                $player->setContribute($line->contribute);
                $player->setName($name);
                $player->setRankScore($data->score);
                $player->setLevelScore(1);
                $player->setState($state);
                $player->setPlayerID($id);
                $player->setServerID($item[ClubData::SERVER_ID]);
                $player->setCars(json_encode($carData));
                $player->setCarExteriorRefits(json_encode($carErData));
                $player->setActive($line->active);
                $player->setActiveBattlePass($line->activeBattlePass);
                $player->setActiveTotal($line->activeTotal);
                $player->setBattlePassMoney($line->clubMoney);
                $player->setDailyDonateFlag($line->dailyDonateFlag);
                $players[] = $player;
            }
            $clubInfo->setClubID($c->clubID)->setClubName($c->clubName)->setClubMaster($account)
                ->setImage($c->image)->setBgImage($c->bgImage)->setLevelScore($c->levelScore)
                ->setClubNotice($c->clubNotice)->setLevelLimit($c->levelLimit)->setRankdLimit($c->rankLimit)
                ->setJoinState($c->joinState)->setCreateTime($c->createTime)->setClubTags($c->clubTags)
                ->setJoinApply($c->joinApply)->setPlayers($players)->setClubScore($c->levelScore)
                ->setHaveImpeach($haveImpeach);
            $this->joinClubMsg->setData($clubInfo);
        }
    }

    public function GCSendJoinClub() {
        if(!empty($this->joinClubMsg)) {
            SendMessage::getInstance()->sendClient(PacketId::GC_CreateClub, $this->joinClubMsg);
        }
    }

    public function GCSendChangeClub(int $code, int $type) {
        $changeMsg = new GCChangeClub();
        $changeMsg->setCode($code);
        $changeMsg->setType($type);
        SendMessage::getInstance()->sendClient(PacketId::GC_ChangeClub, $changeMsg);
    }

    public function GCSendChangeNotice(int $code) {
        $changeMsg = new GCChangeNotice();
        $changeMsg->setCode($code);
        SendMessage::getInstance()->sendClient(PacketId::GC_ChangeNotice, $changeMsg);
    }

    public function GCSendReplaceMaster(int $code) {
        $changeMsg = new GCReplaceClubMaster();
        $changeMsg->setCode($code);
        SendMessage::getInstance()->sendClient(PacketId::GC_ReplaceClubMaster, $changeMsg);
    }

    public function GCSendChangeTags(int $code) {
        $changeMsg = new GCChangeTag();
        $changeMsg->setCode($code);
        SendMessage::getInstance()->sendClient(PacketId::GC_ChangeTag, $changeMsg);
    }

    //
    public function clubPlayerMessage($playerId, $serverId)
    {
        /**
         * @var CarModel $carModel
         */
        $carModel = ModelManager::getInstance()->getModel(ModelTypeDefine::CAR);
        $carData = $carModel->getSignData($playerId);

        /**
         * @var CarExteriorRefitModel $carErModel
         */
        $carErModel = ModelManager::getInstance()->getModel(ModelTypeDefine::CAR_EXTERIOR_REFIT);
        $carErData = $carErModel->getSignData($playerId);

        $player = new ClubPlayer();
        $name = $this->getAccountProperty($playerId, AccountData::DB_NICK_NAME);
        $data = $this->getTargetPaiWeiLevel($playerId);
        $line = new ClubPlayerData($playerId, $serverId);
        $line->searchClubPlayer();
        $player->setPost($line->post);
        $player->setContribute($line->contribute);
        $player->setName($name);
        $player->setRankScore($data->score);
        $player->setLevelScore(1);
        $player->setPlayerID($playerId);
        $player->setServerID($serverId);
        $state = $this->getRoleStatus($playerId);
        $player->setState($state);
        $player->setCars(json_encode($carData));
        $player->setCarExteriorRefits(json_encode($carErData));
        $player->setActive($line->active);
        $player->setActiveBattlePass($line->activeBattlePass);
        $player->setActiveTotal($line->activeTotal);
        $player->setBattlePassMoney($line->clubMoney);
        $player->setDailyDonateFlag($line->dailyDonateFlag);
        /**
         * @var AccountModel $account
         */
        $account = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $account->setPlayerId($playerId);
        $rInfo = $account->getAccountAttr([AccountData::DB_LOGOUT_TIME]);
        $player->setStateTime($rInfo[AccountData::DB_LOGOUT_TIME]);
        return $player;
    }

    public function GCGetClubInfo(int $code, ClubData $c = null) {
        $this->clubInfoMsg->setCode($code);
        if(!is_null($c)) {
            $clubInfo = new ClubInfo();
            // 查询队长名称
            $account = $this->getAccountProperty($this->playerId, AccountData::DB_NICK_NAME);
            // 查询俱乐部所有成员 返回给client
            $players = [];
            $haveImpeach = false;
            if(!empty($c->impeachData)) {
                $haveImpeach = true;
            }
            foreach ($c->playerInfo as $id => $item) {
                $player = $this->clubPlayerMessage($id, $item[ClubData::SERVER_ID]);
                array_push($players, $player);
            }
            $joinApply = [];
            if(!empty($c->joinApply)) {
                foreach ($c->joinApply as $item) {
                    $line = new JoinApplyStruct();
                    $name = $this->getAccountProperty($item[ClubData::REQUEST_ID], AccountData::DB_NICK_NAME);
                    $level = $this->getAccountProperty($item[ClubData::REQUEST_ID], AccountData::DB_LEVEL);
                    $data = $this->getTargetPaiWeiLevel($item[ClubData::REQUEST_ID]);

                    $state = $this->getRoleStatus($item[ClubData::REQUEST_ID]);
                    /**
                     * @var AccountModel $account
                     */
                    $account = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
                    $account->setPlayerId($item[ClubData::REQUEST_ID]);
                    $rInfo = $account->getAccountAttr([AccountData::DB_LOGOUT_TIME]);

                    $line->setName($name);
                    $line->setScore($data->score);
                    $line->setLevel($level);
                    $line->setState($state);
                    $line->setStateTime($rInfo[AccountData::DB_LOGOUT_TIME]);
                    $line->setTime($item[ClubData::REQUEST_TIME]);
                    $line->setPlayerID($item[ClubData::REQUEST_ID]);
                    $line->setServerID($item[ClubData::REQUEST_SERVER_ID]);
                    array_push($joinApply, $line);
                }
            }
            $clubInfo->setClubID($c->clubID)->setClubName($c->clubName)->setClubMaster($account)
                ->setImage($c->image)->setBgImage($c->bgImage)->setLevelScore($c->levelScore)
                ->setClubNotice($c->clubNotice)->setLevelLimit($c->levelLimit)->setRankdLimit($c->rankLimit)
                ->setJoinState($c->joinState)->setCreateTime($c->createTime)->setClubTags($c->clubTags)
                ->setJoinApply($joinApply)->setPlayers($players)->setLevelScore($c->levelScore)
                ->setHaveImpeach($haveImpeach);
            $this->clubInfoMsg->setData($clubInfo);
        }
    }

    public function GCSendGetClubInfo() {
        if(!empty($this->clubInfoMsg)) {
            SendMessage::getInstance()->sendClient(PacketId::GC_ClubInfo, $this->clubInfoMsg);
        }
    }

    public function GCSendSearchClub(int $code, ClubData $c1 = null, ClubData $c2 = null) {
        $searchMsg = new GCSearchClubFuzzy();
        $clubs = [];
        if(!is_null($c1)) {
            array_push($clubs, $c1);
        }
        if(!is_null($c2)) {
            array_push($clubs, $c2);
        }
        $clubsArr = [];
        if(!empty($clubs)) {
            foreach ($clubs as $item) {
                if ($item->clubMaster == 0){
                    continue;
                }
                $line = new Club();
                // 查询队长名称
                $account = $this->getAccountProperty($item->clubMaster, AccountData::DB_NICK_NAME);

                $players = [];
                foreach($item->playerInfo as $id=>$v) {
                    array_push($players, $id);
                }
                // 查询俱乐部所有成员 返回给client
                $line->setClubID($item->clubID)->setClubName($item->clubName)->setClubMaster($account)
                    ->setImage($item->image)->setBgImage($item->bgImage)->setLevelScore($item->levelScore)
                    ->setClubNotice($item->clubNotice)->setLevelLimit($item->levelLimit)
                    ->setRankdLimit($item->rankLimit)->setJoinState($item->joinState)->setCreateTime($item->createTime)
                    ->setClubTags($item->clubTags)
                    ->setPlayers($players);
                array_push($clubsArr, $line);
            }
        }
        $searchMsg->setCode($code);
        $searchMsg->setClubs($clubsArr);
        SendMessage::getInstance()->sendClient(PacketId::GC_SearchClubFuzzy, $searchMsg);
    }

    public function GCSendReqJoin(int $code) {
        $reqMsg = new GCRequestJoinClub();
        $reqMsg->setCode($code);
        SendMessage::getInstance()->sendClient(PacketId::GC_RequestJoinClub, $reqMsg);
    }

    public function GCSendChangePlayerPost(int $code) {
        $changeMsg = new GCChangePost();
        $changeMsg->setCode($code);
        SendMessage::getInstance()->sendClient(PacketId::GC_ChangePost, $changeMsg);
    }

    public function GCSendApprovalJoin(int $code, $pass, $serverId, $playerId = null) {
        if (is_null($playerId)){
            $playerId = $this->playerId;
        }
        $clubPlayer = new ClubPlayerData($playerId, $serverId);
        $clubPlayer->searchClubPlayer($playerId);

        $sendMsg = new GCApprovalJoin();
        $sendMsg->setCode($code);
        $sendMsg->setPass($pass);
        $sendMsg->setPost((int)$clubPlayer->post);
        $sendMsg->setClubID((int)$clubPlayer->clubID);
        if ($playerId == $this->playerId){
            SendMessage::getInstance()->sendClient(PacketId::GC_ApprovalJoin,  $sendMsg);
        }else{
            $this->addPacket(PacketId::GC_ApprovalJoin,  $sendMsg, $playerId);
        }
    }

    public function GCUpdateClubPlayer(int $playerId, int $status, ClubPlayer $clubPlayer)
    {
        $sendMessage = new GCUpdateClubPlayer();
        $sendMessage->setInfo($clubPlayer);
        $sendMessage->setStatus($status);
        $this->addPacket(PacketId::GC_UpdateClubPlayer, $sendMessage, $playerId);
    }

    public function GCSendDelClubMember(int $code) {
        $sendMsg = new GCDelClubMember();
        $sendMsg->setCode($code);
        SendMessage::getInstance()->sendClient(PacketId::GC_DelClubMember, $sendMsg);
    }

    public function GCAddDelClubMember(int $code, $playerID) {
        $sendMsg = new GCDelClubMember();
        $sendMsg->setCode($code);
        $this->addPacket(PacketId::GC_DelClubMember,  $sendMsg, $playerID);
    }

    public function GCSendExitClub(int $code) {
        $sendMsg = new GCExitClub();
        $sendMsg->setCode($code);
        SendMessage::getInstance()->sendClient(PacketId::GC_ExitClub, $sendMsg);
    }

    public function GCSendDisbandClub(int $code) {
        $sendMsg = new GCDisbandClub();
        $sendMsg->setCode($code);
        SendMessage::getInstance()->sendClient(PacketId::GC_DisbandClub, $sendMsg);
    }

    public function GCSendFindMyClubID(int $code, int $clubID = 0) {
        $sendMsg = new GCFindMyClubID();
        $sendMsg->setCode($code);
        $sendMsg->setClubID($clubID);
        SendMessage::getInstance()->sendClient(PacketId::GC_FindMyClubID, $sendMsg);
    }

    public function GCSendClearApplyJoin(int $code) {
        $sendMsg = new GCApplyJoinClear();
        $sendMsg->setCode($code);
        SendMessage::getInstance()->sendClient(PacketId::GC_ApplyJoinClear, $sendMsg);
    }

    public function GCSendImpeachMaster(int $code, string $subName = "", string $masterName = "") {
        $sendMsg = new GCImpeachMaster();
        $sendMsg->setCode($code);
        $sendMsg->setSubmitName($subName);
        $sendMsg->setMasterName($masterName);
        $sendMsg->setSubmitTime(Utils::getServerTimestamp());
        SendMessage::getInstance()->sendClient(PacketId::GC_ImpeachMaster, $sendMsg);
    }

    public function GCAddSendImpeachMaster(int $id, int $code, string $subName, string $masterName) {
        $sendMsg = new GCImpeachMaster();
        $sendMsg->setCode($code);
        $sendMsg->setSubmitName($subName);
        $sendMsg->setMasterName($masterName);
        $sendMsg->setSubmitTime(Utils::getServerTimestamp());
        $this->addPacket(PacketId::GC_ImpeachMaster,  $sendMsg, $id);
    }

    public function GCAddSendImpeachRes(int $id, bool $pass, string $subName, string $masterName) {
        $sendMsg = new GCImpeachResMsg();
        $sendMsg->setPass($pass);
        $sendMsg->setSubmitName($subName);
        $sendMsg->setMasterName($masterName);
        $sendMsg->setExecTime(Utils::getServerTimestamp());
        $this->addPacket(PacketId::GC_ImpeachResMsg,  $sendMsg, $id);
    }

}