<?php

class LuckDiceActModel extends ActBaseModel implements ActInterface
{
    function formatActData(array &$actConfig)
    {

        if (empty($actConfig['luckyDiceConf']['extraConf']['openLv']))$this->response(__LINE__, '配置异常， 开放等级为空', $actConfig['luckyDiceConf']);
        if (empty($actConfig['luckyDiceConf']['extraConf']['spinsRatio']))$this->response(__LINE__, '配置异常, 体力系数为空', $actConfig['luckyDiceConf']);

        $actConfig['extraData'] = json_encode($actConfig['luckyDiceConf']['extraConf'], JSON_NUMERIC_CHECK);
        $actConfig['extra_reward'] = json_encode([
            "prdConf" => $actConfig['luckyDiceConf']['prdConf']
        ], JSON_NUMERIC_CHECK);

        if(empty($actConfig['luckyDiceConf']['rewardConf']))$this->response(__LINE__, '阶段配置异常1', $actConfig['luckyDiceConf']);
        foreach ($actConfig['luckyDiceConf']['rewardConf'] as $lvIdx => &$lvItem){
            if (empty($lvItem['stages']))$this->response(__LINE__, '阶段配置异常2', $actConfig['luckyDiceConf']);

            foreach ($lvItem['stages'] as $yIdx => &$yItem){
                if (empty($yItem['stages']))$this->response(__LINE__, '配置异常', $actConfig['luckyDiceConf']);

                foreach ($yItem['stages'] as $ssIdx => &$ssItem){
                    if (empty($ssItem['stages']['tasks']))$this->response(__LINE__, '配置异常', $actConfig['luckyDiceConf']);
                    foreach ($ssItem['stages']['tasks'] as $tIdx => &$task){
                        $tKey = $tIdx + 1;
                        if (empty($task['target']))$this->response(__LINE__, "第{$lvIdx}层等级区间，第{$yIdx}层Y值区间，第{$ssIdx}层数数层，第{$tKey}个任务，任务值为空", $actConfig['luckyDiceConf']);
                        if (empty($task['bet']))$this->response(__LINE__, "第{$lvIdx}层等级区间，第{$yIdx}层Y值区间，第{$ssIdx}层数数层，第{$tKey}个任务，下注值为空", $actConfig['luckyDiceConf']);
                        if (empty($task['prize']))$this->response(__LINE__, "第{$lvIdx}层等级区间，第{$yIdx}层Y值区间，第{$ssIdx}层数数层，第{$tKey}个任务，奖励为空", $actConfig['luckyDiceConf']);
                    }
                }
            }
        }
//        if(empty($actConfig['luckyDiceConf']['rankConfGroup']))$this->response(__LINE__, '排名分组异常', $actConfig['luckyDiceConf']);
//        if(empty($actConfig['luckyDiceConf']['rankConf']))$this->response(__LINE__, '排名配置异常', $actConfig['luckyDiceConf']);
        $rankConf =[];
        foreach ($actConfig['luckyDiceConf']['rankConfGroup'] as $gid=>$item){
            if($item['lv_start']>=$item['lv_end']){
                $this->response(__LINE__, '等级区间异常', $item);
            }
            if($item['coinY_end']!=-1&&$item['coinY_start']>=$item['coinY_end']){
                $this->response(__LINE__, 'coinY区间异常', $item);
            }
            $conditions =[
                ["start"=>$item['lv_start'],"end"=>$item['lv_end'],"shushu"=>[],"type"=>"level"],
                ["start"=>$item['coinY_start'],"end"=>$item['coinY_end'],"shushu"=>[],"type"=>"coinY"],
                ["start"=>0,"end"=>0,"shushu"=>$item['shushu'],"type"=>"shushu"]
            ];
            $rooms =[];
            if(empty($actConfig['luckyDiceConf']['rankConf'][$gid]))$this->response(__LINE__, "分组{$gid}内排名配置异常", $actConfig['luckyDiceConf']['rankConf']);
            foreach($actConfig['luckyDiceConf']['rankConf'][$gid] as $idx=>$item2){
                if(empty($item2['prize']))$this->response(__LINE__, "分组{$gid}内第{$idx}行排名奖励配置异常", $item2);
                $roomsOne =[
                    "id"=>$idx+1,
                    "rankPos"=>$item2['rankPos'],
                    "prize"=>$item2['prize'],
                ];
                $rooms[] = $roomsOne;
            }
            $rankConfOne =[
                "id"=>$gid,
                "shushu"=>$item['shushu'],
                "lv_start"=>$item['lv_start'],
                "lv_end"=>$item['lv_end'],
                "coinY_start"=>$item['coinY_start'],
                "coinY_end"=>$item['coinY_end'],
                "rooms"=>$rooms,
                "conditions"=>$conditions
            ];
            $rankConf[]= $rankConfOne;
        }

        $actConfig['reward_info'] = json_encode($actConfig['luckyDiceConf']['rewardConf'], JSON_NUMERIC_CHECK);
        $actConfig['pro'] = $rankConf;

        unset($actConfig['luckyDiceConf']);
    }

    function writeActCache(array $actConfig)
    {
        $aid = $actConfig["aid"];
        $conditionKeys = okeys::activityConditionKeys($aid);
        $stageRewardKeys = okeys::activityRewardsStageKeys($aid);

        $extraData = json_decode($actConfig['extraData'], true) ?? [];
        $rewardInfo = json_decode($actConfig['reward_info'], true) ?? [];
        $expireTime = max($actConfig['end_time'], time() + 60);#redis最少一分钟
        foreach ($rewardInfo 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_LV],
                        ['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));
                }
            }
        }
        $SpinsRatioKey = okeys::treasureSpinsRatio($aid);
        oo::commonOprRedis('games')->set($SpinsRatioKey, $extraData['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));
    }

    function serializeShowConf(array &$actConfig)
    {
    }

    function importActData(array &$basicConfig, $sheetArray)
    {
        if (count($sheetArray) < 7) {
            $this->response(-1 * __LINE__, "工作表数量不匹配");
        }

        $sheet2 = $sheetArray[1] ?? [];
        $sheet3 = $sheetArray[2] ?? [];
        $sheet4 = $sheetArray[3] ?? [];
        $sheet5 = $sheetArray[4] ?? [];
        $sheet6 = $sheetArray[5] ?? [];
        $sheet7 = $sheetArray[6] ?? [];

        $extraConf = $this->parseExtraSheet($sheet2);
        $prdConf = $this->parsePrdSheet($sheet3);
        $stageConf = $this->parseStageSheet($sheet4);
        $rewardConf = $this->parseRewardSheet($sheet5);
        $rankConf = $this->parseRankSheet($sheet6);
        $rankRewardConf = $this->parseRankRewardSheet($sheet7);
        $basicConfig['luckyDiceConf'] = $this->packageConf($extraConf, $prdConf, $stageConf, $rewardConf,$rankConf, $rankRewardConf);
    }

    private function parseExtraSheet(array $sheet): array
    {
        $baseConfig = ["openLv" => 0, "spinsRatio" => 0, "resultMul" => []];
        foreach ($sheet as $item) {
            $label = trim($item[0]);
            if (empty($label)) {
                continue;
            }
            $value = $item[1];
            switch ($label) {
                case '开放等级':
                    $baseConfig['openLv'] = $value;
                    break;
                case '任务可选':
                    $baseConfig['canSelectTask'] = $value == '是' ? 1 : 0;
                    break;
                case '体力存量系数':
                    $baseConfig['spinsRatio'] = $value;
                    break;
                case '豹子倍数':
                    $baseConfig['resultMul'][] = ["type" => "AAA", "mul" => $value];
                    break;
                case '顺子倍数':
                    $baseConfig['resultMul'][] = ["type" => "ABC", "mul" => $value];
                    break;
                case '对子倍数':
                    $baseConfig['resultMul'][] = ["type" => "AA", "mul" => $value];
                    break;
            }
        }

        return $baseConfig;
    }

    private function parsePrdSheet(array $sheet): array
    {
        $prdConf = [];
        for ($i = 1; $i < count($sheet); $i++) {
            $row = $sheet[$i];
            if (empty(array_filter($row))) {
                continue;
            }

            $line = $i + 1;
            list($prdLv, $co1, $co2) = $row;
            if ($prdLv != count($prdConf) + 1) $this->response(-1, "第{$line}行,prd配置等级不连续");

            $prdConf[$prdLv] = [$co1, $co2];
        }

        return $prdConf;
    }

    private function parseStageSheet(array $sheet): array
    {
        $rewardsConfig = [];
        self::$actGroupMapping=[];
        for ($i = 1; $i < count($sheet); $i++) {
            $row = $sheet[$i];
            if (empty(array_filter($row))) {
                continue;
            }

            list($idx, $lvMin, $lvMax, $yMin, $yMax, $ssGroup) = $row;
            $yKey = "{$yMin}-$yMax";
            $lvKey = "{$lvMin}-$lvMax";

            $lvIdx = $this->getGroupMappingIdx(CONDITION_TYPE_LV, $lvKey);
            $yIdx = $this->getGroupMappingIdx(CONDITION_TYPE_COIN_Y, $yKey, $lvIdx);
            $ssIdx = $this->getGroupMappingIdx(CONDITION_TYPE_SHUSHU, $ssGroup, "{$yIdx}_{$lvIdx}");

            if (empty($rewardsConfig[$lvIdx]))
                $rewardsConfig[$lvIdx] = [
                    'stages' => [],
                    'start' => $lvMin,
                    'end' => $lvMax,
                ];
            if (empty($rewardsConfig[$lvIdx]['stages'][$yIdx]))
                $rewardsConfig[$lvIdx]['stages'][$yIdx] = [
                    'stages' => [],
                    'start' => $yMin,
                    'end' => $yMax,
                ];

            $shushus = $this->parseShushuGroups($ssGroup);
            if (empty($rewardsConfig[$lvIdx]['stages'][$yIdx]['stages'][$ssIdx]))
                $rewardsConfig[$lvIdx]['stages'][$yIdx]['stages'][$ssIdx] = [
                    'idx' => $idx,
                    'stages' => [],
                    'shushu' => $shushus,
                ];
        }

        return $rewardsConfig;
    }

    private function parseRewardSheet(array $sheet): array
    {
        $rewardArrMap = [];

        # 解析阶段奖励配置
        $taskTypeMap = [
            1 => '投掷骰子',
            2 => '获得金币',
            3 => 'HUGE WIN',
            4 => '在对子中获得金币' ,
            5 => '在顺子中获得金币' ,
            6 => '在豹子中获得金币' ,
        ];

        for ($i = 1; $i < count($sheet); $i++) {
            $row = $sheet[$i];
            if (empty(array_filter($row))) {
                continue;
            }
            $line = $i + 1;

            list($idx, $stageIdx, $taskStr, $target, $betStr) = $row;

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

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

            $bet = explode(',', strtr($betStr, ['，' => ',', ' ' => '']));
            $bet = array_filter($bet);

            $rewardArrMap[$idx][] = [
                'id' => $stageIdx,
                'taskType' => $taskType,
                'target' => $target,
                'prize' => $prize,
                'bet' => $bet,
            ];
        }

        return $rewardArrMap;
    }

    private function parseRankSheet(array $sheet): array
    {
        $rankConfGroup = [];
        self::$actGroupMapping=[];
        for ($i = 1; $i < count($sheet); $i++) {
            $row = $sheet[$i];
            if (empty(array_filter($row))) {
                continue;
            }

            list($idx, $lvMin, $lvMax, $yMin, $yMax, $ssGroup) = $row;
            $shushus = $this->parseShushuGroups($ssGroup);
            $rankConfGroup[$idx] = [
                "shushu"=>$shushus,
                "lv_start"=>$lvMin,
                "lv_end"=>$lvMax,
                "coinY_start"=>$yMin,
                "coinY_end"=>$yMax,
            ];

        }
        return $rankConfGroup;
    }
    private function parseRankRewardSheet(array $sheet): array
    {
        $rewardArrMap = [];

        for ($i = 1; $i < count($sheet); $i++) {
            $row = $sheet[$i];
            if (empty(array_filter($row))) {
                continue;
            }
            $line = $i + 1;

            list($idx, $rankPos) = $row;

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


            $rewardArrMap[$idx][] = [
                'rankPos' => $rankPos,
                'prize' => $prize,
            ];
        }
        return $rewardArrMap;
    }

    private function packageConf(array $extraConf, array $prdConf, array $stageConf, array $rewardConf, array $rankConfGroup, array $rankRewardConf): array
    {
        $luckyDiceConf = [];

        $luckyDiceConf['extraConf'] = $extraConf;
        $luckyDiceConf['prdConf'] = $prdConf;

        foreach ($stageConf as &$item) {
            foreach ($item['stages'] as &$item2) {
                foreach ($item2['stages'] as &$item3) {
                    $id = $item3['idx'];
                    unset($item3['idx']);

                    $item3['stages'] = [
                        'tasks' => $rewardConf[$id] ?? [],
                    ];
                    if (empty($item3['stages']['tasks'])) {
                        $this->response(-1 * __LINE__, "唯一ID:{$id}, 任务配置为空");
                    }
                }
            }
        }
        $i=0;
        foreach ($rankConfGroup as $gid=>$item4){
            $rankConfGroupNew[$i] = $item4;
            if (empty($rankRewardConf[$gid])) $this->response(-1, "分组{$gid},排名奖励未配置");
            $rankRewardConfNew[$i] = $rankRewardConf[$gid];
            $i++;
        }
        $luckyDiceConf['rewardConf'] = $stageConf;
        $luckyDiceConf['rankConf'] = $rankRewardConfNew;
        $luckyDiceConf['rankConfGroup'] = $rankConfGroupNew;
        return $luckyDiceConf;
    }

}