<?php

declare(strict_types=1);

namespace app\api\controller\v1;

use ba\Random;
use Throwable;
use app\common\controller\Api;
use app\common\facade\Token;
use app\common\library\Auth as UserAuth;
use app\common\model\MallUserAsset;
use Webman\Http\Request;
use support\Response;

/**
 * API v1 鉴权接口
 */
class Auth extends Api
{

    /**
     * 临时登录 token 有效期（秒）
     */
    protected int $tempTokenExpire = 86400;

    /**
     * H5 临时登录（GET/POST）
     * 参数：username
     * 写入或复用 mall_user_asset；签发 muser 类型 token（user_id 为资产表主键）
     */
    public function temLogin(Request $request): Response
    {
        $response = $this->initializeApi($request);
        if ($response !== null) {
            return $response;
        }

        $enabled = config('buildadmin.temp_login.enable', false);
        if (!$enabled) {
            return $this->error(__('Temp login is disabled'));
        }

        $username = trim(strval($request->get('username', $request->post('username', ''))));
        // 兼容：querystring 中未编码的 '+' 会被解析为空格（application/x-www-form-urlencoded 规则）
        // 例如：/api/v1/temLogin?username=+607... 期望保留 '+'，则从原始 querystring 提取并还原
        if ($username !== '' && str_contains($username, ' ')) {
            $qs = $request->queryString();
            if (is_string($qs) && $qs !== '') {
                foreach (explode('&', $qs) as $pair) {
                    if ($pair === '' || !str_contains($pair, '=')) {
                        continue;
                    }
                    [$k, $v] = explode('=', $pair, 2);
                    if (rawurldecode($k) === 'username') {
                        // 先把 %xx 解码；注意这里不把 '+' 当空格处理，从而保留 '+'
                        $username = trim(rawurldecode($v));
                        break;
                    }
                }
            }
        }
        if ($username === '') {
            return $this->error(__('Parameter username can not be empty'));
        }

        try {
            $asset = MallUserAsset::ensureForUsername($username);
        } catch (Throwable $e) {
            return $this->error($e->getMessage());
        }

        $token = Random::uuid();
        $refreshToken = Random::uuid();
        $expire = config('buildadmin.temp_login.expire', $this->tempTokenExpire);
        $assetId = intval($asset->getKey());
        Token::set($token, UserAuth::TOKEN_TYPE_MALL_USER, $assetId, $expire);
        Token::set($refreshToken, UserAuth::TOKEN_TYPE_MALL_USER . '-refresh', $assetId, 2592000);

        return $this->success('', [
            'userInfo' => [
                'id' => $assetId,
                'username' => strval($asset->username ?? ''),
                'nickname' => strval($asset->username ?? ''),
                'playx_user_id' => strval($asset->playx_user_id ?? ''),
                'token' => $token,
                'refresh_token' => $refreshToken,
                'expires_in' => $expire,
            ],
        ]);
    }
}
