<?php

declare(strict_types=1);

use App\Jobs\ImportLeadsJob;
use App\Mail\ImportCompletedNotification;
use App\Models\Deal;
use App\Models\ImportLog;
use App\Models\Tenant;
use App\Models\User;
use App\Services\Import\CsvLeadsParser;
use App\Services\Import\HistoricalImportService;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use Tests\Concerns\SharesSupplierPdo;

uses(DatabaseTransactions::class, SharesSupplierPdo::class);
// ImportLeadsJob запускает HistoricalImportService → MonthlyPartitionManager →
// CREATE через pgsql_supplier. Нужен shared PDO.

beforeEach(function (): void {
    $this->tenant = Tenant::factory()->create();
    $this->user = User::factory()->for($this->tenant)->create();
    DB::statement('SET app.current_tenant_id = '.$this->tenant->id);
    Mail::fake();
    Storage::fake('local');
});

function storedCsv(int $tenantId, string $body): string
{
    $header = "\xEF\xBB\xBF".'id,Проект,Тег проекта,Телефон,Создано,Напоминание,Комментарий,Состояние,Имя';
    $path = "imports/{$tenantId}/test.csv";
    Storage::disk('local')->put($path, $header."\n".$body);

    return $path;
}

function runImportJob(int $logId, int $tenantId): void
{
    (new ImportLeadsJob($logId, $tenantId))->handle(
        app(HistoricalImportService::class),
        app(CsvLeadsParser::class),
    );
}

test('job импортирует лиды и переводит import_log в done', function (): void {
    $path = storedCsv($this->tenant->id,
        '7001,Окна,окна,79161112233,2023/05/10 10:00:00,,,Новые,Иван'
    );
    $log = ImportLog::create([
        'tenant_id' => $this->tenant->id,
        'user_id' => $this->user->id,
        'filename' => 'leads.csv',
        'file_path' => $path,
        'status' => 'pending',
    ]);

    runImportJob($log->id, $this->tenant->id);

    $log->refresh();
    expect($log->status)->toBe('done')
        ->and($log->rows_added)->toBe(1)
        ->and($log->finished_at)->not->toBeNull()
        ->and(Deal::query()->where('source_crm_id', 7001)->exists())->toBeTrue();

    Mail::assertSent(ImportCompletedNotification::class);
});

test('job переводит import_log в failed при отсутствии файла', function (): void {
    $log = ImportLog::create([
        'tenant_id' => $this->tenant->id,
        'user_id' => $this->user->id,
        'filename' => 'leads.csv',
        'file_path' => 'imports/missing.csv',
        'status' => 'pending',
    ]);

    runImportJob($log->id, $this->tenant->id);

    expect($log->refresh()->status)->toBe('failed')
        ->and($log->error_message)->not->toBeNull();
});

test('job пишет unknown_statuses_count и rows_skipped', function (): void {
    $path = storedCsv($this->tenant->id,
        "7002,Окна,окна,79161112234,2023/05/11 10:00:00,,,Архив,\n".
        '7003,Окна,окна,BADPHONE,2023/05/12 10:00:00,,,Новые,'
    );
    $log = ImportLog::create([
        'tenant_id' => $this->tenant->id,
        'user_id' => $this->user->id,
        'filename' => 'leads.csv',
        'file_path' => $path,
        'status' => 'pending',
    ]);

    runImportJob($log->id, $this->tenant->id);

    $log->refresh();
    expect($log->status)->toBe('done')
        ->and($log->unknown_statuses_count)->toBe(1)   // «Архив»
        ->and($log->rows_skipped)->toBe(1);            // битый телефон
});
