<?php

namespace App\Services\Integrations;

use App\Models\PlatformConnection;
use App\Services\Credentials\CredentialVault;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;

class GoogleOAuthService
{
    public function __construct(private readonly CredentialVault $vault) {}

    public function scopesFor(string $platform): array
    {
        return match ($platform) {
            'google_ads' => ['https://www.googleapis.com/auth/adwords'],
            'search_console' => ['https://www.googleapis.com/auth/webmasters.readonly'],
            'ga4' => ['https://www.googleapis.com/auth/analytics.readonly'],
            default => [],
        };
    }

    public function redirectUrl(): string
    {
        return route('admin.integrations.google.callback');
    }

    public function authorizationUrl(PlatformConnection $connection): string
    {
        $payload = $this->vault->payload($connection->secureCredential);
        $clientId = $payload['google_client_id'] ?? $payload['client_id'] ?? config('services.google.client_id', env('GOOGLE_CLIENT_ID'));

        if (blank($clientId)) {
            throw new \RuntimeException('Google Client ID bulunamadı. Önce bağlantı formundan Google Client ID girilmeli.');
        }

        $state = Str::random(48);
        session([
            'dw_google_oauth_state' => $state,
            'dw_google_oauth_connection_id' => $connection->id,
        ]);

        $query = http_build_query([
            'client_id' => $clientId,
            'redirect_uri' => $this->redirectUrl(),
            'response_type' => 'code',
            'scope' => implode(' ', $this->scopesFor($connection->platform)),
            'access_type' => 'offline',
            'prompt' => 'consent',
            'state' => $state,
            'include_granted_scopes' => 'true',
        ]);

        return 'https://accounts.google.com/o/oauth2/v2/auth?'.$query;
    }

    public function exchangeCode(PlatformConnection $connection, string $code): array
    {
        $payload = $this->vault->payload($connection->secureCredential);
        $clientId = $payload['google_client_id'] ?? $payload['client_id'] ?? config('services.google.client_id', env('GOOGLE_CLIENT_ID'));
        $clientSecret = $payload['google_client_secret'] ?? $payload['client_secret'] ?? config('services.google.client_secret', env('GOOGLE_CLIENT_SECRET'));

        if (blank($clientId) || blank($clientSecret)) {
            throw new \RuntimeException('Google Client ID / Client Secret eksik.');
        }

        $response = Http::asForm()->timeout(30)->post('https://oauth2.googleapis.com/token', [
            'code' => $code,
            'client_id' => $clientId,
            'client_secret' => $clientSecret,
            'redirect_uri' => $this->redirectUrl(),
            'grant_type' => 'authorization_code',
        ]);

        if (! $response->successful()) {
            throw new \RuntimeException('Google OAuth token alınamadı: '.$response->body());
        }

        return $response->json();
    }

    public function accessTokenFromRefreshToken(PlatformConnection $connection): string
    {
        $payload = $this->vault->payload($connection->secureCredential);
        $clientId = $payload['google_client_id'] ?? $payload['client_id'] ?? config('services.google.client_id', env('GOOGLE_CLIENT_ID'));
        $clientSecret = $payload['google_client_secret'] ?? $payload['client_secret'] ?? config('services.google.client_secret', env('GOOGLE_CLIENT_SECRET'));
        $refreshToken = $payload['refresh_token'] ?? null;

        if (blank($clientId) || blank($clientSecret) || blank($refreshToken)) {
            throw new \RuntimeException('Google OAuth için client_id, client_secret veya refresh_token eksik.');
        }

        $response = Http::asForm()->timeout(30)->post('https://oauth2.googleapis.com/token', [
            'client_id' => $clientId,
            'client_secret' => $clientSecret,
            'refresh_token' => $refreshToken,
            'grant_type' => 'refresh_token',
        ]);

        if (! $response->successful()) {
            throw new \RuntimeException('Google access token yenilenemedi: '.$response->body());
        }

        $tokens = $response->json();
        $this->vault->saveOAuthTokens($connection, $tokens);

        return $tokens['access_token'] ?? throw new \RuntimeException('Google access_token dönmedi.');
    }
}
