<?php

namespace App\Services\Sync;

use App\Models\PlatformConnection;
use App\Models\SearchConsolePageSnapshot;
use App\Models\SearchConsoleQuerySnapshot;
use App\Services\Credentials\CredentialVault;
use App\Services\Integrations\GoogleOAuthService;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;

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

    public function sync(PlatformConnection $connection, string $from, string $to): SyncResult
    {
        $started = microtime(true);

        try {
            $payload = $this->vault->payload($connection->secureCredential);
            $siteUrl = $payload['site_url'] ?? $connection->account_id ?? $connection->account_name;
            if (blank($siteUrl)) {
                return SyncResult::failed('Search Console site_url eksik.');
            }

            $queries = $this->syncDimension($connection, (string) $siteUrl, 'query', $from, $to);
            $pages = $this->syncDimension($connection, (string) $siteUrl, 'page', $from, $to);
            $duration = (int) round((microtime(true) - $started) * 1000);

            return SyncResult::success('Search Console verileri senkronize edildi.', [
                'queries' => $queries,
                'pages' => $pages,
            ], $duration);
        } catch (\Throwable $e) {
            $duration = (int) round((microtime(true) - $started) * 1000);

            return SyncResult::failed('Search Console senkronizasyonu başarısız.', $e->getMessage(), [], $duration);
        }
    }

    private function syncDimension(PlatformConnection $connection, string $siteUrl, string $dimension, string $from, string $to): int
    {
        $rows = $this->query($connection, $siteUrl, ['date', $dimension], $from, $to);
        $count = 0;

        foreach ($rows as $row) {
            $keys = $row['keys'] ?? [];
            $date = $keys[0] ?? null;
            $value = $keys[1] ?? null;
            if (blank($date) || blank($value)) {
                continue;
            }
            $hash = sha1($date.'|'.$dimension.'|'.$value);
            $payload = [
                'client_id' => $connection->client_id,
                'clicks' => (int) ($row['clicks'] ?? 0),
                'impressions' => (int) ($row['impressions'] ?? 0),
                'ctr' => (float) ($row['ctr'] ?? 0),
                'position' => (float) ($row['position'] ?? 0),
                'raw_json' => json_encode($row, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
            ];

            if ($dimension === 'query') {
                SearchConsoleQuerySnapshot::updateOrCreate(
                    ['platform_connection_id' => $connection->id, 'date' => $date, 'row_hash' => $hash],
                    array_merge($payload, ['query_text' => $value])
                );
            } else {
                SearchConsolePageSnapshot::updateOrCreate(
                    ['platform_connection_id' => $connection->id, 'date' => $date, 'row_hash' => $hash],
                    array_merge($payload, ['page_url' => $value])
                );
            }
            $count++;
        }

        return $count;
    }

    private function query(PlatformConnection $connection, string $siteUrl, array $dimensions, string $from, string $to): array
    {
        $encodedSite = rawurlencode($siteUrl);
        $endpoint = "https://www.googleapis.com/webmasters/v3/sites/{$encodedSite}/searchAnalytics/query";
        $response = Http::withToken($this->oauth->accessTokenFromRefreshToken($connection))->timeout(90)->post($endpoint, [
            'startDate' => $from,
            'endDate' => $to,
            'dimensions' => $dimensions,
            'rowLimit' => 25000,
            'startRow' => 0,
        ]);

        if (! $response->successful()) {
            throw new \RuntimeException('Search Console sorgusu başarısız: '.Str::limit($response->body(), 1000));
        }

        return $response->json('rows') ?? [];
    }
}
