<?php

class CoinPushManiaActModel extends ActBaseModel implements ActInterface
{
    public $extraConfigFieldMapping = [
        '收集物基础值' => 'collect_base_num',
    ];
    function formatActData(array &$actConfig)
    {
        $config = $actConfig['coinPushManiaReward'];
        $actConfig['reward_conf'] = [
          'collect_base_num' => intval($actConfig['coinPushManiaExtra']['collect_base_num'])
        ];
        if(empty($actConfig['reward_conf']['collect_base_num']))$this->response(-1 * __LINE__, "收集物基础值为空");
        unset($actConfig['coinPushManiaReward'], $actConfig['coinPushManiaExtra']);

        if(empty($config))$this->response(-1 * __LINE__, "配置为空");
        foreach ($config as $lvIdx => &$lvItem){
            if(empty($lvItem['stages']))$this->response(-1 * __LINE__, "第{$lvIdx}层等级层, 未配置体力层");
            foreach ($lvItem['stages'] as $spinsIdx => &$spinsItem){
                if(empty($spinsItem['tokenCollectConfig']))$this->response(-1 * __LINE__, "第{$lvIdx}层等级层, 第{$spinsIdx}层体力层, 未配置 代币收集配置");
                if(empty($spinsItem['rewardConfig']))$this->response(-1 * __LINE__, "第{$lvIdx}层等级层, 第{$spinsIdx}层体力层, 未配置 关卡配置");
                if(empty($spinsItem['tokenStageConfig']))$this->response(-1 * __LINE__, "第{$lvIdx}层等级层, 第{$spinsIdx}层体力层, 未配置 阶段奖励配置");

                $spinsItem['tokenCollectConfig'] = array_values($spinsItem['tokenCollectConfig']);
                foreach ($spinsItem['tokenCollectConfig'] as $k => &$item){
                    $idx = $k+1;
                    if(empty($item['target']))$this->response(-1 * __LINE__, "第{$lvIdx}层等级层, 第{$spinsIdx}层体力层,  第{$idx}层代币收集阶段,  目标值为空");
                    if(empty($item['value']))$this->response(-1 * __LINE__, "第{$lvIdx}层等级层, 第{$spinsIdx}层体力层,  第{$idx}层代币收集阶段,  代币数为空");
                }

                $spinsItem['rewardConfig'] = array_values($spinsItem['rewardConfig']);
                foreach ($spinsItem['rewardConfig'] as $k => &$coins){
                    $idx = $k + 1;
                    $hasBonus = false;
                    if(empty($coins['coins']))$this->response(-1 * __LINE__, "第{$lvIdx}层等级层, 第{$spinsIdx}层体力层,  第{$idx}关, 奖励币为空", $coins);

                    foreach ($coins['coins'] as $ck => &$coin){
                        $cidx = $ck + 1;
                        $coin['level'] = intval($k);
                        $coin['bonus'] = boolval($coin['bonus']);
                        $coin['prizes'] = json_decode(urldecode($coin['prizes']), true);
                        if($hasBonus && $coin['bonus'])$this->response(-1 * __LINE__, "第{$lvIdx}层等级层, 第{$spinsIdx}层体力层,  第{$idx}关, 超过一个大奖", $coin);

                        $hasBonus = $hasBonus || $coin['bonus'];
                        if(empty($coin['prizes']))$this->response(-1 * __LINE__, "第{$lvIdx}层等级层, 第{$spinsIdx}层体力层,  第{$idx}关, 第{$cidx}个奖励币, 奖励为空", $coin);
                    }
                    if(!$hasBonus)$this->response(-1 * __LINE__, "第{$lvIdx}层等级层, 第{$spinsIdx}层体力层,  第{$idx}关, 未配置大奖");
                }

                $spinsItem['tokenStageConfig'] = array_values($spinsItem['tokenStageConfig']);
                foreach ($spinsItem['tokenStageConfig'] as $k => &$item){
                    $idx = $k + 1;
                    $item['prizes'] = json_decode(urldecode($item['prizes']), true);
                    if(empty($item['target']))$this->response(-1 * __LINE__, "第{$lvIdx}层等级层, 第{$spinsIdx}层体力层,  第{$idx}阶段奖,  目标值为空");
                    if(empty($item['prizes']))$this->response(-1 * __LINE__, "第{$lvIdx}层等级层, 第{$spinsIdx}层体力层,  第{$idx}阶段奖,  奖励为空");
                }
            }
        }
        $actConfig['extraData'] = $config;
    }

    function writeActCache(array $actConfig)
    {
        $aid = $actConfig["aid"];
        $conditionKeys = okeys::activityConditionKeys($aid);
        $stageRewardKeys = okeys::activityRewardsStageKeys($aid);
        $extraData = json_decode($actConfig['extraData'], true) ?? [];
        $expireTime = max($actConfig['end_time'], time() + 60);#redis最少一分钟
        foreach ($extraData as $idx1 => $item1) {
            foreach ($item1['stages'] as $idx2 => $item2) {
                $condition = $this->getStageConditionLvSpins($item1, $item2);

                $stageKey = "{$idx1}_{$idx2}";
                unset($item2['spinsStart']);
                unset($item2['spinsEnd']);
                oo::commonOprRedis('games')->hset($conditionKeys, $stageKey, json_encode($condition, 32));
                oo::commonOprRedis('games')->hset($stageRewardKeys, $stageKey, json_encode($item2, 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)
    {
        if (count($sheetArray) < 5) {
            $this->response(-1 * __LINE__, "工作表数量不匹配");
        }

        $sheetIdx = 1;
        $basicExtra = $sheetArray[$sheetIdx++] ?? [];
        $stageMappingSheet = $sheetArray[$sheetIdx++] ?? [];
        $collectSheet = $sheetArray[$sheetIdx++] ?? [];
        $rewardSheet = $sheetArray[$sheetIdx++] ?? [];
        $stageSheet = $sheetArray[$sheetIdx++] ?? [];

        list($rewardConf, $idxMapping) = $this->parseLvSpinsStagesMapping($stageMappingSheet);

        $this->parseCollectConfig($rewardConf, $idxMapping, $collectSheet);

        $this->parseRewardConfig($rewardConf, $idxMapping, $rewardSheet);

        $this->parseStageConfig($rewardConf, $idxMapping, $stageSheet);
        $basicConfig['coinPushManiaExtra'] = self::parseExtraBasicConfig($this->extraConfigFieldMapping, $basicExtra);
        $basicConfig['coinPushManiaReward'] = $rewardConf;
    }

    private function parseCollectConfig(array  &$rewardConf, array $idxMapping, array $sheet)
    {
        $length = count($sheet);
        for ($i=1;$i < $length; $i++){
            $item = $sheet[$i];
            list($idx, $stage, $target, $value) = $item;
            if(empty($idxMapping[$idx]))
                $this->response(-1 * __LINE__, "映射关系不存在:{$idx}", [$idxMapping, $item]);
            list($lvIdx, $spinsIdx) = $idxMapping[$idx];
            $rewardConf[$lvIdx]['stages'][$spinsIdx]['tokenCollectConfig'] = $rewardConf[$lvIdx]['stages'][$spinsIdx]['tokenCollectConfig'] ?? [];
            $rewardConf[$lvIdx]['stages'][$spinsIdx]['tokenCollectConfig'][$stage] = [
                'target' =>$target,
                'value' =>$value,
            ];
        }
    }

    private function parseRewardConfig(array  &$rewardConf, array $idxMapping, array $sheet)
    {
        $coinIdx = 0;
        $length = count($sheet);
        for ($i=1;$i < $length; $i++){
            $coinIdx++;
            $item = $sheet[$i];
            list($idx, $stage, $size, $bonus, $target) = $item;
            switch ($size){
                case '小':$size = 1;break;
                case '中':$size = 2;break;
                case '大':$size = 3;break;
                default:$this->response(-1 * __LINE__, "奖励币大小异常:{$size}", [$idxMapping, $item]);
            }
            $bonus = $this->parseYesOrNo($bonus);
            if(empty($idxMapping[$idx]))$this->response(-1 * __LINE__, "映射关系不存在:{$idx}", [$idxMapping, $item]);

            $prizes = $this->parseLineRewards(array_slice($sheet[$i], 5), $i+1);
            list($lvIdx, $spinsIdx) = $idxMapping[$idx];
            $rewardConf[$lvIdx]['stages'][$spinsIdx]['rewardConfig'] = $rewardConf[$lvIdx]['stages'][$spinsIdx]['rewardConfig'] ?? [];
            $rewardConf[$lvIdx]['stages'][$spinsIdx]['rewardConfig'][$stage]['coins'][] = [
                'id' =>$coinIdx,
                'coinSize' =>$size,
                'bonus' =>$bonus,
                'coinUsedLimit' =>$target,
                'prizes' => urlencode(json_encode($prizes)),
            ];
        }
    }


    private function parseStageConfig(array  &$rewardConf, array $idxMapping, array $sheet)
    {
        $length = count($sheet);
        for ($i=1;$i < $length; $i++){
            $item = $sheet[$i];
            list($idx, $stage, $target) = $item;
            if(empty($idxMapping[$idx]))
                $this->response(-1 * __LINE__, "映射关系不存在:{$idx}", [$idxMapping, $item]);
            list($lvIdx, $spinsIdx) = $idxMapping[$idx];

            $prizes = $this->parseLineRewards(array_slice($sheet[$i], 3), $i+1);
            $rewardConf[$lvIdx]['stages'][$spinsIdx]['tokenStageConfig'] = $rewardConf[$lvIdx]['stages'][$spinsIdx]['tokenStageConfig'] ?? [];
            $rewardConf[$lvIdx]['stages'][$spinsIdx]['tokenStageConfig'][$stage] = [
                'id' =>$stage,
                'target' =>$target,
                'prizes' => urlencode(json_encode($prizes)),
            ];
        }
    }

}