<?php

class SuperGashaponActModel extends ActBaseModel implements ActInterface
{
    public $rewardTypes = [
        SUPER_GASHAPON_REWARD_TYPE_NORMAL  =>'普通蛋',
        SUPER_GASHAPON_REWARD_TYPE_COLLECT1  =>'收集物1',
        SUPER_GASHAPON_REWARD_TYPE_COLLECT2  =>'收集物2',
        SUPER_GASHAPON_REWARD_TYPE_LUCKY  =>'幸运蛋',
        SUPER_GASHAPON_REWARD_TYPE_BONUS  =>'大奖',
    ];
    public $collectTypes = [
        1, 2
    ];
    function formatActData(array &$actConfig)
    {
        if (empty($actConfig['superGashaponRewardConfig'])) $this->response(-1, '保存失败，奖励配置为空');
        foreach ($actConfig['superGashaponRewardConfig'] as $lvIdx => &$lvItem) {
            if (empty($lvItem['stages'])) $this->response(-1, "保存失败，第{$lvIdx}层等级区间配置为空");

            foreach ($lvItem['stages'] as $spinIdx => &$spinItem) {
                if (empty($spinItem['stages'])) $this->response(-1, "保存失败，第{$lvIdx}层等级区间,第{$spinIdx}层体力区间配置为空");

                foreach ($spinItem['stages'] as $shushuIdx => &$shushuItem) {
                    if (empty($shushuItem['shushu'])) $shushuItem['shushu'] = [0];

                    // 收集配置
                    foreach ($this->collectTypes as $collectType){
                        if (empty($shushuItem["collect{$collectType}"])) $this->response(-1, "保存失败，第{$lvIdx}层等级区间,第{$spinIdx}层体力区间,第{$shushuIdx}层数数区间，收集物{$collectType} 配置为空");

                        foreach ($shushuItem["collect{$collectType}"] as $collectIdx => $collectItem){
                            $collectKey = $collectIdx + 1;
                            if (empty($collectItem['target'])) $this->response(-1, "保存失败，第{$lvIdx}层等级区间,第{$spinIdx}层体力区间,第{$shushuIdx}层数数区间，收集物{$collectType} 第{$collectKey}层，阶段值为空");
                            if (empty($collectItem['prizes'])) $this->response(-1, "保存失败，第{$lvIdx}层等级区间,第{$spinIdx}层体力区间,第{$shushuIdx}层数数区间，收集物{$collectType} 第{$collectKey}层，奖励为空");

                        }
                    }

                    // 关卡配置
                    if (empty($shushuItem['layers'])) $this->response(-1, "保存失败，第{$lvIdx}层等级区间,第{$spinIdx}层体力区间,第{$shushuIdx}层数数区间，关卡配置为空", $shushuItem);
                    foreach ($shushuItem['layers'] as $stageIdx => &$stageItem) {
                        if (empty($stageItem['items'])) $this->response(-1, "保存失败，第{$lvIdx}层等级区间,第{$spinIdx}层体力区间,第{$shushuIdx}层数数区间，第{$stageItem['layer']}关，扭蛋配置为空");
                        $bonusCNt = 0;
                        foreach ($stageItem['items'] as $pIdx => &$pItem) {
                            if (empty($pItem['weight']))
                                $this->response(-1, "保存失败，第{$lvIdx}层等级区间,第{$spinIdx}层体力区间,第{$shushuIdx}层数数区间，第{$stageItem['layer']}关，第{$pItem['id']}个扭蛋 权重为空");
                            switch ($pItem['type']) {
                                case SUPER_GASHAPON_REWARD_TYPE_BONUS:
                                    $bonusCNt++;
                                case SUPER_GASHAPON_REWARD_TYPE_NORMAL:
                                    if (empty($pItem['prizes']))
                                        $this->response(-1, "保存失败，第{$lvIdx}层等级区间,第{$spinIdx}层体力区间,第{$shushuIdx}层数数区间，第{$stageItem['layer']}关，第{$pItem['id']}个扭蛋 奖励配置为空");
                                    break;

                                case SUPER_GASHAPON_REWARD_TYPE_COLLECT1:
                                case SUPER_GASHAPON_REWARD_TYPE_COLLECT2:
                                    if (empty($pItem['prizes']))
                                        $this->response(-1, "保存失败，第{$lvIdx}层等级区间,第{$spinIdx}层体力区间,第{$shushuIdx}层数数区间，第{$stageItem['layer']}关，第{$pItem['id']}个扭蛋 奖励配置为空");

                                    if (empty($pItem['progressNum']))
                                        $this->response(-1, "保存失败，第{$lvIdx}层等级区间,第{$spinIdx}层体力区间,第{$shushuIdx}层数数区间，第{$stageItem['layer']}关，第{$pItem['id']}个扭蛋 收集物数量配置为空");
                                    break;
                                case SUPER_GASHAPON_REWARD_TYPE_LUCKY:
                                    $pItem['prizes'] = [];
                                    break;
                                default:
                                    $this->response(-1, "保存失败，第{$lvIdx}层等级区间,第{$spinIdx}层体力区间,第{$shushuIdx}层数数区间，第{$stageItem['layer']}关，第{$pItem['id']}个扭蛋 奖励类型异常：{$pItem['type']}");
                                    break;
                            }
                        }
                        if (empty($bonusCNt)) $this->response(-1, "保存失败，第{$lvIdx}层等级区间,第{$spinIdx}层体力区间,第{$shushuIdx}层数数区间，第{$stageItem['layer']}关，未配置大奖", $actConfig['superGashaponRewardConfig']);

                    }
                    $shushuItem['maxLayer'] = count($shushuItem['layers']);
                    $shushuItem['layers'] = array_values($shushuItem['layers']);
                }
            }
        }
        $actConfig['extraData'] = $actConfig['superGashaponRewardConfig'];
        unset($actConfig['superGashaponRewardConfig']);
    }

    function writeActCache(array $actConfig)
    {
        $conditionKeys = okeys::activityConditionKeys($actConfig['aid']);
        $stageRewardKeys = okeys::activityRewardsStageKeys($actConfig['aid']);
        $stageConfig = json_decode($actConfig['extraData'], true) ?? [];
        $expireTime = max($actConfig['end_time'], time() + 60);#redis最少一分钟
        foreach ($stageConfig as $idx1 => $item1) {
            foreach ($item1['stages'] as $idx2 => $item2) {
                foreach ($item2['stages'] as $idx3 => $item3) {
                    $stageKey = "{$idx1}_{$idx2}_{$idx3}";
                    $stageConditions = $this->getStageConditionLvSpinsShushu($item1, $item2, $item3);
                    unset($item3['shushu']);
                    oo::commonOprRedis('games')->hset($conditionKeys, $stageKey, json_encode($stageConditions, 32));
                    oo::commonOprRedis('games')->hset($stageRewardKeys, $stageKey, json_encode($item3, 32));
                }
            }
        }
        oo::commonOprRedis('games')->expireAt($conditionKeys, oo::redisRandomExpire($expireTime));
        oo::commonOprRedis('games')->expireAt($stageRewardKeys, oo::redisRandomExpire($expireTime));
    }

    function serializeShowConf(array &$actConfig)
    {
    }

    function importActData(array &$basicConfig, $sheetArray)
    {
        $sheetIdx = 0;
        $stagesMappingArray = $sheetArray[++$sheetIdx] ?? [];
        $rewardStagesSheet = $sheetArray[++$sheetIdx] ?? [];
        $collect1Sheet = $sheetArray[++$sheetIdx] ?? [];
        $collect2Sheet = $sheetArray[++$sheetIdx] ?? [];
        list($rewardsConfig, $idxMapping) = $this->parseLvSpinsShushuStagesMapping($stagesMappingArray);

        $this->parseRewardStagesSheet($rewardsConfig, $idxMapping, $rewardStagesSheet);

        foreach ($this->collectTypes as $collectType){
            $this->parseCollectRewardSheet($rewardsConfig, $idxMapping, ${"collect{$collectType}Sheet"}, $collectType);
        }

        $basicConfig['superGashaponRewardConfig'] = $rewardsConfig;

    }

    private function parseRewardStagesSheet(&$rewardsConfig, $idxMapping, $rewardStagesSheet){
        $rewardTypeMap = array_flip($this->rewardTypes);
        $sheetLen = count($rewardStagesSheet);
        for($i = 1;$i < $sheetLen;$i++){
            if(empty($rewardStagesSheet[$i]))continue;
            $filterLine = array_filter($rewardStagesSheet[$i]);
            if (empty($filterLine)) continue;
            $item = $rewardStagesSheet[$i];
            $line = $i + 1;
            list($idx, $stageIdx, $rewardTypeText, $weight, $min_token_spend, $collect_num) = $item;

            if (empty($rewardTypeMap[$rewardTypeText])) $this->response(-1 * __LINE__, "第{$line}行,奖励类型:{$rewardTypeText} 不存在");

            @list($lvIdx, $spinsIdx, $ssIdx) = $idxMapping[$idx];
            if (empty($lvIdx) || empty($spinsIdx) || empty($ssIdx))$this->response(-1 * __LINE__, "分层配置异常：{$idx}", $idxMapping);
            $rewardsConfig[$lvIdx]['stages'][$spinsIdx]['stages'][$ssIdx]['layers'] = $rewardsConfig[$lvIdx]['stages'][$spinsIdx]['stages'][$ssIdx]['layers'] ?? [];
            $rewardsConfig[$lvIdx]['stages'][$spinsIdx]['stages'][$ssIdx]['layers'][$stageIdx] = $rewardsConfig[$lvIdx]['stages'][$spinsIdx]['stages'][$ssIdx]['layers'][$stageIdx] ?? [
                'layer' => count($rewardsConfig[$lvIdx]['stages'][$spinsIdx]['stages'][$ssIdx]['layers']) + 1,
                'items' => [],
            ];

            $stageCnt = count($rewardsConfig[$lvIdx]['stages'][$spinsIdx]['stages'][$ssIdx]['layers'][$stageIdx]['items']);
            $prizeItems = array_slice($item, 6);
            $rewardsConfig[$lvIdx]['stages'][$spinsIdx]['stages'][$ssIdx]['layers'][$stageIdx]['items'][] = [
                'id' => $stageCnt + 1,
                'type' => $rewardTypeMap[$rewardTypeText],
                'weight' => $weight,
                'spendLowest' => $min_token_spend,
                'progressNum' => $collect_num,
                'prizes' => $this->parseLineRewards($prizeItems, $line),
            ];
        }
    }
    private function parseCollectRewardSheet(&$rewardsConfig, $idxMapping, $rewardStagesSheet, $collectType){
        if(!in_array($collectType, $this->collectTypes))$this->response(-1 * __LINE__, "导入异常，请联系开发人员");
        $sheetLen = count($rewardStagesSheet);
        for($i = 1;$i < $sheetLen;$i++){
            if(empty($rewardStagesSheet[$i]))continue;
            $filterLine = array_filter($rewardStagesSheet[$i]);
            if (empty($filterLine)) continue;
            $item = $rewardStagesSheet[$i];
            $line = $i + 1;
            list($idx, $target) = $item;

            @list($lvIdx, $spinsIdx, $ssIdx) = $idxMapping[$idx];
            if (empty($lvIdx) || empty($spinsIdx) || empty($ssIdx))$this->response(-1 * __LINE__, "分层配置异常：{$idx}", $idxMapping);
            $rewardsConfig[$lvIdx]['stages'][$spinsIdx]['stages'][$ssIdx]["collect{$collectType}"] = $rewardsConfig[$lvIdx]['stages'][$spinsIdx]['stages'][$ssIdx]["collect{$collectType}"] ?? [];

            $prizeItems = array_slice($item, 2);
            $stageCnt = count($rewardsConfig[$lvIdx]['stages'][$spinsIdx]['stages'][$ssIdx]["collect{$collectType}"]);
            $rewardsConfig[$lvIdx]['stages'][$spinsIdx]['stages'][$ssIdx]["collect{$collectType}"][] = [
                'stage' => $stageCnt + 1,
                'target' => $target,
                'prizes' => $this->parseLineRewards($prizeItems, "收集物{$collectType} {$line}"),
            ];
        }
    }


    function getActBasicConfig(): array
    {
        return [
            'rewardTypes' => $this->rewardTypes
        ];
    }
}