<?php

class LuckDiceActModel extends ActBaseModel implements ActInterface
{
    function formatActData(array &$actConfig)
    {
        $actConfig['extraData'] = json_encode($actConfig['luckyDiceConf']['extraConf'], JSON_NUMERIC_CHECK);

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

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

        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::luckyDiceSpinsRatio($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) < 5) {
            $this->response(-1 * __LINE__, "工作表数量不匹配");
        }

        $sheet2 = $sheetArray[1] ?? [];
        $sheet3 = $sheetArray[2] ?? [];
        $sheet4 = $sheetArray[3] ?? [];
        $sheet5 = $sheetArray[4] ?? [];

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

    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['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 = [];

        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',
        ];

        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 packageConf(array $extraConf, array $prdConf, array $stageConf, array $rewardConf): 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'] = $rewardConf[$id];
                    if (empty($item3['stages'])) {
                        $this->response(-1 * __LINE__, "唯一ID:{$id}, 奖励配置不存在");
                    }
                }
            }
        }
        $luckyDiceConf['rewardConf'] = $stageConf;

        return $luckyDiceConf;
    }

}