<?php

declare(strict_types=1);

use App\Models\Project;
use App\Models\ReportJob;
use App\Models\Tenant;
use App\Services\Reports\Providers\SourcesSummaryProvider;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;

uses(DatabaseTransactions::class);

beforeEach(function () {
    $this->tenant = Tenant::factory()->create();
    $this->project = Project::factory()->create(['tenant_id' => $this->tenant->id]);
});

function seedSourceDeal(int $tenantId, int $projectId, array $overrides = []): void
{
    DB::table('deals')->insert(array_merge([
        'tenant_id' => $tenantId,
        'project_id' => $projectId,
        'phone' => '+7999'.random_int(1000000, 9999999),
        'status' => 'new',
        'received_at' => Carbon::now()->startOfMonth()->addDays(10),
        'created_at' => Carbon::now(),
        'updated_at' => Carbon::now(),
    ], $overrides));
}

function sourcesJob(int $tenantId): ReportJob
{
    return new ReportJob([
        'tenant_id' => $tenantId,
        'type' => 'sources_summary',
        'parameters' => [
            'format' => 'csv',
            'date_from' => Carbon::now()->startOfMonth()->toDateString(),
            'date_to' => Carbon::now()->endOfMonth()->toDateString(),
        ],
    ]);
}

test('headers: 4 колонки', function () {
    expect((new SourcesSummaryProvider)->headers())
        ->toBe(['Источник', 'Всего сделок', 'Оплачено', 'Конверсия (%)']);
});

test('slug = sources', function () {
    expect((new SourcesSummaryProvider)->slug())->toBe('sources');
});

test('агрегирует сделки по utm_source', function () {
    seedSourceDeal($this->tenant->id, $this->project->id, ['utm_source' => 'yandex', 'status' => 'won']);
    seedSourceDeal($this->tenant->id, $this->project->id, ['utm_source' => 'yandex', 'status' => 'new']);
    seedSourceDeal($this->tenant->id, $this->project->id, ['utm_source' => 'vk', 'status' => 'won']);

    $rows = (new SourcesSummaryProvider)->rows(sourcesJob($this->tenant->id));

    expect($rows)->toHaveCount(2);
    // ORDER BY COUNT(*) DESC → yandex (2) первый.
    expect($rows[0])->toBe(['yandex', 2, 1, 50.0]);
    expect($rows[1])->toBe(['vk', 1, 1, 100.0]);
});

test('сделки без utm_source → «Прямые / без метки»', function () {
    seedSourceDeal($this->tenant->id, $this->project->id, ['utm_source' => null]);

    $rows = (new SourcesSummaryProvider)->rows(sourcesJob($this->tenant->id));

    expect($rows)->toHaveCount(1);
    expect($rows[0][0])->toBe('Прямые / без метки');
});

test('исключает soft-deleted и тестовые сделки', function () {
    seedSourceDeal($this->tenant->id, $this->project->id, ['utm_source' => 'yandex']);
    seedSourceDeal($this->tenant->id, $this->project->id, ['utm_source' => 'yandex', 'deleted_at' => Carbon::now()]);
    seedSourceDeal($this->tenant->id, $this->project->id, ['utm_source' => 'yandex', 'is_test' => true]);

    $rows = (new SourcesSummaryProvider)->rows(sourcesJob($this->tenant->id));

    expect($rows)->toHaveCount(1);
    expect($rows[0][1])->toBe(1);
});

test('изолирует по tenant_id', function () {
    $other = Tenant::factory()->create();
    $otherProject = Project::factory()->create(['tenant_id' => $other->id]);
    seedSourceDeal($other->id, $otherProject->id, ['utm_source' => 'yandex']);

    $rows = (new SourcesSummaryProvider)->rows(sourcesJob($this->tenant->id));

    expect($rows)->toBe([]);
});
