<?php

namespace App\Services;

use Illuminate\Http\Exceptions\HttpResponseException;

class GoogleAuthService
{
    /**
     * Verify a Google ID token and return its payload.
     *
     * Uses Google's tokeninfo endpoint via PHP's built-in file_get_contents
     * (no extra composer package required — guzzlehttp/guzzle is NOT
     * installed in this project, so the Http facade is unavailable).
     *
     * @see https://developers.google.com/identity/sign-in/web/backend-auth
     *
     * @return array{sub: string, email: string, name: string, picture: ?string, email_verified: string, aud: string}
     */
    public function verifyIdToken(string $idToken): array
    {
        $url = 'https://oauth2.googleapis.com/tokeninfo?id_token=' . urlencode($idToken);

        $context = stream_context_create([
            'http' => [
                'method'        => 'GET',
                'timeout'       => 10,
                'ignore_errors' => true, // capture 4xx/5xx response bodies instead of throwing
            ],
        ]);

        $body = @file_get_contents($url, false, $context);

        if ($body === false) {
            $this->abort('Could not reach Google to verify sign-in. Please try again.');
        }

        // Check HTTP status from the response headers (e.g. "HTTP/1.1 400 Bad Request")
        $statusLine = $http_response_header[0] ?? '';
        if (! preg_match('/\s(\d{3})\s/', $statusLine, $matches) || $matches[1] !== '200') {
            $this->abort('Invalid Google token.');
        }

        $payload = json_decode($body, true);

        if (! is_array($payload)) {
            $this->abort('Unexpected response from Google.');
        }

        // Verify the token was issued for OUR app (prevents token substitution attacks)
        $expectedClientId = config('services.google.client_id');
        if ($expectedClientId && ($payload['aud'] ?? null) !== $expectedClientId) {
            $this->abort('Google token was not issued for this app.');
        }

        if (empty($payload['sub']) || empty($payload['email'])) {
            $this->abort('Google token payload is incomplete.');
        }

        if (($payload['email_verified'] ?? 'false') !== 'true') {
            $this->abort('Google email is not verified.');
        }

        return $payload;
    }

    private function abort(string $message): never
    {
        throw new HttpResponseException(
            response()->json(['message' => $message], 401)
        );
    }
}
