<?php
/**
 * 俱乐部数据类
 * cluster commonDBHandler
 */
namespace Game\Data\Club;

use Framework\Log\LogMark;
use Framework\DB\Handler\CommonDBHandler;
use Framework\Logic\TemplateHelp;
use Game\Config\GameConfig;
use Game\Constant\ConstTemplate\TemplateClubLevel;
use Game\Constant\DBTableDefine;
use Game\Constant\GameErrorCode;
use Game\Constant\TemplateDefine;

class ClubData {
    use CommonDBHandler;
    use TemplateHelp;

    public const LIST_SIZE = 20;

    public const CLUB_ID     = "ClubID";
    public const CLUB_NAME   = "ClubName";
    public const CLUB_MASTER = "ClubMaster";
    public const IMAGE       = "Image";
    public const BG_IMAGE    = "BgImage";
    public const PLAYER_INFO = "PlayerInfo";
    public const PLAYER_CARS = "PlayerCars";
    public const LEVEL = "Level";
    public const LEVEL_SCORE = "LevelScore";
    public const CLUB_NOTICE = "ClubNotice";
    public const CLUB_TAGS   = "ClubTags";
    public const LEVEL_LIMIT = "LevelLimit";
    public const RANK_LIMIT  = "RankLimit";
    public const JOIN_STATE  = "JoinState";
    public const JOIN_APPLY  = "JoinApply";
    public const CREATE_TIME = "CreateTime";
    public const IMPEACH_DATA = "ImpeachData";  // 弹劾信息
    public const DONATE = "Donate";  //捐献

    // 俱乐部成员信息
    public const PLAYER_ID = "playerID";
    public const SERVER_ID = "serverID";

    // 请求列表
    public const REQUEST_ID   = "RequestID";
    public const REQUEST_TIME = "RequestTime";
    public const REQUEST_SERVER_ID = "RequestServerID";

    // 弹劾
    public const ID = "PlayerID";  // 发起者id
    public const SID = "ServerID";  // 发起者服务器id
    public const TIME = "Time";  // 发起时间

    public const DB_KEY_MAP = array(
        self::CLUB_ID     => "clubID",
        self::CLUB_NAME   => "clubName",
        self::CLUB_MASTER => "clubMaster",
        self::IMAGE       => "image",
        self::BG_IMAGE    => "bgImage",
        self::PLAYER_INFO => "playerInfo",
        self::PLAYER_CARS => "playerCars",
        self::LEVEL       => "level",
        self::LEVEL_SCORE => "levelScore",
        self::CLUB_NOTICE => "clubNotice",
        self::CLUB_TAGS   => "clubTags",
        self::LEVEL_LIMIT => "levelLimit",
        self::RANK_LIMIT  => "rankLimit",
        self::JOIN_STATE  => "joinState",
        self::JOIN_APPLY  => "joinApply",
        self::CREATE_TIME => "createTime",
        self::IMPEACH_DATA => "impeachData",
        self::DONATE      => "donate",
    );

    public int    $playerID = 0;
    public int    $clubID;
    public string $clubName;
    public int    $clubMaster;
    public int    $image;
    public int    $bgImage;
    public array  $playerInfo; // 玩家ids
    public array  $playerCars; // 俱乐部车
    public int    $level;  // 等级
    public int    $levelScore; // 等级经验积分
    public string $clubNotice; // 俱乐部通告
    public array  $clubTags;   // 标签组
    public int    $levelLimit; // 等级限制
    public int    $rankLimit;  // 段位限制
    public int    $joinState;  // 加入限制  1：无需审核 2：审核 3：不可加入
    public array  $joinApply;  // 申请列表
    public int    $createTime;
    public array  $impeachData; // 弹劾数据
    public int    $donate;     //捐献值


    public function __construct(
        int $clubID = 0, string $clubName = '', int $image = 0, int $bgImage = 0, int $clubMaster = 0
        , int $createTime = 0, array $playerInfo = [], array $playerCars = [], int $levelScore = 0,
        string $clubNotice = '', array $clubTags = [], int $levelLimit = 0, int $rankLimit = 0, int $joinState = 1
        , array $joinApply = [], array $impeachData = [], int $level = 1, int $donate = 0
    ) {
        $this->clubID      = $clubID;
        $this->clubName    = $clubName;
        $this->clubMaster  = $clubMaster;
        $this->image       = $image;
        $this->bgImage     = $bgImage;
        $this->playerInfo  = $playerInfo;
        $this->playerCars  = $playerCars;
        $this->levelScore  = $levelScore;
        $this->clubNotice  = $clubNotice;
        $this->clubTags    = $clubTags;
        $this->levelLimit  = $levelLimit;
        $this->rankLimit   = $rankLimit;
        $this->joinState   = $joinState;
        $this->joinApply   = $joinApply;
        $this->createTime  = $createTime;
        $this->impeachData = $impeachData;
        $this->level = $level;
        $this->donate = $donate;
    }

    public function CreateClubData(int $playerID, int $serverID): bool {
        $data = array();
        foreach (self::DB_KEY_MAP as $k => $v) {
            if(in_array($k, [self::PLAYER_CARS, self::CLUB_TAGS, self::JOIN_APPLY, self::IMPEACH_DATA])) {
                $data[$k] = json_encode($this->$v);
            } elseif ($k == self::PLAYER_INFO) {
                $data[$k] = json_encode([
                    $playerID => [
                        self::PLAYER_ID => $playerID,
                        self::SERVER_ID => $serverID,
                    ]
                ]);
            } else {
                $data[$k] = $this->$v;
            }
        }
        if(!$this->updateFullServerClusterTitle(DBTableDefine::TABLE_CLUB, $this->clubID, $data)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_CREATE_ERROR,
                '[data] club data create error!', $data
            );
            return false;
        }
        return true;
    }

    public function saveDB(): bool
    {
        $data = array();
        foreach (self::DB_KEY_MAP as $k => $v) {
            if(in_array($k, [self::PLAYER_INFO, self::PLAYER_CARS, self::CLUB_TAGS,
                self::JOIN_APPLY, self::IMPEACH_DATA])) {
                $data[$k] = json_encode($this->$v);
            } else {
                $data[$k] = $this->$v;
            }
        }

        if(!$this->updateFullServerClusterTitle(DBTableDefine::TABLE_CLUB, $this->clubID, $data)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[data] club data update error!', $data
            );
            return false;
        }
        return true;
    }

    public function delClubDB(): bool
    {
        if(!$this->deleteCommTitle(DBTableDefine::TABLE_CLUB, $this->clubID)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_DELETE_ERROR,
                '[ClubData] club delete error!',
                ['playerID' => $this->playerID, 'clubID' => $this->clubID]
            );
            return false;
        }
        return true;
    }

    // 查找房间
    public function searchClubByID(): bool {
        $club = [];
        if(!$this->searchFullServerClusterTitle(DBTableDefine::TABLE_CLUB, $this->clubID, $club)) {
            return false;
        }
        if(empty($club)) {
            return false;
        }
        $this->setClubID($club[self::CLUB_ID]);
        $this->setClubName($club[self::CLUB_NAME]);
        $this->setCLubMaster($club[self::CLUB_MASTER]);
        $this->setImage($club[self::IMAGE]);
        $this->setBgImage($club[self::BG_IMAGE]);
        $this->setPlayerInfo($club[self::PLAYER_INFO]);
        $this->setLevelScore($club[self::LEVEL_SCORE]);
        $this->setClubNotice($club[self::CLUB_NOTICE]);
        $this->setClubTags($club[self::CLUB_TAGS]);
        $this->setLevelLimit($club[self::LEVEL_LIMIT]);
        $this->setRankLimit($club[self::RANK_LIMIT]);
        $this->setJoinState($club[self::JOIN_STATE]);
        $this->setJoinApply($club[self::JOIN_APPLY]);
        $this->setCreateTime($club[self::CREATE_TIME]);
        $this->setLevel($club[self::LEVEL]);
        $this->setDonate($club[self::DONATE] ?? 0);
        if(!isset($club[self::IMPEACH_DATA])) {
            $this->setImpeach("[]");
        } else {
            $this->setImpeach($club[self::IMPEACH_DATA]);
        }
        return true;
    }

    public function setClubID(int $clubID) {
        $this->clubID = $clubID;
    }

    public function setClubName(string $clubName) {
        $this->clubName = $clubName;
    }

    public function setCLubMaster(int $id) {
        $this->clubMaster = $id;
    }

    public function setImage(int $image) {
        $this->image = $image;
    }

    public function setBgImage(int $bgImage) {
        $this->bgImage = $bgImage;
    }

    public function setPlayerInfo(string $info) {
        $this->playerInfo = json_decode($info, true);
    }

    public function setLevelScore(int $score) {
        $this->levelScore = $score;
    }

    public function setClubNotice(string $notice) {
        $this->clubNotice = $notice;
    }

    public function setClubTags(string $tags) {
        $this->clubTags = json_decode($tags, true);
    }

    public function setLevelLimit(int $levelLimit) {
        $this->levelLimit = $levelLimit;
    }

    public function setRankLimit(int $rankLimit) {
        $this->rankLimit = $rankLimit;
    }

    public function setJoinState(int $state) {
        $this->joinState = $state;
    }

    public function setJoinApply(string $joins) {
        $this->joinApply = json_decode($joins, true);
    }

    public function setCreateTime(int $time) {
        $this->createTime = $time;
    }

    public function setImpeach(string $impeach) {
        $this->impeachData = json_decode($impeach, true);
    }

    public function setLevel(int $level): void
    {
        $this->level = $level;
    }

    public function setDonate(int $donate): void
    {
        $this->donate = $donate;
    }

    //搜索集合随机列表
    //设置为不显示就从当前的集合中删除
    public function searchRandomList(&$ret): bool
    {
        $this->getSetLen(DBTableDefine::TABLE_CLUB_SEARCH, 0, $len);
        if ($len <= self::LIST_SIZE){
            return $this->searchSetMember(DBTableDefine::TABLE_CLUB_SEARCH, 0, $ret);
        }
        $playerDB = new ClubPlayerData($this->playerID, GameConfig::getInstance()->SERVER_ID());
        if ($len <= self::LIST_SIZE*2){
            if (!$this->searchSetMember(DBTableDefine::TABLE_CLUB_SEARCH, 0, $search)){
                return false;
            }
            $temporary = $playerDB->readTemporaryData();
            $ret = array_diff($search, $temporary);
            if (count($ret) == 0){
                return true;
            }
            shuffle($ret);
            $ret = array_slice($ret, 0, self::LIST_SIZE, true);
            return $playerDB->storageTemporaryData($ret);
        }

        if (!$this->searchSetRandomList(DBTableDefine::TABLE_CLUB, 0, self::LIST_SIZE, $search)){
            return false;
        }

        $temporary = $playerDB->readTemporaryData();
        $ret = array_merge((array)$ret, array_diff($search, $temporary));
        if (count($ret) >= self::LIST_SIZE){
            $ret = array_slice($ret, 0,self::LIST_SIZE, true);
            $playerDB->storageTemporaryData($ret);
            return true;
        }

        return $this->searchRandomList($ret);
    }

    //等级提升增加经验值
    public function levelUpgrade($exp): bool
    {
        if ($exp <= 0 ){
            return false;
        }
        if (!$this->autoAddCommonTerm($nowScore, DBTableDefine::TABLE_CLUB, $this->clubID, self::LEVEL_SCORE, $exp)){
            return false;
        }
        $this->getLevel();
        $tplClubLevel = $this->getTitle(TemplateDefine::TYPE_CLUB_LEVEL, $this->level);
        if (empty($tplClubLevel)){
            return true;
        }
        if ($nowScore > $tplClubLevel[TemplateClubLevel::ClubExpMax]){
            $this->autoAddCommonTerm($ret, DBTableDefine::TABLE_CLUB, $this->clubID, self::LEVEL, 1);
        }
        return true;
    }

    public function updateClubDB(array $attr): bool
    {
        if (!is_array($attr)){
            return false;
        }
        $data = array();
        foreach (self::DB_KEY_MAP as $k => $v) {
            if (!isset($attr[$k])){
                return false;
            }
            $data[$k] = $attr[$k];
        }

        if(!$this->updateFullServerClusterTitle(DBTableDefine::TABLE_CLUB, $this->clubID, $data)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[data] club data update error!', $data
            );
            return false;
        }
        return true;
    }

    //查询当前的等级
    public function  getLevel(): void
    {
        if ($this->searchCommonTerm($level, DBTableDefine::TABLE_CLUB, $this->clubID, self::LEVEL)){
            $this->level = $level;
        }
    }

}