<?php
/**
 * 自定义房间数据类
 */
namespace Game\Data;

use Framework\Lib\Utils;
use Framework\Log\LogMark;
use Game\Constant\DBTableDefine;
use Framework\DB\Handler\PlayerDBHandler;
use Game\Constant\GameErrorCode;
use Game\Model\RoomCustomizeModel;

class RoomCustomizeData extends RoomData {
    use PlayerDBHandler;

    // customize room field
    public const HAVE_PASSWORD = "HavePassword";
    public const PASSWORD    = "Password";
    public const AI          = "AI";
    public const IS_SHOW_PWD = "IsShowPwd";

    // 玩家信息
    public const TEAM = "Team";    // 属于哪个队伍 在第几个位置
    public const ROLE = "Role";    // 角色 1 房间中 2 观战

    public const DB_CUSTOMIZE_MAP = array(
        self::PASSWORD    => "password",
        self::HAVE_PASSWORD => 'havePassword',
        self::AI          => "ai",
        self::IS_SHOW_PWD => 'isShowPwd',
    );

    public bool   $havePassword;    // 密码
    public string   $password;    // 密码
    public bool   $ai;          // 是否使用AI
    public int    $team;        // 玩家属于哪个战队  23: 第二分队 第三个位置
    public int    $role;        // 角色
    public bool    $isShowPwd;        // 角色

    public function __construct(
        int $roomID, int $playerID = 0, string $roomName = '', int $roomState = 1, int $mapID = 0, int $modeType = 0
        , array $playerInfo = [], int $playType = 1, bool $havePassword = false,  string $password
        = "", bool $ai = true, bool $isShowPwd = true
    ) {
        parent::__construct($roomID, $playerID, $roomName, $roomState, $mapID, $modeType, $playerInfo, $playType);
        $this->havePassword = $havePassword;
        $this->password  = $password;
        $this->ai = $ai;
        $this->isShowPwd = $isShowPwd;
    }

    // 创建自定义房间
    public function createCustomizeRoomDB(int $playerID, int $carTplID, int $timeOut): ?int {
        // {私密/公开} 2/1      1/0 {是/否练图} {是否游戏中} {是否加密} {是否 单人/团队}  {是否准备中}  {是否不加密}
        $score = 2100010;
        $data = [
            'roomID' => (int)$this->roomID,           // 1
            'roomName' => $this->roomName,            // 2
            'mapID' => (int)$this->mapID,             // 3
            'modeType' => (int)$this->modeType,       // 4
            'playerID' => $playerID,                  // 5
            'carTplID' => $carTplID,                  // 6
            'time' => Utils::getServerTimestamp(),                         // 7
            'score' => $score,                        // 8
            'password' => $this->password,            // 9
            'havePassword' => $this->password,        // 10
            'ai' => $this->ai,                        // 11
            'exteriorRefit' => $this->playerInfo[$this->playerID][self::EXTERIOR_REFIT],   // 12
            'proficiency' => $this->playerInfo[$this->playerID][self::PROFICIENCY],        // 13
            'proficiencyLv' => $this->playerInfo[$this->playerID][self::PROFICIENCY_LV],   // 14
            'gender' => $this->playerInfo[$this->playerID][self::GENDER],                  // 15
            'cloth' => $this->playerInfo[$this->playerID][self::CLOTH],                    // 16
            'head' => $this->playerInfo[$this->playerID][self::HEAD],                      // 17
            'nickName' => $this->playerInfo[$this->playerID][self::NICK_NAME],             // 18
            'team' => $this->playerInfo[$this->playerID][self::TEAM],                      // 19
            'TimeOut' => Utils::getServerTimestamp() + $timeOut,                           // 20
            'carLv' => $this->playerInfo[$this->playerID][self::CAR_LV],                   // 21
            'ChatID' => $this->chatID,                   // 22
        ];
        return $this->createCustomizeRoom(DBTableDefine::TABLE_ROOM_CUSTOMIZE, 0, 0, $data);
    }

    // 加入房间
    public function joinCustomizeRoomDB(int $maxNum, int $playerID, array $showPlayer, array $showCar, int $team, int
    $roomID, int $role, int $timeOut)
    : ?int {
        $data = [
            'maxNum' => $maxNum,                                  // 1
            'playerID' => $playerID,                              // 2
            'carTplID' => $showPlayer[self::CAR_TPL_ID],          // 3
            'time' => Utils::getServerTimestamp() + $timeOut,                          // 4
            'exteriorRefit' => $showCar[self::EXTERIOR_REFIT],    // 5
            'proficiency' => $showCar[self::PROFICIENCY],         // 6
            'proficiencyLv' => $showCar[self::PROFICIENCY_LV],    // 7
            'gender' => $showPlayer[self::GENDER],                // 8
            'cloth' => $showPlayer[self::CLOTH],                  // 9
            'head' => $showPlayer[self::HEAD],                    // 10
            'nickName' => $showPlayer[self::NICK_NAME],           // 11
            'team' => $team,                                      // 12
            'roomID' => $roomID,                                  // 13
            'role' => $role,                                      // 14
            'timeOut' => Utils::getServerTimestamp() + $timeOut,                       // 15
            'carLv' => $showCar[self::CAR_LV],                      // 16
        ];

        return $this->joinCustomizeRoom(DBTableDefine::TABLE_ROOM_CUSTOMIZE, 0, 0, $data);
    }

    // 加入房间
    public function joinWatchCustomizeRoomDB(int $playerID, int $roomID, int $role, int $num, int $timeOut)
    : ?int {
        $data = [
            'maxNum' => $num,                                     // 1
            'playerID' => $playerID,                              // 2
            'carTplID' => 0,                                      // 3
            'time' => Utils::getServerTimestamp(),                                     // 4
            'exteriorRefit' => "",                                // 5
            'proficiency' => 0,                                   // 6
            'proficiencyLv' => 0,                                 // 7
            'gender' => 0,                                        // 8
            'cloth' => "{}",                                      // 9
            'head' => 0,                                          // 10
            'nickName' => "",                                     // 11
            'team' => 0,                                          // 12
            'roomID' => $roomID,                                  // 13
            'role' => $role,                                      // 14
            'timeOut' => Utils::getServerTimestamp() + $timeOut,                       // 15
            'carLv' => 0,                       // 16
        ];

        return $this->joinCustomizeRoom(DBTableDefine::TABLE_ROOM_CUSTOMIZE, 0, 0, $data);
    }
    // 退出房间
    public function exitCustomizeRoomDB(int $roomID, int $eID, $role): ?int {

        $data = [
            'roomID' => $roomID,
            'exitID' => $eID,
            'role'   => $role,
        ];

        return $this->exitCustomizeRoom(DBTableDefine::TABLE_ROOM_CUSTOMIZE, 0, 0, $data);
    }


    // 保存房间信息
    public function saveDB(): bool
    {
        $data = array();
        foreach (self::DB_KEY_MAP as $k => $v) {
            if($k == self::PLAYER_INFO) {
                $data[$k] = json_encode($this->$v);
            } else {
                $data[$k] = $this->$v;
            }
        }

        foreach (self::DB_CUSTOMIZE_MAP as $k => $v) {
            $data[$k] = $this->$v;
        }

        if(!$this->updateCRoomTitle(DBTableDefine::TABLE_ROOM_CUSTOMIZE, 0, 0, $data)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[data] customize room update error!', $data
            );
            return false;
        }

        // {私密/公开} 2/1      1/0 {是/否练图} {是否游戏中} {是否加密} {是否 单人/团队}  {是否准备中}  {是否不加密}
        $this->roomState === RoomCustomizeModel::ROOM_STATE_PUBLIC ? $s1 = 1 * 1000000 : $s1 = 2 * 1000000;
        $this->modeType === RoomCustomizeModel::CUSTOMIZE_3 ? $s2 = 1 * 100000 : $s2 = 0;
        $this->playType === RoomCustomizeModel::ROOM_GAME_READY ? $s3 = 0 : $s3 = 1 * 10000;
        $this->havePassword ? $s4 = 1 * 1000 : $s4 = 0;
        $this->modeType === RoomCustomizeModel::CUSTOMIZE_3 ? $s5 = 0 : $s5 = 1 * 100;
        $this->playType === RoomCustomizeModel::ROOM_GAME_READY ? $s6 = 1 * 10 : $s6 = 0;
        $this->havePassword ? $s7 = 0 : $s7 = 1;

        $score = $s1 + $s2 + $s3 + $s4 + $s5 + $s6 + $s7;

        if(!$this->addRank(DBTableDefine::TABLE_ROOM_CUSTOMIZE, 0, $this->roomID, $score)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_UPDATE_ERROR,
                '[data] room customize update z set error!', $data
            );
            return false;
        }
        return true;
    }

    // 查找房间
    public function searchRoomByRoomID(): bool {
        $room = [];
        if(!$this->searchCRoomTitle(DBTableDefine::TABLE_ROOM_CUSTOMIZE, 0, 0, $this->roomID, $room)) {
            return false;
        }

        if(empty($room) || count($room) <= 8) {
            return false;
        }
        $this->setRoomName($room[self::ROOM_NAME]);
        $this->setRoomState($room[self::ROOM_STATE]);
        $this->setMapID($room[self::MAP_ID]);
        $this->setModeType($room[self::MODE_TYPE]);
        $this->setPlayType($room[self::PLAY_TYPE]);
        $this->setAI($room[self::AI]);
        $this->setPassword($room[self::PASSWORD]);
        $this->setHavePassword($room[self::HAVE_PASSWORD]);
        $this->setRoomPlayerInfo($room[self::PLAYER_INFO]);
        $this->setIsShowPwd($room[self::IS_SHOW_PWD]);
        if (isset($room[self::CHAT_ID])) {
            $this->setChatID($room[self::CHAT_ID]);
        } else {
            $this->setChatID("");
        }
        if (isset($room[self::INVITED_INFO1])) {
            $this->setInvitedInfo($room[self::INVITED_INFO1], $room[self::INVITED_INFO2]);
        } else {
            $this->setInvitedInfo("[]", "[]");
        }
        return true;
    }

    public function setPassword(string $passward): void {
        $this->password = $passward;
    }

    public function setAI(bool $ai): void {
        $this->ai = $ai;
    }

    public function setHavePassword(bool $havePassword): void {
        $this->havePassword = $havePassword;
    }

    public function setIsShowPwd(bool $isShowPwd): void {
        $this->isShowPwd = $isShowPwd;
    }

    public function setPlayerTeam(array &$player, int $team) {
        $player[self::TEAM] = $team;
    }
}