<?php

declare(strict_types=1);

use App\Models\Deal;
use App\Models\Project;
use App\Models\Tenant;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;

/**
 * Тесты POST /api/deals/export — экспорт по диапазону дат поставки.
 *
 * Редизайн «Сделки» (2026-05-17, Task A5): вместо ids[] — received_from/received_to.
 * Конвенции: DatabaseTransactions + actingAs + SET app.current_tenant_id
 * (аналогично DealIndexTest.php).
 */
uses(DatabaseTransactions::class);

beforeEach(function () {
    $this->tenant = Tenant::factory()->create();
    $this->user = User::factory()->for($this->tenant)->create();
    $this->actingAs($this->user);
    DB::statement('SET app.current_tenant_id = '.$this->tenant->id);
    $this->project = Project::factory()->for($this->tenant)->create(['name' => 'Окна Москва']);
});

test('POST /api/deals/export требует auth', function () {
    auth()->logout();
    $this->postJson('/api/deals/export', ['format' => 'csv'])->assertStatus(401);
});

test('POST /api/deals/export csv возвращает сделки в диапазоне дат', function () {
    Deal::factory()->for($this->tenant)->for($this->project)->create([
        'phone' => '+7 999 111-11-11', 'received_at' => '2026-05-15 10:00:00',
    ]);
    Deal::factory()->for($this->tenant)->for($this->project)->create([
        'phone' => '+7 999 222-22-22', 'received_at' => '2026-05-25 10:00:00',
    ]);

    $r = $this->post('/api/deals/export', [
        'received_from' => '2026-05-14', 'received_to' => '2026-05-16', 'format' => 'csv',
    ]);

    $r->assertStatus(200);
    $r->assertHeader('content-type', 'text/csv; charset=utf-8');
    $body = $r->streamedContent();
    expect($body)->toContain('+7 999 111-11-11');
    expect($body)->not->toContain('+7 999 222-22-22');
});

test('POST /api/deals/export xlsx отдаёт spreadsheet content-type', function () {
    Deal::factory()->for($this->tenant)->for($this->project)->create(['received_at' => '2026-05-15 10:00:00']);

    $r = $this->post('/api/deals/export', ['format' => 'xlsx']);

    $r->assertStatus(200);
    $r->assertHeader('content-type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
});

test('POST /api/deals/export не экспортирует чужой tenant (RLS)', function () {
    $other = Tenant::factory()->create();
    DB::statement('SET app.current_tenant_id = '.$other->id);
    $foreignProject = Project::factory()->for($other)->create();
    Deal::factory()->for($other)->for($foreignProject)->create(['phone' => '+7 900 000-00-00']);

    DB::statement('SET app.current_tenant_id = '.$this->tenant->id);
    $r = $this->post('/api/deals/export', ['format' => 'csv']);

    expect($r->streamedContent())->not->toContain('+7 900 000-00-00');
});

test('POST /api/deals/export 422 на неизвестный format', function () {
    $this->postJson('/api/deals/export', ['format' => 'pdf'])->assertStatus(422);
});

test('POST /api/deals/export без format по умолчанию отдаёт CSV', function () {
    Deal::factory()->for($this->tenant)->for($this->project)->create(['received_at' => '2026-05-15 10:00:00']);
    $r = $this->post('/api/deals/export', []);
    $r->assertStatus(200);
    $r->assertHeader('content-type', 'text/csv; charset=utf-8');
});

test('POST /api/deals/export нейтрализует CSV-формулы в свободном тексте (F-CSV)', function () {
    Deal::factory()->for($this->tenant)->for($this->project)->create([
        'received_at' => '2026-05-15 10:00:00',
        'comment' => '=HYPERLINK("http://evil","нажми")',
        'city' => '@SUM(1+1)',
    ]);

    $r = $this->post('/api/deals/export', ['format' => 'csv']);

    $body = $r->streamedContent();
    // Формула нейтрализована префиксом-апострофом, исходная формула в начале
    // ячейки отсутствует.
    expect($body)->toContain("'=HYPERLINK(");
    expect($body)->toContain("'@SUM(1+1)");
    // До фикса ячейка-комментарий обрамлялась как "=HYPERLINK(...; city — как ;@SUM.
    expect($body)->not->toContain('"=HYPERLINK(');
    expect($body)->not->toContain(';@SUM');
});
