<?php

namespace App\Services;

use App\Enums\KeywordStatus;
use App\Enums\ProjectStatus;
use App\Enums\SerpCheckStatus;
use App\Jobs\RunSerpCheck;
use App\Jobs\SubmitSerpCheck;
use App\Models\Keyword;
use App\Models\SerpCheck;
use App\Models\User;
use App\Serp\Data\SerpQuery;
use App\Serp\Operations\ActivationManager;
use App\Serp\SerpProviderRegistry;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;

final class SerpCheckCreator
{
    public function __construct(private SerpProviderRegistry $providers, private ActivationManager $activation) {}

    public function create(User $user, Keyword $keyword, bool $dispatch = true, string $origin = 'manual'): SerpCheck
    {
        $keyword->refresh()->loadMissing('project');
        if ($keyword->project->user_id !== $user->id || $keyword->status !== KeywordStatus::Active || $keyword->archived_at !== null || $keyword->project->status !== ProjectStatus::Active || $keyword->project->archived_at !== null) {
            throw ValidationException::withMessages(['serp' => 'Bu anahtar kelime için kontrol başlatılamaz.']);
        }if (! config('serp.enabled')) {
            throw ValidationException::withMessages(['serp' => 'SERP kontrol hizmeti henüz yapılandırılmamış.']);
        }$provider = $this->providers->resolve();
        if ($provider->key() === 'dataforseo' && ! $this->activation->allowsNormal()) {
            throw ValidationException::withMessages(['serp' => 'SERP kontrol hizmeti şu anda kullanılamıyor.']);
        }$query = new SerpQuery($keyword->phrase, $keyword->search_engine->value, $keyword->country_code, $keyword->language_code, $keyword->device->value, 10);
        if (! $provider->supports($query)) {
            throw ValidationException::withMessages(['serp' => 'Seçili hedef yapılandırılmış sağlayıcı tarafından desteklenmiyor.']);
        }if (! in_array($origin, ['manual', 'scheduled'], true)) {
            throw ValidationException::withMessages(['serp' => 'Geçersiz kontrol kaynağı.']);
        }$mode = $provider->key() === 'dataforseo' ? ($origin === 'manual' ? (string) config('serp.manual_mode') : (string) config('serp.automatic_mode')) : 'live';
        if (! in_array($mode, ['live', 'standard'], true)) {
            throw ValidationException::withMessages(['serp' => 'Geçersiz yürütme modu.']);
        }

return Cache::lock('serp-create:'.$keyword->id, 10)->block(3, function () use ($user, $keyword, $dispatch, $origin, $mode) {
            if ($keyword->serpChecks()->whereIn('status', ['pending', 'running'])->exists()) {
                throw ValidationException::withMessages(['serp' => 'Bu anahtar kelime için devam eden bir kontrol var.']);
            }$cool = (int) config('serp.keyword_cooldown_minutes');
            if ($keyword->serpChecks()->where('created_at', '>', now()->subMinutes($cool))->exists()) {
                throw ValidationException::withMessages(['serp' => 'Yeni kontrol için bekleme süresi henüz dolmadı.']);
            }$used = SerpCheck::whereHas('keyword.project', fn ($q) => $q->where('user_id', $user->id))->where('created_at', '>=', now()->startOfDay())->count();
            if ($used >= (int) config('serp.daily_user_quota')) {
                throw ValidationException::withMessages(['serp' => 'Günlük SERP kontrol kotanıza ulaştınız.']);
            }$check = DB::transaction(fn () => $keyword->serpChecks()->create(['phrase' => $keyword->phrase, 'status' => SerpCheckStatus::Pending, 'active_slot' => 'active', 'search_engine' => $keyword->search_engine, 'country_code' => $keyword->country_code, 'language_code' => $keyword->language_code, 'device' => $keyword->device, 'provider' => config('serp.provider'), 'execution_mode' => $mode, 'origin' => $origin, 'result_count' => 0]));
            if ($dispatch) {
                $job = $mode === 'standard' ? new SubmitSerpCheck($check->ulid) : new RunSerpCheck($check->ulid);
                dispatch($job->onQueue(config('serp.queue')))->afterCommit();
            }

return $check;
        });
    }
}
