<?php

namespace Controllers;

use Libs\ResponseLib;
use Psr\Http\Message\ServerRequestInterface;
use React\Http\Message\Response;

class B3TokenController
{
    public function __invoke(ServerRequestInterface $request)
    {
        $b3Url = $_ENV['B3_URL'] ?? null;
        $clientId = $_ENV['CLIENT_ID'] ?? null;
        $clientSecret = $_ENV['CLIENT_SECRET'] ?? null;
        $grantType = $_ENV['GRANT_TYPE'] ?? 'client_credentials';
        $certPass = $_ENV['CERT_PASS'] ?? null;

        if (!$b3Url || !$grantType || !$clientId || !$clientSecret) {
            return ResponseLib::sendFail('Missing required env vars: B3_URL, GRANT_TYPE, CLIENT_ID, CLIENT_SECRET', [], 'E_VALIDATE')->withStatus(500);
        }

        $certPath = dirname(__DIR__) . DIRECTORY_SEPARATOR . '319245319-320109623_PROD.cer';
        $keyPath  = dirname(__DIR__) . DIRECTORY_SEPARATOR . '319245319-320109623_PROD.key';
        if (!file_exists($certPath) || !file_exists($keyPath)) {
            return ResponseLib::sendFail('Client certificate or key not found', ['cert' => $certPath, 'key' => $keyPath], 'E_INTERNAL')->withStatus(500);
        }

        // Send grant_type + client credentials in body in the same order as the working curl
        $postFields = 'grant_type=' . ($grantType);

        $ch = curl_init($b3Url);
        curl_setopt($ch, CURLOPT_POST, true);
        $headers = [
            'Content-Type: application/x-www-form-urlencoded',
            'Accept: application/json',
        ];
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        // mTLS client certificate
        curl_setopt($ch, CURLOPT_SSLCERT, $certPath);
        curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
        curl_setopt($ch, CURLOPT_SSLKEY, $keyPath);
        curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
        if ($certPass) {
            curl_setopt($ch, CURLOPT_SSLKEYPASSWD, $certPass);
        }
        // Keep verification enabled (recommended)
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);

        $responseBody = curl_exec($ch);
        $curlErrNo = curl_errno($ch);
        $curlErr = curl_error($ch);
        $httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($curlErrNo !== 0) {
            return ResponseLib::sendFail('cURL error during B3 token request', ['error' => $curlErr, 'code' => $curlErrNo], 'E_EXTERNAL')->withStatus(502);
        }

        $decoded = json_decode($responseBody, true);
        if ($decoded === null) {
            // Not a JSON body; return raw text for troubleshooting
            return Response::json(['raw' => $responseBody, 'status' => $httpCode])->withStatus($httpCode ?: 502);
        }

        return Response::json($decoded)->withStatus($httpCode ?: 200);
    }
}
