<?php

/**
 * pvp匹配相关
 */

namespace Game\Logic\Pvp;

use Exception;
use Framework\Define\ErrorDefine;
use Framework\Log\LogMark;
use Game\Constant\GameErrorCode;
use Game\Data\Activity\ScuffleData;
use Game\Data\RoomData;
use Game\Logic\AccountLogic;
use Game\Logic\CarExteriorRefitLogic;
use Game\Logic\CarLogic;
use Game\Logic\EventConditionLogic;
use Game\Logic\PaiweiLevelLogic;
use Game\Protobuf\CarShow;
use Game\Protobuf\ClothData;
use Game\Protobuf\PlayerShow;
use Game\Data\AccountData;

trait PvpMatchLogic
{
    use AccountLogic;
    use CarLogic;
    use CarExteriorRefitLogic;
    use EventConditionLogic;
    use PaiweiLevelLogic;

    //比赛需要显示玩家信息
    public function getMatchShowPlayer(int $playerId): array
    {
        $player = $this->searchPlayerInfo($playerId);
        if (is_null($player)) {
            LogMark::getInstance()->markDebug(
                "[PvpMatchLogic] player not found",
                array(
                    "playerId" => $playerId
                )
            );
            return array();
        }
        [$gender, $cloth] = $this->getClothProtoData($playerId);
        //查询组队排位位置
        $paiWeiData = $this->getTargetPaiWeiLevel($playerId);
        $position = json_decode($paiWeiData->positionOrder, true)[0];
        return array(
            RoomData::HEAD => $player[AccountData::DB_HEAD],
            RoomData::NICK_NAME => $player[AccountData::DB_NICK_NAME],
            RoomData::GENDER => $gender,
            RoomData::CLOTH => $cloth->serializeToJsonString(),  //protobufJsonString
            RoomData::CAR_TPL_ID => $player[AccountData::DB_DEFAULT_CAT_TPL],
            AccountData::DB_DEFAULT_CAR => $player[AccountData::DB_DEFAULT_CAR],
            RoomData::POSITION => $position,
            RoomData::SCUFFLE_SCORE => $player[ScuffleData::SCUFFLE_SCORE] ?? ScuffleData::DEFAULT_SCORE,
            RoomData::CONTINUITY_WIN => $player[AccountData::DB_CONTINUITY_WIN] ?? 0,
            AccountData::DB_SKIN_COLOR => $player[AccountData::DB_SKIN_COLOR] ?? 1,
            RoomData::PLAYER_LEVEL => $player[AccountData::DB_LEVEL],
            RoomData::PLAYER_DAN => $paiWeiData->levelId,
        );
    }

    //比赛显示车信息
    public function getMatchShowCar(int $carId): array
    {
        $car = $this->searchCarDataByCarID($carId);
        if(is_null($car)) {
            LogMark::getInstance()->markError(
                GameErrorCode::DATA_SEARCH_ERROR,
                '[PvpMatchLogic] search car by carID error!',
                array(
                    "playerId" => $this->playerId,
                    "carId" => $carId
                )
            );
            return array();
        }
        return array(
            RoomData::EXTERIOR_REFIT => $this->getCarExteriorRefitFormatData($car->uid), //外观改装String
            RoomData::PROFICIENCY_LV => $car->proficiencyLv,
            RoomData::PROFICIENCY => $car->proficiency,
            RoomData::CAR_LV => $car->level,
        );
    }

    //生成比赛内玩家显示信息--匹配发送,原样返回
    public function makePlayerShowString(int $playerId, array $data): string
    {
        $playerShow = new PlayerShow();
        $clothData = new ClothData();
        $clothData->mergeFromJsonString($data[RoomData::CLOTH]);
        $playerShow->setGender($data[RoomData::GENDER]);
        $playerShow->setCloth($clothData);
        $playerShow->setHead($data[RoomData::HEAD]);
        $playerShow->setNickName($data[RoomData::NICK_NAME]);
        $playerShow->setScuffleScore($data[RoomData::SCUFFLE_SCORE] ?? 0);
        $playerShow->setContinuityWin($data[RoomData::CONTINUITY_WIN] ?? 0);
        $playerShow->setSkinColor($data[AccountData::DB_SKIN_COLOR] ?? 1);
        $playerShow->setLevel($data[RoomData::PLAYER_LEVEL] ?? 1);
        $playerShow->setDan($data[RoomData::PLAYER_DAN] ?? 1);
        return $playerShow->serializeToJsonString();
    }

    //生成比赛内赛车显示信息--匹配发送,原样返回
    public function makeCarShowString(int $playerId, array $data, int $mapId): string
    {
        $carShow = new CarShow();
        $carShow->setCarTplID($data[RoomData::CAR_TPL_ID]);
        $carShow->setExteriorRefit($data[RoomData::EXTERIOR_REFIT]);
        $carShow->setProficiencyLv($data[RoomData::PROFICIENCY_LV]);
        $carShow->setProficiency($data[RoomData::PROFICIENCY]);
        $carShow->setCarLv($data[RoomData::CAR_LV]);
        return $carShow->serializeToJsonString();
    }

    //解析匹配返回玩家数据
    public function getPlayerShowData(string $playerShowJsonStr): ?PlayerShow
    {
        $playerShow = new PlayerShow();
        try {
            $playerShow->mergeFromJsonString($playerShowJsonStr);
        } catch (Exception $e) {
            LogMark::getInstance()->markError(
                ErrorDefine::ERROR_INTERNAL,
                "[PvpMatchLogic] player show json string error",
                array(
                    "string" => $playerShowJsonStr
                )
            );
            return null;
        }
        return $playerShow;
    }

    //解析匹配返回赛车数据
    public function getCarShowData(string $carShowJsonStr): ?CarShow
    {
        $carShow = new CarShow();
        try {
            $carShow->mergeFromJsonString($carShowJsonStr);
        } catch (Exception $e) {
            LogMark::getInstance()->markError(
                ErrorDefine::ERROR_INTERNAL,
                "[PvpMatchLogic] car show json string error",
                array(
                    "string" => $carShowJsonStr
                )
            );
            return null;
        }
        return $carShow;
    }
}
