<?php

namespace app\middleware;

use Webman\Http\Request;
use Webman\Http\Response;
use Webman\MiddlewareInterface;
use GRPC\Auth\AuthClient;
use GRPC\Auth\ValidateJwtTokenReq;
use GRPC\Auth\JwtVerifyResult;

class Jwt implements MiddlewareInterface
{
    protected $authClient;

    public function __construct()
    {
        // 初始化 AuthClient
        $host             = "192.168.21.27:22101"; // 替换为你的 Auth 服务地址
        $this->authClient = new AuthClient($host);
    }

    public function process(Request $request, callable $handler): Response
    {
        // 从请求头中获取 JWT token
        $jwtToken = $request->header('Authorization');

        if (!$jwtToken) {
            return Json([
                'code' => 1,
                'msg' => 'Authorization token is missing',
                'data' => []
            ]);
        }

        // 去除 Bearer 前缀
        if (strpos($jwtToken, 'Bearer ') === 0) {
            $jwtToken = substr($jwtToken, 7);
        }
//        try {
            // 创建 GRPC 请求
//            dump($jwtToken);
            $grpcRequest = new ValidateJwtTokenReq();
            $grpcRequest->setJwtToken($jwtToken);
            // 调用 GRPC 服务
//            list($response, $status) = $this->authClient->ValidateJwtToken($grpcRequest);
            $responseAuth = $this->authClient->ValidateJwtToken($grpcRequest);


            // 检查验证结果
            // 获取验证结果
            $result = $responseAuth->getResult();

            // 根据验证结果返回不同的消息
            switch ($result) {
                case JwtVerifyResult::JWT_VERIFY_OK:
                    // Token 验证成功,继续执行下层逻辑
                    break;

                case JwtVerifyResult::JWT_VERIFY_BAD_FORMAT:
                    return Json([
                        'code' => 1,
                        'msg' => 'Invalid token format',
                        'data' => []
                    ]);

                case JwtVerifyResult::JWT_VERIFY_SIGN_FAILED:
                    return Json([
                        'code' => 1,
                        'msg' => 'Token signature is invalid',
                        'data' => []
                    ]);

                case JwtVerifyResult::JWT_VERIFY_EXPIRED:
                    return Json([
                        'code' => 1,
                        'msg' => 'Token has expired',
                        'data' => []
                    ]);

                case JwtVerifyResult::JWT_VERIFY_REVOKED:
                    return Json([
                        'code' => 1,
                        'msg' => 'Token has been revoked',
                        'data' => []
                    ]);

                case JwtVerifyResult::JWT_VERSION_LOW:
                    return Json([
                        'code' => 1,
                        'msg' => 'Token version is too low',
                        'data' => []
                    ]);

                default:
                    return Json([
                        'code' => 1,
                        'msg' => 'Unknown token verification error',
                        'data' => []
                    ]);
            }

            // 将解析的 claims 数据传递给下层业务逻辑
            $claims = $responseAuth->getClaims();

            if ($claims) {
                // 获取 uid 和 merchant_id
                $uid        = $claims->getUid();
                $merchantId = $claims->getMerchantId();

//                dump("UID: " . $uid);  // 打印 uid
//                dump("Merchant ID: " . $merchantId);  // 打印 merchant_id

                // 将 claims 数据附加到请求对象中,供后续使用
                $request->jwtClaims = [
                    'uid' => $uid,
                    'merchant_id' => $merchantId
                ];
            }

            // 检查是否存在新 token
            $newToken = $responseAuth->getNewToken();

            if ($newToken) {
                $request->jwtNewToken = $newToken;
//                response()->withHeader('X-New-Token',$newToken);
            }

            // 如果验证通过,则继续处理请求
            return $handler($request);
//        } catch (\Exception $e) {
//            return new Response(500, [], json_encode(['error' => 'Internal server error']));
//        }
    }
}