<?php

class TreasureActModel extends ActBaseModel implements ActInterface
{

    public static $weightGroupList = [];
    public $extraConfigFieldMapping = [
        '开放等级' => 'treasureOpenLv',
        '体力存量系数（整数）' => 'spinsRatio',
        '体力存量系数' => 'spinsRatio',
    ];
    function serializeShowConf(array &$actConfig)
    {
        foreach ($actConfig['stages'] as $idx1 => &$items1) {
            foreach ($items1['stages'] as $idx2 => &$items2) {
                if (isset($items2['stages'][0]['id'])) {
                    $items2['stages'] = [$items2['stages']];
                }
            }
        }
    }

    function formatActData(array &$actConfig)
    {
        $maxStageCnt = 0;
        if (empty($actConfig['treasure'])) $this->response(1, '保存失败，奖励配置异常');
        foreach ($actConfig['treasure'] as $idx => $item) {
            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) {


                    if (empty($item2['stages'])) $this->response(1, "第{$idx}层等级区间，第{$idx1}层Y值区间，第{$idx2}层数数区间未配置关卡");
                    $maxStageCnt = max(count($item2['stages']), $maxStageCnt);
                    foreach ($item2['stages'] as $idx3 => $item3) {
                        $roomId = $idx3+1;
                        foreach ($item3 as $idx4 => $rewardItem) {
                            $taskId = $idx4+1;
                            $tmpPrize = array_values(json_decode(urldecode($rewardItem['prize']), true));
                            $tmpBet = array_unique(array_values(json_decode(urldecode($rewardItem['bet']), true)));
                            if (empty($tmpPrize) || empty($tmpBet)) $this->response(1, "第{$idx}层等级区间，第{$idx1}层Y值区间，第{$idx2}层数数区间，，第{$roomId}层房间，第{$taskId}层任务未配置奖励或倍率", $rewardItem);
                            sort($tmpBet);
                            $actConfig['treasure'][$idx]['stages'][$idx1]['stages'][$idx2]['stages'][$idx3][$idx4]['prize'] = $tmpPrize;
                            $actConfig['treasure'][$idx]['stages'][$idx1]['stages'][$idx2]['stages'][$idx3][$idx4]['bet'] = $tmpBet;
                        }
                    }
                }
            }
        }
        $actConfig['reward_info'] = "{}";
        $actConfig['extra_reward'] = json_encode([
            'fixCo' => [],
            'waterLevelCoefficient' => [],
            'prdConf' => [],
        ], JSON_NUMERIC_CHECK);

        $actConfig['extraData'] = json_encode([
            'openLv' => $actConfig['treasureOpenLv'],
            'spinsRatio' => intval($actConfig['spinsRatio']),
//                        'difficultyDegree'=> $data['difficultyDegree'],
//                        'taskDegree'=> $data['taskDegree'],
            'yStages' => $actConfig['treasure']
        ], JSON_NUMERIC_CHECK);
        unset($actConfig['treasure'], $actConfig['spinsRatio'], $actConfig['prdConf'], $actConfig['spins'], $actConfig['spinStage'], $actConfig['treasureShushu'], $actConfig['treasureOpenLv'], $actConfig['taskDegree']);
    }

    function writeActCache(array $actConfig)
    {
        $conditionKeys = okeys::activityConditionKeys($actConfig['aid']);
        $stageRewardKeys = okeys::activityRewardsStageKeys($actConfig['aid']);
        $stageExtraConfKeys = okeys::activityStageExtraConfigKeys($actConfig['aid']);
        $extraReward = json_decode($actConfig['extraData'], true) ?? [];
        $expireTime = ActBaseModel::getActCacheExpireTime($actConfig['end_time']);#redis最少一分钟
        foreach ($extraReward['yStages'] as $idx1 => $item1) {
            foreach ($item1['stages'] as $idx2 => $item2) {
                foreach ($item2['stages'] as $idx3 => $item3) {
                    $stageConditions = $this->getStageConditionLvCoinYShushu($item1, $item2, $item3);
                    $stageKey = self::getMultiStageKey([$idx1, $idx2, $idx3]);
                    unset($item3['start']);
                    unset($item3['end']);
                    oo::commonOprRedis('games')->hset($conditionKeys, $stageKey, json_encode($stageConditions, 32));
                    oo::commonOprRedis('games')->hset($stageRewardKeys, $stageKey, json_encode($item3['stages'], 32));
                    oo::commonOprRedis('games')->hset($stageExtraConfKeys, $stageKey, json_encode(['treasureWeightConfig' => $item3['treasureWeightConfig'] ?? []], 32));

                }
            }
        }
        $SpinsRatioKey = okeys::treasureSpinsRatio($actConfig['aid']);
        oo::commonOprRedis('games')->set($SpinsRatioKey, $extraReward['spinsRatio']);
        oo::commonOprRedis('games')->expireAt($SpinsRatioKey, oo::redisRandomExpire($expireTime));

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

    function importActData(array &$basicConfig, $sheetArray)
    {

        $multiNumTypeReward = self::$multiNumTypeReward; #可以选择 非固定值的奖励类型
        $sheetIdx = 0;
        $basicConfArray = $sheetArray[$sheetIdx++] ?? [];
        $basicConfArray2 = $sheetArray[$sheetIdx++] ?? [];
        $stagesMappingArray = $sheetArray[$sheetIdx++] ?? [];
        $stagesRewardsArray = $sheetArray[$sheetIdx++] ?? [];


        $extraConfig = self::parseExtraBasicConfig($this->extraConfigFieldMapping, $basicConfArray2);
        $basicConfig = array_merge($basicConfig, $extraConfig);



        # 解析映射关系
        list($rewardsConfig, $idxMapping) = $this->parseLvSpinsShushuStagesMapping($stagesMappingArray);

        # 解析阶段奖励配置
        $taskTypeMap = [
            1 => '下注次数',
            2 => '获得金币',
            3 => 'Bonus Wheel',
        ];

        foreach ($stagesRewardsArray as $k => $item) {
            $filterLine = array_filter($item);
            if (empty($filterLine)) continue;
            $line = $k + 1;
            if ($k == 0) continue;

            list($idx, $roomIdx, $weightGroupText, $stageIdx, $taskType, $target, $frequency, $betStr) = $item;
            if (empty($idxMapping[$idx])) $this->response(-1, "第{$line}行,唯一id:{$idx} 无对应关系", $idxMapping);    #奖励不能为空
            list($idx1, $idx2, $idx3) = $idxMapping[$idx];

            $rewardsTemp = $this->parseLineRewards(array_slice($item, 8));
            if (empty($rewardsTemp)) $this->response(-1, "第{$line}行,奖励不能为空");    #奖励不能为空

            $taskType = array_search($taskType, $taskTypeMap);
            if (empty($taskType)) $this->response(-1, "任务类型不存在：{$item[0]},line:$line," . __LINE__);

            $betStr = strtr($betStr, ['，' => ',', ' ' => '']);
            $bet = explode(',', $betStr);
            $bet = array_filter(array_unique($bet));
            $rewardsIdx = $stageIdx - 1;
            $roomIdx--;
            $roomLength = count(rewardsConfig[$idx1]['stages'][$idx2]['stages'][$idx3]['stages']);
            if ($roomIdx < 0) $this->response(-1, "第{$line}行,房间号需从1开始" . __LINE__);
            if (!in_array($roomIdx, [$roomLength, $roomLength - 1]))$this->response(-1, "第{$line}行,房间号不连续,");
            if ($rewardsIdx < 0) $this->response(-1, "第{$line}行,阶段值从1开始" . __LINE__);
            if (empty($rewardsConfig[$idx1]['stages'][$idx2]['stages'][$idx3]['stages'][$roomIdx])){

                $weightGroupId =  $this->parseTreasureWeightGroups($weightGroupText, $line);
                if (empty($weightGroupId)) $this->response(-1, "权重分组不存在：{$weightGroupText},line:$line");
                $rewardsConfig[$idx1]['stages'][$idx2]['stages'][$idx3]['treasureWeightConfig'][$roomIdx] = [
                    'slotWeightGroup' => $weightGroupId,
                    'roomId' => $roomIdx,
                ];

                $rewardsConfig[$idx1]['stages'][$idx2]['stages'][$idx3]['stages'][$roomIdx] = [];
            }
            $rewardsConfig[$idx1]['stages'][$idx2]['stages'][$idx3]['stages'][$roomIdx][] = [
                'id' => $stageIdx,
                'taskType' => $taskType,
                'target' => $target,
                'frequency' => $frequency,
                'prize' => urlencode(json_encode($rewardsTemp)),
                'bet' => urlencode(json_encode($bet)),
            ];
        }
        $basicConfig['treasure'] = $rewardsConfig;
    }



    public function parseTreasureWeightGroups(string $slotWeightGroupName,$line = 0):int{
        if(empty($slotWeightGroupName))self::response(-1, $line.'行，权重分组为空');
        $this->getActBasicConfig();
        $groupsMapping = array_column(self::$weightGroupList, 'id', 'name');
        return intval($groupsMapping[$slotWeightGroupName]);
    }

    function getActBasicConfig(): array
    {
        if(empty(self::$weightGroupList)){
            $groupsTbl = otable::treasureProGroups();
            self::$weightGroupList = oo::commonOprDb('slavedb')->getAll("select * from {$groupsTbl}");
        }
        return ['list' => self::$weightGroupList];
    }
}