<?php

namespace App\Services;

use App\Models\Client;
use App\Models\Log;
use Illuminate\Database\Eloquent\Builder;

class EmailMarketingSegmentService
{
    public const CRITERIA = ['active_clients', 'product_owners', 'country', 'client_group', 'domain_tld', 'domain_searchers_no_purchase'];

    public function query(string $criterion, array $params): Builder
    {
        return match ($criterion) {
            'active_clients' => Client::query()->where('status', 'active'),

            'product_owners' => Client::query()->whereHas('products', fn ($q) => $q
                ->where('status', 'active')
                ->where('product_id', (int) ($params['product_id'] ?? 0))
            ),

            'country' => Client::query()->whereHas('country', fn ($q) => $q
                ->where('a2_iso', strtoupper((string) ($params['country_code'] ?? '')))
            ),

            'client_group' => Client::query()->where('group_id', (int) ($params['client_group_id'] ?? 0)),

            // PRC-734 — seçili TLD('ler)de AKTİF domaini olan müşteriler (çoklu TLD).
            // Eşleşme tld_id ile (indexed); yalnız status='active' domainler.
            'domain_tld' => Client::query()->whereHas('domains', fn ($q) => $q
                ->where('status', 'active')
                ->whereIn('tld_id', array_map('intval', (array) ($params['tld_ids'] ?? [])))
            ),

            // PRC-793 — "sorgulandı ama alınmadı" retargeting lead'i: son N günde
            // domain araması yapmış (client_id'li log) ve AKTİF domaini olmayan müşteriler.
            'domain_searchers_no_purchase' => Client::query()
                ->whereIn('id', function ($q) use ($params) {
                    $q->select('client_id')->from('logs')
                        ->where('type', Log::TYPE_DOMAIN_SEARCH)
                        ->whereNotNull('client_id')
                        ->where('created_at', '>=', now()->subDays(max(1, (int) ($params['days'] ?? 30))));
                })
                ->whereDoesntHave('domains', fn ($q) => $q->where('status', 'active')),

            default => Client::query()->whereRaw('1 = 0'),
        };
    }

    public function preview(string $criterion, array $params): int
    {
        return $this->query($criterion, $params)->count();
    }

    public function emails(string $criterion, array $params): \Generator
    {
        foreach ($this->query($criterion, $params)->cursor() as $client) {
            if (! $client->email) {
                continue;
            }
            yield [
                'email' => $client->email,
                'first_name' => $client->first_name ?? null,
                'last_name' => $client->last_name ?? null,
                'client_id' => $client->id,
            ];
        }
    }
}
