<?php

/**
 * 服装
 */

namespace Game\Logic;

use Framework\Log\LogMark;
use Framework\MVC\ModelManager;
use Framework\Network\SendMessage;
use Framework\Logic\TemplateHelp;
use Game\Constant\ClientErrorCode;
use Game\Constant\ConstTemplate\TemplateClothing;
use Game\Constant\ConstTemplate\TemplateCreateRole;
use Game\Constant\GameErrorCode;
use Game\Constant\ModelTypeDefine;
use Game\Constant\TemplateDefine;
use Game\Data\AccountData;
use Game\Model\AccountModel;
use Game\Protobuf\ClothData;
use Game\Protobuf\ClothSaveRecv;
use Game\Protobuf\PacketId;

trait ClothLogic
{
    use TemplateHelp;

    //当前穿戴的服装过期后,恢复为默认服装
    //$clothArray 过期服装id
    public function checkResetPlayerClothOnExpire(int $playerId, array $clothArray)
    {
        if (empty($clothArray)) {
            return;
        }
        [$femaleCloth, $maleCloth] = $this->getPlayerClothArray($playerId);
        $femaleClothIdx = array();
        $maleClothIdx = array();
        foreach ($clothArray as $id) {
            $part = $this->getTerm(TemplateDefine::TYPE_CLOTHING, $id, TemplateClothing::Part);
            if (in_array($id, $femaleCloth)) {
                $femaleClothIdx[$part] = $id;
            }
            if (in_array($id, $maleCloth)) {
                $maleClothIdx[$part] = $id;
            }
        }
        $this->resetPlayerClothByIdx($femaleClothIdx, $maleClothIdx, $femaleCloth, $maleCloth);
    }

    //根据位置重置玩家服装,
    //$femaleClothIdx $maleClothIdx [位置=>服装Id]
    public function resetPlayerClothByIdx(array $femaleClothIdx, array $maleClothIdx, array $femaleCloth, array $maleCloth)
    {
        //没有需要替换的服装
        if (empty($femaleClothIdx) && empty($maleClothIdx)) {
            return;
        }
        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $roleModelId = $accountModel->getAccountAttr(AccountData::DB_ROLE_MODEL_ID);
        //替换服装
        $configInitData = $this->getTitle(TemplateDefine::TYPE_CREATE_ROLE, $roleModelId);
        if (is_null($configInitData)) {
            LogMark::getInstance()->markError(
                GameErrorCode::ROLE_MODEL_NOT_FOUND,
                "[ClothLogic] player role model not found,table createRole",
                array(
                    "roleId" => $roleModelId
                )
            );
            return;
        }
        $configFemaleCloth = $configInitData[TemplateCreateRole::InitClothFemale];
        $configMaleCloth = $configInitData[TemplateCreateRole::InitClothMale];
        if (!empty($femaleClothIdx)) {
            foreach ($femaleClothIdx as $idx => $clothId) {
                $clothConfig = $this->getTitle(TemplateDefine::TYPE_CLOTHING, $clothId);
                //移除过期服装
                if (isset($configFemaleCloth[$idx])) {
                    $i = array_search($clothId, $femaleCloth);
                    $femaleCloth[$i] = $configFemaleCloth[$idx];
                }
                //互斥部位检查,恢复互斥部位
                if (isset($configFemaleCloth[$clothConfig[TemplateClothing::MutuallyExclusiveParts]])) {
                    $femaleCloth[] = $configFemaleCloth[$clothConfig[TemplateClothing::MutuallyExclusiveParts]];
                }
            }
            $accountModel->saveDress(AccountModel::CLOTH_FEMALE, json_encode(array_values($femaleCloth)));
        }
        if (!empty($maleClothIdx)) {
            foreach ($maleClothIdx as $idx => $clothId) {
                $clothConfig = $this->getTitle(TemplateDefine::TYPE_CLOTHING, $clothId);
                //移除过期服装
                if (isset($configMaleCloth[$idx])) {
                    $i = array_search($clothId, $maleCloth);
                    $maleCloth[$i] = $configMaleCloth[$idx];
                }
                //互斥部位检查,恢复互斥部位
                if (isset($configMaleCloth[$clothConfig[TemplateClothing::MutuallyExclusiveParts]])) {
                    $maleCloth[] = $configMaleCloth[$clothConfig[TemplateClothing::MutuallyExclusiveParts]];
                }
            }
            $accountModel->saveDress(AccountModel::CLOTH_MALE, json_encode(array_values($maleCloth)));
        }
    }

    //获取玩家当前服装
    public function getPlayerClothArray(int $playerId): array
    {
        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        $playerInfo = array();
        $ret = array();
        $keys = [
            AccountData::DB_GENDER,
            AccountData::DB_CLOTH_FEMALE,
            AccountData::DB_CLOTH_MALE
        ];
        if ($accountModel->search($playerId, $playerInfo)) {
            foreach ($keys as $key) {
                $ret[$key] = $playerInfo[$key] ?? null;
            }
        }
        $gender = (int)$ret[AccountData::DB_GENDER];
        $femaleCloth = json_decode($ret[AccountData::DB_CLOTH_FEMALE], true);
        $maleCloth = json_decode($ret[AccountData::DB_CLOTH_MALE], true);
        return [$femaleCloth, $maleCloth];
    }

    public function getPlayerClothProtobuf(int $playerId): array
    {
        [$femaleCloth, $maleCloth] = $this->getPlayerClothArray($playerId);
        $clothFemale = new ClothData();
        foreach($femaleCloth as $item) {
            if(empty($item)) {
                continue;
            }
            $cfg = $this->getTitle(TemplateDefine::TYPE_CLOTHING, $item);
            switch($cfg[TemplateClothing::Part]) {
                case 1:  $clothFemale->setHairId($item); break;
                case 2:  $clothFemale->setFaceId($item); break;
                case 3:  $clothFemale->setUpClothId($item); break;
                case 4:  $clothFemale->setDownClothId($item); break;
                case 5:  $clothFemale->setShoesId($item); break;
            }
        }

        $clothMale = new ClothData();

        foreach($maleCloth as $item) {
            if(empty($item)) {
                continue;
            }
            $cfg = $this->getTitle(TemplateDefine::TYPE_CLOTHING, $item);
            switch($cfg[TemplateClothing::Part]) {
                case 1:  $clothMale->setHairId($item); break;
                case 2:  $clothMale->setFaceId($item); break;
                case 3:  $clothMale->setUpClothId($item); break;
                case 4:  $clothMale->setDownClothId($item); break;
                case 5:  $clothMale->setShoesId($item); break;
            }
        }
        return [$clothFemale, $clothMale];
    }

    //穿上新购买的服装
    //clothArray=[clothId,..]
    public function wearNewClothInShop(int $playerId, array $clothArray)
    {
        [$femaleCloth, $maleCloth] = $this->getPlayerClothArray($playerId);
        foreach ($clothArray as $clothId) {
            $clothConfig = $this->getTitle(TemplateDefine::TYPE_CLOTHING, $clothId);
            if ($clothConfig[TemplateClothing::Sex] == AccountModel::CLOTH_MALE) {
                $this->wearNewCloth($maleCloth, $clothId, $clothConfig);
                $sex = AccountModel::CLOTH_MALE;
            } else {
                $this->wearNewCloth($femaleCloth, $clothId, $clothConfig);
                $sex = AccountModel::CLOTH_FEMALE;
            }
        }
        /**
         * @var AccountModel $accountModel
         */
        $accountModel = ModelManager::getInstance()->getModel(ModelTypeDefine::ACCOUNT);
        //保存
        $clothData = new ClothData();
        if ($sex == AccountModel::CLOTH_MALE) {
            $accountModel->saveDress(AccountModel::CLOTH_MALE, json_encode(array_values($maleCloth)));
            foreach($maleCloth as $item) {
                if(empty($item)) {
                    continue;
                }
                switch($this->getTerm(TemplateDefine::TYPE_CLOTHING, $item, TemplateClothing::Part)) {
                    case 1:  $clothData->setHairId($item); break;
                    case 2:  $clothData->setFaceId($item); break;
                    case 3:  $clothData->setUpClothId($item); break;
                    case 4:  $clothData->setDownClothId($item); break;
                    case 5:  $clothData->setShoesId($item); break;
                }
            }
        } else {
            $accountModel->saveDress(AccountModel::CLOTH_FEMALE, json_encode(array_values($femaleCloth)));
            foreach($femaleCloth as $item) {
                if(empty($item)) {
                    continue;
                }
                switch($this->getTerm(TemplateDefine::TYPE_CLOTHING, $item, TemplateClothing::Part)) {
                    case 1:  $clothData->setHairId($item); break;
                    case 2:  $clothData->setFaceId($item); break;
                    case 3:  $clothData->setUpClothId($item); break;
                    case 4:  $clothData->setDownClothId($item); break;
                    case 5:  $clothData->setShoesId($item); break;
                }
            }
        }
        //通知换装
        $sendMessage = new ClothSaveRecv();
        $sendMessage->setSucc(true);
        $sendMessage->setCode(ClientErrorCode::CLIENT_SUCCESS);
        $sendMessage->setSex($sex);
        $sendMessage->setCloth($clothData);
        SendMessage::getInstance()->sendClient(PacketId::Cloth_Save_Recv, $sendMessage);
    }

    private function wearNewCloth(array &$cloth, int $clothId, array $clothConfig)
    {
        //找到当前位置的服装,替换
        $hasCloth = false;
        foreach ($cloth as $idx => $cloId) {
            $part = $this->getTerm(TemplateDefine::TYPE_CLOTHING, $cloId, TemplateClothing::Part);
            //替换当前位置
            if ($part == $clothConfig[TemplateClothing::Part]) {
                $cloth[$idx] = $clothId;
                $hasCloth = true;
            }
            //检查是否有互斥部位,替换
            if ($part == $clothConfig[TemplateClothing::MutuallyExclusiveParts]) {
                $cloth[$idx] = 0;
            }
        }
        //新部位,没有替换的
        if (!$hasCloth) {
            $cloth[] = $clothId;
        }
    }
}
