<?php

class TaskExpressActModel extends ActBaseModel implements ActInterface
{
    function getActBasicConfig(): array
    {
        return [
            'taskMap' => self::$taskMapping
        ];
    }

    function formatActData(array &$actConfig)
    {

        $gtype = self::getGtypeByActType($this->actType);
        if (empty($gtype))
            $this->response(__LINE__, "活动：{$this->actType} 无对应gtype");
        $gid = $gtype * 10000;
        $config = $actConfig['taskExpressConfig'];
        unset($actConfig['taskExpressConfig']);
        foreach ($config as  $i => &$item){
            $gid++;
            $wrapIdx = $i+1;
            $dayNum = 0;
            if (empty($item['price']))
                $this->response(__LINE__, "区间:{$wrapIdx} 激活价格为空");

            $sku = $this->getSkuByPrice($item['price']);
            if (empty($sku))
                $this->response(__LINE__, "区间:{$wrapIdx} 激活价格 {$item['price']} 无对应sku");
            $item['sku'] = $sku;
            $item['gtype'] = $gtype;
            $item['gid'] = $gid;

            if (empty($item['tasks']))
                $this->response(__LINE__, "区间:{$wrapIdx} 任务配置为空");

            if (empty($item['rewards']))
                $this->response(__LINE__, "区间:{$wrapIdx} 奖励配置为空");

            $taskIdMap = [];
            foreach ($item['tasks'] as &$task){
                $validDay = [$dayNum, $dayNum+1];
                if (!in_array($task['day'], $validDay))
                    $this->response(__LINE__, "区间:{$wrapIdx}  任务所在天不连续 {$dayNum}-{$task['day']}");
                $dayNum = $task['day'];
                $taskIdMap[$task['day']] = $taskIdMap[$task['day']] ?? 0;

                $task['id'] = ++$taskIdMap[$task['day']];
                foreach ([1,2,3] as $taskIdx) {

                    if (empty($task["task{$taskIdx}"]['target']))
                        $this->response(__LINE__, "区间:{$wrapIdx} 任务目标值为空", $task);

                    if (empty($task["task{$taskIdx}"]['score']))
                        $this->response(__LINE__, "区间:{$wrapIdx} 任务积分值为空", $task);
                }

            }

            foreach ($item['rewards'] as &$reward){
                $reward['free_prize'] = @json_decode(urldecode($reward['free_prize']), true) ?? [];
                $reward['payment_prize'] = @json_decode(urldecode($reward['payment_prize']), true) ?? [];

                if (empty($reward['free_prize']))
                    $this->response(__LINE__, "区间:{$wrapIdx} 等级：{$reward['lv']} 免费奖励为空");
                if (empty($reward['payment_prize']))
                    $this->response(__LINE__, "区间:{$wrapIdx} 等级：{$reward['lv']} 令牌奖励为空");

            }
        }

        $actConfig['reward_conf'] = $config;
    }

    function writeActCache(array $actConfig)
    {
        $conditionKeys = okeys::activityConditionKeys($actConfig['aid']);
        $stageRewardKeys = okeys::activityRewardsStageKeys($actConfig['aid']);
        $rewardConf = json_decode($actConfig['reward_conf'], true);
        foreach ($rewardConf as $idx => $item) {
            $condition = $this->getStageConditionLvSpinsShushu($item, $item, $item);
            $tasks = [];
            foreach ($item['tasks'] as $task){
                $tasks[$task['day']] = $tasks[$task['day']] ?? [
                    'day' => $task['day'],
                    'task1' => [],
                    'task2' => [],
                    'task3' => [],
                ];
                $tasks[$task['day']]['task1'][] = $task['task1'];
                $tasks[$task['day']]['task2'][] = $task['task2'];
                $tasks[$task['day']]['task3'][] = $task['task3'];
            }
            $stageConf = [
                'tasks' => array_values($tasks),
                'rewards' => $item['rewards'],
                'payment' => [
                    'price' => $item['price'],
                    'sku' => $item['sku'],
                    'gtype' => $item['gtype'],
                    'gid' => $item['gid'],
                ],
            ];


            oo::commonOprRedis('games')->hset($stageRewardKeys, $idx, json_encode($stageConf, 32));
            oo::commonOprRedis('games')->hset($conditionKeys, $idx, json_encode($condition, 32));
        }

        $expireTime = max($actConfig['end_time'], time() + 60);#redis最少一分钟
        oo::commonOprRedis('games')->expireAt($conditionKeys, oo::redisRandomExpire($expireTime));
        oo::commonOprRedis('games')->expireAt($stageRewardKeys, oo::redisRandomExpire($expireTime));
        return true;
    }

    function serializeShowConf(array &$actConfig)
    {

    }

    function importActData(array &$basicConfig, $sheetArray)
    {
        $sheetIdx = 0;
        $stagesMappingArray = $sheetArray[++$sheetIdx] ?? [];
        $taskSheet = $sheetArray[++$sheetIdx] ?? [];
        $freePrizeSheet = $sheetArray[++$sheetIdx] ?? [];
        $paymentPrizeSheet = $sheetArray[++$sheetIdx] ?? [];

        $rewardsConfig = $this->parseLvSpinsShushuStagesMappingV1($stagesMappingArray);

        $priceMap = [];
        foreach ($stagesMappingArray as $k => $item){
            if (empty($k))continue;
            $priceMap[$item[0]] = $item[6];

        }
        $taskMapping = $this->parseTaskMapping($taskSheet);

        $rewardsMapping = $this->parseFreePrizeMapping($freePrizeSheet);

        $rewardsMapping = $this->parsePaymentPrizeMapping($paymentPrizeSheet, $rewardsMapping);

        foreach ($rewardsConfig as $id => $item){
            if(empty($priceMap[$item['id']]))
                $this->response(__LINE__, "分层：{$item['id']} 无激活价格配置", $rewardsMapping);

            if(empty($rewardsMapping[$item['id']]))
                $this->response(__LINE__, "分层：{$item['id']} 无奖励配置", $rewardsMapping);

            if(empty($taskMapping[$item['id']]))
                $this->response(__LINE__, "分层：{$item['id']} 无任务配置", $taskMapping);

            $rewardsConfig[$id]['price'] = $priceMap[$item['id']];
            $rewardsConfig[$id]['tasks'] = $taskMapping[$item['id']];
            $rewardsConfig[$id]['rewards'] = array_values($rewardsMapping[$item['id']]);
        }

        $basicConfig['taskExpressConfig'] = $rewardsConfig;
    }

    private function parseTaskMapping($taskSheet){
        $taskMapping = [];
        $taskTypeMapping = array_flip(self::$taskMapping);
        for ($i=1; $i<count($taskSheet); $i++){
            $item = $taskSheet[$i];
            list($idx, $day) = $item;
            $taskMapping[$idx] = $taskMapping[$idx] ?? [];
            $taskRow = [
                'day' => $day
            ];
            $taskId = 0;
            while($taskId < 3){
                $taskId++;
                $idxOffset = 2 + ($taskId - 1) * 3;
                $taskTypeText = $item[$idxOffset++];
                if (empty($taskTypeMapping[$taskTypeText]))
                    $this->response(__LINE__, "任务:{$taskTypeText} 不存在");
                $target = $item[$idxOffset++];
                $score = $item[$idxOffset++];
                $taskRow["task{$taskId}"] = [
                    'task_type' => $taskTypeMapping[$taskTypeText],
                    'target' => $target,
                    'score' => $score,
                ];
            }
            $taskMapping[$idx][] = $taskRow;
        }
        return $taskMapping;
    }

    private function parseFreePrizeMapping($rewardsSheet){
        $rewardsMapping = [];
        for ($i=1; $i<count($rewardsSheet); $i++){
            $item = $rewardsSheet[$i];
            list($idx, $lv, $score) = $item;
            $rewardsMapping[$idx] = $rewardsMapping[$idx] ?? [];
            $prize = $this->parseLineRewards(array_slice($item, 3));
            $rewardsMapping[$idx][$lv] = [
                'lv' => $lv,
                'score' => $score,
                'free_prize' => urlencode(json_encode($prize)),
            ];

        }
        return $rewardsMapping;
    }

    private function parsePaymentPrizeMapping($rewardsSheet, $rewardsMapping){
        for ($i=1; $i<count($rewardsSheet); $i++){
            $item = $rewardsSheet[$i];
            list($idx, $lv) = $item;
            if (empty($rewardsMapping[$idx][$lv])) $this->response(__LINE__, "奖励层级异常：{$lv}", $rewardsMapping);

            $prize = $this->parseLineRewards(array_slice($item, 2));
            $rewardsMapping[$idx][$lv]['payment_prize'] = urlencode(json_encode($prize));

        }
        return $rewardsMapping;
    }
}