<?php

class JackpotActModel extends ActBaseModel implements ActInterface
{

    static  $taskMapping = [
        1 =>"下注次数",
        2 =>"获得金币",
        3 =>"Jackpot中获得奖金"
    ];

    public $extraConfigFieldMapping = [
        '开放等级' => 'jackpotOpenLv',
        '体力存量系数（整数）' => 'spinsRatio',
        '体力存量系数' => 'spinsRatio',
    ];
    static  $permissionMapping = [
        '通行证专属头像框' => 2 ,
        '赠送N个通行证等级' => 3 ,
    ];
    function serializeShowConf(array &$actConfig)
    {

    }

    function formatActData(array &$actConfig)
    {

        $maxStageCnt = 0;
        if(empty($actConfig['jackpot']))$this->response(1, '保存失败，奖励配置异常');
        $json = [];
        foreach ($actConfig['jackpot'] as $idx => $item){
            $configsValue = [];
            if(empty($item['stages']))$this->response(1, "第{$idx}层等级区间未配置Y值层");
            foreach ($item['stages'] as $idx1 => $item1){

                if(empty($item1['stages']))$this->response(1, "第{$idx}层等级区间，第{$idx1}层Y值区间未配置数数层");
                foreach ($item1['stages'] as $idx2 => $item2){
                    $configsValue[$idx2]['shushu'] = array_map(function($v){return intval($v);}, $item2);

                    if(empty($item2['stages']))$this->response(1, "第{$idx}层等级区间，第{$idx1}层Y值区间，第{$idx2}层数数区间未配置任务");
                    $maxStageCnt = max(count($item2['stages']), $maxStageCnt);
                    foreach ($item2['stages'] as $idx3 => $rewardItem){
                        $tmpPrize = array_values(json_decode(urldecode($rewardItem['prize']),true));
                        $tmpBet = array_values(json_decode(urldecode($rewardItem['bet']),true));
                        if(empty($tmpPrize) || empty($tmpBet))$this->response(1, "第{$idx}层等级区间，第{$idx1}层Y值区间，第{$idx2}层数数区间，第{$idx3}层任务未配置奖励或倍率");
                        sort($tmpBet);
                        $actConfig['jackpot'][$idx]['stages'][$idx1]['stages'][$idx2]['stages'][$idx3]['prize'] = $tmpPrize;
                        $actConfig['jackpot'][$idx]['stages'][$idx1]['stages'][$idx2]['stages'][$idx3]['bet'] = $tmpBet;
                        $configsValue[$idx2]['reward'][] = [
                            'prize' => $tmpPrize,
                            'bet' => $tmpBet,
                            'frequency' => intval($rewardItem['frequency']),
                            'target' => intval($rewardItem['target']),
                            'taskType' => intval($rewardItem['taskType']),
                            'id' => intval($rewardItem['id']),
                        ];
                    }
                }
            }
            empty($json) && $json = $configsValue[$idx2]['reward'];
        }
        if(count($actConfig['prdConf']) < $maxStageCnt)$this->response(1, "prd概率配置任务数:".count($actConfig['prdConf']).",小于最大任务数:{$maxStageCnt}");
        $actConfig['reward_info'] = json_encode($json,JSON_NUMERIC_CHECK);
        $actConfig['extra_reward']= json_encode([
            'fixCo' => $actConfig['common_conf'] ?? [],
            'waterLevelCoefficient'=>[],
            'prdConf'=>$actConfig['prdConf'],
        ],JSON_NUMERIC_CHECK);

        $actConfig['extraData']   = json_encode([
            'openLv'=> $actConfig['jackpotOpenLv'],
            'spinsRatio'=> intval($actConfig['spinsRatio']),
            'yStages'=> $actConfig['jackpot']
        ],JSON_NUMERIC_CHECK);
        unset($actConfig['spinsRatio'],
            $actConfig['jackpotWaterLevelCoefficient'],$actConfig['prdConf'],
            $actConfig['jackpotOpenLv'], $actConfig['jackpot']
        );
    }

    function writeActCache(array $actConfig)
    {
        $conditionKeys = okeys::activityConditionKeys($actConfig['aid']);
        $stageRewardKeys = okeys::activityRewardsStageKeys($actConfig['aid']);
        $configs = json_decode($actConfig['extraData'], true) ?? [];
        $expireTime = max($actConfig['end_time'], time() + 60);#redis最少一分钟
        foreach ($configs['yStages'] as $idx1 => $item1) {
            foreach ($item1['stages'] as $idx2 => $item2) {
                foreach ($item2['stages'] as $idx3 => $item3) {
                    $condition = [
                        [
                            'shushu' => [],
                            'start' => $item1['start'],
                            'end' => $item1['end'],
                            'type' => CONDITION_TYPE_COIN_Y,
                        ],
                        [
                            'shushu' => [],
                            'start' => $item2['start'],
                            'end' => $item2['end'],
                            'type' => CONDITION_TYPE_COIN_Y,
                        ],
                        [
                            'shushu' => $item3['shushu'],
                            'start' => 0,
                            'end' => 0,
                            'type' => CONDITION_TYPE_SHUSHU,
                        ],
                    ];

                    $stageKey = "{$idx1}_{$idx2}_{$idx3}";
                    oo::commonOprRedis('games')->hset($conditionKeys, $stageKey, json_encode($condition, 32));
                    oo::commonOprRedis('games')->hset($stageRewardKeys, $stageKey, json_encode($item3['stages'], 32));
                }
            }
        }

        oo::commonOprRedis('games')->expireAt($conditionKeys, oo::redisRandomExpire($expireTime));
        oo::commonOprRedis('games')->expireAt($stageRewardKeys, oo::redisRandomExpire($expireTime));
    }

    function importActData(array &$basicConfig, $sheetArray)
    {
        $sheetIdx = 0;
        $extraConfigSheet = $sheetArray[++$sheetIdx];
        $prdConfigSheet = $sheetArray[++$sheetIdx];
        $stageMappingSheet = $sheetArray[++$sheetIdx];
        $stageRewardsSheet = $sheetArray[++$sheetIdx];

        $extraConfig = self::parseExtraBasicConfig($this->extraConfigFieldMapping, $extraConfigSheet);
        $basicConfig['jackpotOpenLv'] = $extraConfig['jackpotOpenLv'];
        $basicConfig['spinsRatio'] = $extraConfig['spinsRatio'];

        $this->parsePrdConfig($basicConfig, $prdConfigSheet);
        list($rewardsConfig, $idxMapping) = $this->parseLvCoinYShushuStagesMapping($stageMappingSheet);

        $this->parseRewardsConfig($rewardsConfig, $idxMapping, $stageRewardsSheet);

        $basicConfig['jackpot'] = $rewardsConfig;


    }

    private function parsePrdConfig(&$basicConfig, $prdConfigSheet){
        $lineCnt = count($prdConfigSheet);
        $basicConfig['prdConf'] = [];
        for ($i = 1;$i< $lineCnt; $i++){
            $item = $prdConfigSheet[$i];
            list($idx, $ce1, $ce2) = $item;
            $basicConfig['prdConf'][$idx] = [
                $ce1, $ce2
            ];
        }
    }
    private function parseRewardsConfig(&$rewardConf, $idxMapping, $sheet){
        $length = count($sheet);
        $taskFlip = array_flip(self::$taskMapping);
        for ($i=1;$i < $length; $i++){
            $item = $sheet[$i];
            list($idx, $stage, $task, $target, $frequency, $jackpotBase, $jackpotMid, $jackpotHigh, $betStr) = $item;
            if(empty($idxMapping[$idx]))$this->response(-1 * __LINE__, "第{$i}行，映射关系不存在:{$idx}", [$idxMapping, $item]);
            if(empty($taskFlip[$task]))$this->response(-1 * __LINE__, "第{$i}行，任务类型不存在:{$task}", [$idxMapping, $item]);

            $prizes = $this->parseLineRewards(array_slice($sheet[$i], 9), $i);
            $bets = $this->parseBets($betStr);
            list($lvIdx, $spinsIdx, $ssIdx) = $idxMapping[$idx];
            $rewardConf[$lvIdx]['stages'][$spinsIdx]['rewardConfig'] = $rewardConf[$lvIdx]['stages'][$spinsIdx]['rewardConfig'] ?? [];
            $curLength = count($rewardConf[$lvIdx]['stages'][$spinsIdx]['stages'][$ssIdx]['stages']);
            $rewardConf[$lvIdx]['stages'][$spinsIdx]['stages'][$ssIdx]['stages'][$curLength] = [
                "id" => $curLength + 1,
                "taskType" => $taskFlip[$task],
                "target" => $target,
                "frequency" => $frequency,
                "base" => $jackpotBase,
                "mid" => $jackpotMid,
                "high" => $jackpotHigh,
                "prize" => urlencode(json_encode($prizes)),
                "bet" => urlencode(json_encode($bets)),
            ];
        }
    }

    private function parseBets($betStr){
        $betStr = strtr($betStr, ['，' => ',', ' ' => '']);
        $bets = explode(',',$betStr);
        return array_filter($bets);
    }

    function getActBasicConfig(): array
    {
        $this->response(0, '', self::$taskMapping);
        return [];
    }
}