<?php

/**
 * GM获取/修改赛车熟练度
 */

namespace Game\Controller\Gm;

use Framework\Define\ErrorDefine;
use Framework\Lib\Utils;
use Framework\MVC\ControllerBase;
use Framework\MVC\ModelManager;
use Framework\Network\SendServiceMsg;
use Game\Constant\TemplateDefine;
use Game\Data\Car\CarData;
use Game\Logic\AccountLogic;
use Game\Logic\CarLogic;
use Game\Logic\ProficiencyLogic;
use Game\Protobuf\CarGMData;
use Game\Protobuf\GMCarProficiency;
use Game\Protobuf\MGCarProficiency;
use Game\Protobuf\PacketId;
use Gm\Config\ErrorCode;

class CarProficiency extends ControllerBase
{
    use AccountLogic;
    use CarLogic;
    use ProficiencyLogic;

    private GMCarProficiency $sendMessage;

    private const TYPE_OPTION_SEARCH = 1;   //查询
    private const TYPE_OPTION_UPDATE = 2;   //修改

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

    public function run(): int
    {
        $account = $this->message->getAccount();
        $carId = $this->message->getCarId();
        $lv = $this->message->getProficiencyLv();
        $exp = $this->message->getProficiency();
        //检查校验
        if(empty($account)) {
            return $this->sendFailMessage(ErrorCode::ERROR_ACCOUNT_NOT_FOUND);
        }
        $playerId = $this->searchPlayerIdByNickName($account);
        if ($playerId == 0) {
            return $this->sendFailMessage(ErrorCode::ERROR_ACCOUNT_NOT_FOUND);
        }
        ModelManager::getInstance()->clearModelList();
        ModelManager::getInstance()->setPlayerId($playerId);
        //查车
        $car = $this->searchCarDataByCarID($carId);
        if (is_null($car)) {
            return $this->sendFailMessage(ErrorCode::CAR_NOT_FOUND);
        }
        if ($this->message->getOption() == self::TYPE_OPTION_SEARCH) {
            //查询熟练度
            return $this->sendSuccessMessage($car);
        }
        /**
         * @var CarData $car
         */
        if ($car->expire != 0) {
            return $this->sendFailMessage(ErrorCode::CAR_NOT_FOREVER);
        }
        //检查熟练度
        if ($lv < 0 || $car->proficiencyLv > $lv || $exp < 0) {
            return $this->sendFailMessage(ErrorCode::CAR_PROFICIENCY_CAN_NOT_SUB);
        }
        $configData = $this->getTitle(TemplateDefine::TYPE_PROFICIENCY_CAR, $car->carID);
        if (is_null($configData)) {
            return $this->sendFailMessage(ErrorCode::CAR_PROFICIENCY_OVER_MAX);
        }
        $maxLv = count($configData);
        if ($lv > $maxLv) {
            return $this->sendFailMessage(ErrorCode::CAR_PROFICIENCY_OVER_MAX);
        }
        //修改熟练度
        $this->gmAddCarProficiency($car, $lv, $exp);
        return $this->sendSuccessMessage($car, true);
    }

    private function sendFailMessage(int $code): int
    {
        $this->sendMessage->setCode($code);
        SendServiceMsg::getInstance()->sendServiceMsg(
            PacketId::GM_CarProficiency,
            $this->sendServer,
            $this->sendMessage,
            0,
            Utils::getServerTimestamp()
        );
        return ErrorDefine::SUCCESS;
    }

    private function sendSuccessMessage(CarData $car, $reSearch = false): int
    {
        if ($reSearch) {
            $car = $this->searchCarDataByCarID($car->carID);
        }
        $carGmData = new CarGMData();
        $carGmData->setCarId($car->carID);
        $carGmData->setProficiencyLv($car->proficiencyLv);
        $carGmData->setProficiency($car->proficiency);
        $this->sendMessage->setCode(ErrorCode::SUCCESS);
        $this->sendMessage->setCar($carGmData);
        SendServiceMsg::getInstance()->sendServiceMsg(
            PacketId::GM_CarProficiency,
            $this->sendServer,
            $this->sendMessage,
            0,
            Utils::getServerTimestamp()
        );
        return ErrorDefine::SUCCESS;
    }
}
