<?php

/**
 * 比赛记录
 */

namespace Game\Logic;

use Exception;
use Framework\Lib\Utils;
use Framework\Log\LogMark;
use Framework\MVC\ModelManager;
use Framework\Logic\TemplateHelp;
use Game\Constant\ClientErrorCode;
use Game\Constant\ConstTemplate\TemplateConst;
use Game\Constant\ModelTypeDefine;
use Game\Constant\TemplateDefine;
use Game\Data\RecordData;
use Game\Model\RecordModel;
use Game\Protobuf\GCMatchRecordDetail;
use Game\Protobuf\MatchRecord;

trait RecordLogic
{
    use TemplateHelp;

    //获取比赛记录,分页
    //page从0开始
    public function getRecordByPage(int $page): array
    {
        /**
         * @var RecordModel $recordModel
         */
        $recordModel = ModelManager::getInstance()->getModel(ModelTypeDefine::RECORD);
        $allRecordIds = $recordModel->getAllRecordUid(0, -1);
        $allCollectionIds = $recordModel->getAllCollection();
        $configNum = $this->getTerm(TemplateDefine::TYPE_CONST,
                                           TemplateConst::Const_Record_Page,
                                           TemplateConst::ConstNum);
        $start = $page * $configNum;
        $end = $start + $configNum * 2;
        $joinIds = array_slice($allRecordIds, $start, $end);
        $data = array();
        $now = Utils::getServerTimestamp();
        foreach ($joinIds as $joinId) {
            if (count($data) >= $configNum) {
                break;
            }
            $record = $recordModel->getRecordByJoinId($joinId);
            if (is_null($record)) {
                //数据错误
                LogMark::getInstance()->markDebug(
                    "[RecordLogic] record in index but not in db",
                    array(
                        "joinId" => $joinId
                    )
                );
                $recordModel->delRecordByJoinId($joinId);
                continue;
            }
            //检查比赛是否完成结算,未完成的删除
            if (strlen($record->raceResultData) == 0) {
                LogMark::getInstance()->markDebug(
                    "[RecordLogic] record not complete",
                    (array)$record
                );
                //比赛创建30分钟内的 不删除
                if ($now - $record->matchTime >= 1800) {
                    $recordModel->delRecordByJoinId($joinId);
                }
                continue;
            }
            //整理数据
            $this->tidyRecordDataToProtobuf($record, $allCollectionIds, $data);
        }
        return $data;
    }

    //获取收藏数量
    public function getCollectionNum(): int
    {
        /**
         * @var RecordModel $recordModel
         */
        $recordModel = ModelManager::getInstance()->getModel(ModelTypeDefine::RECORD);
        return $recordModel->getCollectionNum();
    }

    //获取收藏记录,分页
    //page从0开始
    public function getCollectionRecordByPage(int $page): array
    {
        /**
         * @var RecordModel $recordModel
         */
        $recordModel = ModelManager::getInstance()->getModel(ModelTypeDefine::RECORD);
        $allCollectionIds = $recordModel->getAllCollection();
        $configNum = $this->getTerm(TemplateDefine::TYPE_CONST,
                                    TemplateConst::Const_Record_Page,
                                    TemplateConst::ConstNum);
        $start = $page * $configNum;
        $end = $start + $configNum;
        $joinIds = array_slice($allCollectionIds, $start, $end);
        $data = array();
        foreach ($joinIds as $joinId) {
            $record = $recordModel->getRecordByJoinId($joinId);
            if (is_null($record)) {
                //数据错误
                LogMark::getInstance()->markDebug(
                    "[RecordLogic] record in index but not in db",
                    array(
                        "joinId" => $joinId
                    )
                );
                $recordModel->delRecordByJoinId($joinId);
            }
            //整理数据
            $this->tidyRecordDataToProtobuf($record, $allCollectionIds, $data);
        }
        return $data;
    }

    //获取比赛详情
    public function getRecordDetail(int $joinId)
    {
        /**
         * @var RecordModel $recordModel
         */
        $recordModel = ModelManager::getInstance()->getModel(ModelTypeDefine::RECORD);
        $record = $recordModel->getRecordByJoinId($joinId);
        $sendMessage = new GCMatchRecordDetail();
        if (is_null($record)) {
            return $sendMessage;
        }
        try {
            $sendMessage->mergeFromJsonString($record->matchRecordDetail);
        } catch (Exception $e) {
            LogMark::getInstance()->markDebug(
                "[RecordLogic] mergeFromJsonString matchRecordDetail error,string:".$record->matchRecordDetail,
            );
            return [];
        }
        return $sendMessage;
    }

    //添加收藏
    public function addCollection(int $joinId): int
    {
        /**
         * @var RecordModel $recordModel
         */
        $recordModel = ModelManager::getInstance()->getModel(ModelTypeDefine::RECORD);
        //检查记录是否存在
        $record = $recordModel->getRecordByJoinId($joinId);
        if (is_null($record)) {
            return ClientErrorCode::RECORD_NOT_FOUND;
        }
        //检查上限
        $maxNum = $this->getTerm(TemplateDefine::TYPE_CONST,
                                    TemplateConst::Const_Record_Collection_Max,
                                    TemplateConst::ConstNum);
        if ($recordModel->getCollectionNum() >= $maxNum) {
            return ClientErrorCode::RECORD_COLLECTION_NUM_OVER_LIMIT;
        }
        //检查是否已收藏
        if ($recordModel->checkHasCollection($joinId)) {
            return ClientErrorCode::RECORD_HAS_COLLECTION;
        }
        //添加收藏
        if ($recordModel->addCollection($joinId)) {
            return ClientErrorCode::CLIENT_SUCCESS;
        }
        return ClientErrorCode::RECORD_OPTION_FAIL;
    }

    //取消收藏
    public function removeCollection(int $joinId): int
    {
        /**
         * @var RecordModel $recordModel
         */
        $recordModel = ModelManager::getInstance()->getModel(ModelTypeDefine::RECORD);
        //检查记录是否存在
        $record = $recordModel->getRecordByJoinId($joinId);
        if (is_null($record)) {
            return ClientErrorCode::RECORD_NOT_FOUND;
        }
        //检查是否已收藏
        if (!$recordModel->checkHasCollection($joinId)) {
            return ClientErrorCode::RECORD_NONE_COLLECTION;
        }
        //取消收藏
        if ($recordModel->removeCollection($joinId)) {
            $recordModel->checkDelTopRecord();
            return ClientErrorCode::CLIENT_SUCCESS;
        }
        return ClientErrorCode::RECORD_OPTION_FAIL;
    }

    //整理比赛数据
    public function tidyRecordDataToProtobuf(RecordData $recordData, array $allCollectionIds, array &$data)
    {
        $matchRecord = new MatchRecord();
        $matchRecord->setId($recordData->joinId);
        $matchRecord->setIsCollection(in_array($recordData->joinId, $allCollectionIds));
        $matchRecord->setMatchType($recordData->matchType);
        $matchRecord->setMapId($recordData->mapID);
        $matchRecord->setCostTime($recordData->costTime);
        $matchRecord->setRank($recordData->result);
        $matchRecord->setCarId($recordData->carId);
        $matchRecord->setMatchTime($recordData->matchTime);
        $matchRecord->setStatistics($recordData->clientStatistics ?? "");
        $data[] = $matchRecord;
    }

    public function getRecordByJoinId(int $joinId): ?RecordData
    {
        /**
         * @var RecordModel $recordModel
         */
        $recordModel = ModelManager::getInstance()->getModel(ModelTypeDefine::RECORD);
        //检查记录是否存在
        return $recordModel->getRecordByJoinId($joinId);
    }
}
