<?php
namespace Base\Service;

use Base\Model\PromoteModel;
use Base\Model\ApplyModel;
use Base\Facade\Request;

class ApplyService {

    const ENCRYPT_METHOD = 'AES-256-ECB';
    const ENCRYPT_KEY = 'WmtX1@#Landing&Download2048';
    const ENCRYPT_TYPE_DOWNLOAD = 1;
    const ENCRYPT_TYPE_LANDING_PAGE = 2;

    public static $enableStatusList = [
        '-1' => '打包失败',
        '0' => '打包失败',
        '1' => '打包成功 ',
        '2' => '准备打包 ',
        '3' => '打包中',
    ];

    public function __construct()
    {
    }

    public function checkApplyStatus($apply)
    {
        if ($apply['status'] == 0) {
            return [
                'status' => false,
                'message' => '游戏未审核',
            ];
        }
        if ($apply['offline_status'] == 1) {
            return [
                'status' => false,
                'message' => '游戏已下架',
            ];
        }
        if ($apply['enable_status'] != 1) {
            return [
                'status' => false,
                'message' => self::$enableStatusList[$apply['enable_status']] ?? '未知错误',
            ];
        }
        return [
            'status' => true,
            'message' => '游戏打包成功',
        ];
    }

    public function cancelGame($gameId, $promoteId) {
        $ids = [$promoteId];
        $list = M('promote', 'tab_')->field('id')->where('parent_id=' . $promoteId . ' or grand_id=' . $promoteId)->select();
        $ids = array_merge($ids, array_column($list, 'id'));

        $save['offline_status'] = 1;

        M('apply', 'tab_')->where(['game_id' => $gameId, 'promote_id' => ['in', $ids]])->save($save);
    }

    public function updateAfterPack($apply, $packageUrl, $plistUrl)
    {
        $data = [];
        $data['id'] = $apply['id'];
        $data['pack_url'] = $packageUrl;
        $data['dow_url'] = '/index.php?s=/Home/Down/down_file/game_id/' . $apply['game_id'] . '/promote_id/' . $apply['promote_id'];
        $data['dow_status'] = 1;
        $data['enable_status'] = 1;
        $data['dispose_id'] = 0;
        $data['dispose_time'] = time();
        $data['plist_url'] = $plistUrl;
        return M('Apply', 'tab_')->save($data);
    }

    public function getDownloadUrl($apply)
    {
        $host = C('DOMAIN_DOWNLOAD');
        $host = $host ? $host : Request::getHost();
        $code = $this->encodeApplyCode($apply, self::ENCRYPT_TYPE_DOWNLOAD);
        return $host . '/index.php?s=/Home/Package/download/code/' . $code;
    }

    public function getLandingPageUrl($apply)
    {
        $host = C('DOMAIN_DOWNLOAD');
        $host = $host ? $host : Request::getHost();
        $code = $this->encodeApplyCode($apply, self::ENCRYPT_TYPE_LANDING_PAGE);
        return $host . '/index.php?s=/Home/Home/landingPage/code/' . $code;
    }

    public function encodeApplyCode($apply, $type)
    {
        $expiresIn = 0;
        $data = [
            'promote_id' => $apply['promote_id'],
            'game_id' => $apply['game_id'],
            'expires_in' => $expiresIn,
            'created_at' => date('Y-m-d H:i:s'),
            'type' => $type
        ];

        $jsonStr = json_encode($data);
        return base64_encode(openssl_encrypt($jsonStr, self::ENCRYPT_METHOD, self::ENCRYPT_KEY));
    }

    public function decodeApplyCode($code)
    {
        $decryptStr = openssl_decrypt(base64_decode($code), self::ENCRYPT_METHOD, self::ENCRYPT_KEY);
        return json_decode($decryptStr, true);
    }

    public function checkApplyCode($data, $type)
    {
        if (
            !isset($data['promote_id']) ||
            !isset($data['game_id']) ||
            !isset($data['expires_in']) ||
            !isset($data['created_at']) ||
            !isset($data['type'])
        ) {
            return [
                'status' => false,
                'message' => '参数异常',
            ];
        }
        if ($data['type'] != $type) {
            return [
                'status' => false,
                'message' => '参数异常',
            ];
        }
        if ($data['expires_in'] > 0 && time() > (strtotime($data['created_at']) + $data['expires_in'])) {
            return [
                'status' => false,
                'message' => '链接已过期',
            ];
        }
        return [
            'status' => true,
            'message' => '验证成功',
        ];
    }

    public  function getPageIdentifier($url)
    {
        $params = $this->getUrlParams($url);
        $sValue = isset($params['s']) ? $params['s'] : '';
        $code = $this->getSParam($sValue, 'code');
        if ($code === null) {
            $gid = $this->getSParam($sValue, 'game_id');
            $pid = $this->getSParam($sValue, 'promote_id');
            $type = 0;
            if ($gid && $pid) {
                $type = 1;
            } else {
                $gid = $this->getSParam($sValue, 'gid');
                $pid = $this->getSParam($sValue, 'pid');
                $type = 2;
            }
            if ($gid === null || $gid === null) {
                return null;
            } else {
                return [
                    'game_id' => $gid,
                    'promote_id' => $pid,
                    'type' => $type,
                ];
            }
        }
        return ['code' => $code];
    }

    public function getSParam($sValue, $name)
    {
        $sValue = ltrim($sValue, '/');
        $sValue = rtrim($sValue, '.html');
        $rows = explode('/', $sValue);
        $codeIndex = null;
        foreach ($rows as $key => $value) {
            if ($key >= 3 && $value == $name) {
                $codeIndex = $key;
                break;
            }
        }
        if ($codeIndex !== null) {
            return $rows[$codeIndex + 1] ?? null;
        }
        return null;
    }

    public function getUrlParams($url)
    {
        $items = parse_url($url);
        $queryParts = explode('&', $items['query']);
        parse_str($items['query'], $params);
        return $params;
    }

    public function checkSociatyPerm($promote, $game)
    {
        if ($game['apply_auth'] == 1) {
            return true;
        }
        $promoteService = new PromoteService();
        $topPromote = $promoteService->getTopPromote($promote);
        $record = M('sociaty_games', 'tab_')->where(['game_id' => $game['id'], 'promote_id' => $topPromote['id']])->find();
        if ($record['status'] == 1) {
            return true;
        } else {
            return false;
        }
    }

    public function getSociatyGameIds($promote)
    {
        $promoteService = new PromoteService();
        $topPromote = $promoteService->getTopPromote($promote);
        $tempIds = M('sociaty_games', 'tab_')->where(['promote_id' => $topPromote['id']])->getField('game_id', true);
        $tempIds = $tempIds ?? [];
        $ids = M('game', 'tab_')->where(['apply_auth' => 1])->getField('id', true);
        $ids = $ids ?? [];
        return array_merge($tempIds, $ids);
    }
}