<?php

/**
 * 生成比赛AI
 */

namespace Game\Logic;

use Framework\Define\ErrorDefine;
use Framework\Log\LogMark;
use Framework\MVC\ModelManager;
use Framework\Logic\TemplateHelp;
use Game\Constant\ConstTemplate\TemplateClothing;
use Game\Constant\ConstTemplate\TemplateConst;
use Game\Constant\ConstTemplate\TemplateGenerateAi;
use Game\Constant\ModelTypeDefine;
use Game\Constant\TemplateDefine;
use Game\Data\Car\CarDeepmodData;
use Game\Model\Car\CarModel;
use Game\Protobuf\AIInfo;
use Game\Protobuf\ClothData;

trait GenerateAiLogic
{
    use TemplateHelp;

    private ?array $config = null;
    private ?array $clothConfig = null;

    //检查是否为AI
    public function checkIsAIPlayer(int $playerId): bool
    {
        if ($playerId == 0) {
            return true;
        }
        $AI_MIN = $this->getTerm(TemplateDefine::TYPE_CONST, TemplateConst::Const_AI_PlayerID_Min, TemplateConst::ConstNum);
        $AI_MAX = $this->getTerm(TemplateDefine::TYPE_CONST, TemplateConst::Const_AI_PlayerID_Max, TemplateConst::ConstNum);
        return $playerId >= $AI_MIN && $playerId <= $AI_MAX;
    }

    //生成AI
    public function generateAI(int $aiLevel, int $idx, int $aiTplId, int $position): ?AIInfo
    {
        $this->initAIConfig($aiLevel);
        if (is_null($this->config)) {
            LogMark::getInstance()->markError(
                ErrorDefine::TEMPLATE_CONFIG_NOT_FOUND,
                "[GenerateAiLogic] AiConfig not found",
                array(
                    "id" => $aiLevel
                )
            );
            return null;
        }
        $aiInfo = new AIInfo();
        $aiInfo->setGender($this->getAISex());
        $aiInfo->setPlayerId($this->makeAIPlayerId($aiLevel, $idx, $position));
        $aiInfo->setGroupID(0);
        $aiInfo->setAITplId($aiTplId);
        $aiInfo->setNickName($this->getRandomName());
        $aiInfo->setHead($this->getAIHead());
        $aiInfo->setSkinColor($this->getAISkinColor());
        $aiInfo->setCloth($this->getAICloth($aiInfo->getGender()));
        $aiInfo->setCarTplId($this->getCarId($position));
        $aiInfo->setCarLevel($this->getCarLevel());
        $aiInfo->setExteriorRefit($this->getCarExteriorRefit());
        $aiInfo->setRefit($this->getCarRefit());
        [$proficiencyLv, $proficiency] = $this->getAICarProficiency();
        $aiInfo->setProficiencyLv($proficiencyLv);
        $aiInfo->setProficiency($proficiency);
        $aiInfo->setContinuityWin($this->getContinuityWinNum());
        return $aiInfo;
    }

    //AI配置表
    private function initAIConfig(int $aiLevel)
    {
        $this->config = $this->getTitle(TemplateDefine::TYPE_GENERATE_AI, $aiLevel);
        $this->clothConfig = $this->getTable(TemplateDefine::TYPE_CLOTHING);
    }

    //生成规则 共7位 (AILevel 位置(竞速,辅助,干扰,默认0)) + idx
    public function makeAIPlayerId(int $aiLevel, int $idx, int $position): int
    {
        return (int)("{$aiLevel}{$position}"."00000") + $idx;
    }

    //随机生成AI表Id
    private function getAIId(): int
    {
        return $this->config[TemplateGenerateAi::AIIds][array_rand($this->config[TemplateGenerateAi::AIIds])];
    }

    //生成AI车辆信息
    private function getCarId(int $position): int
    {
        if ($position == 0) {
            return $this->config[TemplateGenerateAi::Car][array_rand($this->config[TemplateGenerateAi::Car])];
        }
        return $this->config[TemplateGenerateAi::CAR_POSITION][$position][array_rand($this->config[TemplateGenerateAi::CAR_POSITION][$position])];
    }

    //生成车辆等级
    private function getCarLevel(): int
    {
        return $this->config[TemplateGenerateAi::CarLevel][array_rand($this->config[TemplateGenerateAi::CarLevel])];
    }

    //生成车辆改装信息
    //TODO:暂时没有
    private function getCarExteriorRefit(): string
    {
        return "[]";
    }

    //生成车辆性能强化信息
    private function getCarRefit(): string
    {
        [$start, $end] = $this->config[TemplateGenerateAi::Strengthen];
        $carDeepModData = array();
        foreach (CarDeepmodData::DB_KEY_MAP as $key => $value) {
            if ($key == CarDeepmodData::DB_RANDOM_ATTR) {
                continue;
            }
            $carDeepModData[$key] = $this->getCarRefitRandomValue($start, $end);
        }
        /**
         * @var CarModel $carModel
         */
        $carModel = ModelManager::getInstance()->getModel(ModelTypeDefine::CAR);
        return $carModel->refitAttr($carDeepModData);
    }

    //随机性能强化值 保留4位
    private function getCarRefitRandomValue(int $start, int $end): string
    {
        $base = 10000;
        return (string)random_int($start * $base, $end * $base) / $base;
    }

    //生成熟练度等级和经验
    //熟练度等级1-25 经验0-100
    private function getAICarProficiency(): array
    {
        return array(random_int(1, 25), random_int(0, 100));
    }

    //----生成AI人物信息----
    //生成AI性别 0女1男
    private function getAISex(): int
    {
        return random_int(0, 1);
    }

    //TODO:头像 暂时都是1
    private function getAIHead(): int
    {
        return 1;
    }

    //随机肤色
    private function getAISkinColor(): int
    {
        return random_int(1, 3);
    }

    //生成AI服装
    private function getAICloth(int $sex): ClothData
    {
        $clothTmp = array();
        foreach ($this->config[TemplateGenerateAi::Dress][$sex] as $part => $clothArr) {
            if (empty($clothArr)) {
                $clothTmp[$part] = 0;
            } else {
                $clothTmp[$part] = $clothArr[array_rand($clothArr)];
            }
        }
        //检查服装互斥部位
        $cloth = $clothTmp;
        foreach ($clothTmp as $clothId) {
            if ($clothId == 0) {
                continue;
            }
            if ($this->clothConfig[$clothId][TemplateClothing::MutuallyExclusiveParts] != 0) {
                $cloth[$this->clothConfig[$clothId][TemplateClothing::MutuallyExclusiveParts] -1] = 0;
            }
        }
        $clothRes = new ClothData();
        $clothRes->setHairId($cloth[0]);
        $clothRes->setFaceId($cloth[1]);
        $clothRes->setUpClothId($cloth[2]);
        $clothRes->setDownClothId($cloth[3]);
        $clothRes->setShoesId($cloth[4]);
        return $clothRes;
    }

    //生成昵称
    private function getRandomName(): string
    {
        $config = $this->getTable(TemplateDefine::TYPE_RANDOM_ID);
        $randIds = array_rand(array_fill(1, count($config[1]), 1), 3);
        return $config[1][$randIds[0]].$config[2][$randIds[1]].$config[3][$randIds[2]];
    }

    //生成AI连胜次数
    private function getContinuityWinNum(): int
    {
        return random_int(0, 3);
    }
}
