<?php
/**
 * 万能改装卡兑换车改装
 * @date 2022-8-14
 * @author leeFx
 **/
namespace Game\Controller\Car;

use Framework\Define\ErrorDefine;
use Framework\Log\LogMark;
use Framework\MVC\ControllerBase;
use Framework\MVC\ModelManager;
use Framework\Network\SendMessage;
use Game\Constant\CarExteriorRefitDefine;
use Game\Constant\ClientErrorCode;
use Game\Constant\ConstTemplate\TemplateAppearance;
use Game\Constant\ConstTemplate\TemplateRefit;
use Game\Constant\GameErrorCode;
use Game\Constant\ModelTypeDefine;
use Game\Constant\TemplateDefine;
use Game\Data\CarExteriorRefitData;
use Game\Logic\CarExteriorRefitLogic;
use Game\Logic\ItemLogic;
use Game\Model\Car\CarExteriorRefitModel;
use Game\Protobuf\CGRefitItemBindCar;
use Game\Protobuf\GCRefitItemBindCar;
use Game\Protobuf\PacketId;

class RefitItemBindCar extends ControllerBase
{
    use ItemLogic;
    use CarExteriorRefitLogic;

    public GCRefitItemBindCar $sendMessage;

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

    public function run(): int
    {
        $carTplID = $this->message->getCarTplID();
        $refitItemID = $this->message->getRefitItemID();
        $refitID = $this->message->getRefitID();

        // 万能改装道具是否足够
        $itemNum = $this->getItemNumByTplID($refitItemID);
        if($itemNum < 1) {
            $this->sendMessage->setCode(ClientErrorCode::ERROR_REFIT_ITEM_NUM_NOT_ENOUGH);
            SendMessage::getInstance()->sendClient(PacketId::GC_RefitItemBindCar, $this->sendMessage);
            return ErrorDefine::SUCCESS;
        }
        $AppConfig = $this->getTitle(TemplateDefine::TYPE_APPEARANCE, $refitID);

        // 万能改装道具是否可以转换为改装件
        if($AppConfig[TemplateAppearance::IDUniversal] !== $refitItemID) {
            $this->sendMessage->setCode(ClientErrorCode::ERROR_REFIT_ITEM_NOT_EXCHANGE);
            SendMessage::getInstance()->sendClient(PacketId::GC_RefitItemBindCar, $this->sendMessage);
            return ErrorDefine::SUCCESS;
        }

        // 判断车是否可以使用改装件
        $arr = $this->getTitle(TemplateDefine::TYPE_REFIT, $carTplID)
        [CarExteriorRefitDefine::DB_REFIT_CHECK_MAP[$AppConfig[TemplateAppearance::Type]]];
        if(empty($arr) || !in_array($refitID, $arr)) {
            $this->sendMessage->setCode(ClientErrorCode::ERROR_CAR_NOT_REFIT);
            SendMessage::getInstance()->sendClient(PacketId::GC_RefitItemBindCar, $this->sendMessage);
            return ErrorDefine::SUCCESS;
        }

        // 判断车是否已经有了此改装件
        if($this->checkRefitIsRepeated($carTplID, $refitID)) {
            $this->sendMessage->setCode(ClientErrorCode::ERROR_REFIT_REPEATED);
            SendMessage::getInstance()->sendClient(PacketId::GC_RefitItemBindCar, $this->sendMessage);
            return ErrorDefine::SUCCESS;
        }

        // 消耗道具
        if(!$this->subItemByTID($refitItemID, 1)) {
            logMark::getInstance()->markError(
                GameErrorCode::ITEM_SUB_FAILED,
                '[refit item bind car] sub refit item error!',
            );
            $this->sendMessage->setCode(ClientErrorCode::ERROR_REFIT_ERROR);
            SendMessage::getInstance()->sendClient(PacketId::GC_RefitItemBindCar, $this->sendMessage);
            return ErrorDefine::SUCCESS;
        }

        // 生成改装件
        if(!$this->createExteriorRefitData($carTplID, $refitID)) {
            logMark::getInstance()->markError(
                GameErrorCode::DATA_CREATE_ERROR,
                '[refit item bind car] create refit error!',
            );
            $this->sendMessage->setCode(ClientErrorCode::ERROR_REFIT_ERROR);
            SendMessage::getInstance()->sendClient(PacketId::GC_RefitItemBindCar, $this->sendMessage);
            return ErrorDefine::SUCCESS;
        }
        return ErrorDefine::SUCCESS;
    }

    private function checkRefitIsRepeated(int $carID, int $refitID):bool {
        /**
         * @var CarExteriorRefitModel $refitModel
         */
        $refitModel = ModelManager::getInstance()->getModel(ModelTypeDefine::CAR_EXTERIOR_REFIT);
        $refits = $refitModel->getPlayerExteriorRefits();
        if(empty($refits)) {
            return false;
        }
        /**
         * @var CarExteriorRefitData $item
         */
        foreach ($refits as $item) {
            if($item->carID === $carID && $item->tplID === $refitID) {
                return true;
            }
        }
        return false;
    }
}