<?php

declare(strict_types=1);

use App\Services\Supplier\SupplierCsvParser;
use Illuminate\Support\Facades\Log;
use Tests\TestCase;

uses(TestCase::class);

// Контракт парсера (эпик CSV-канал T2, 18.05.2026): отчёт «Запрос номеров»
// crm.bp-gr.ru — 3 колонки Name;Tag;Phone. vid и время в отчёте отсутствуют.
// SupplierCsvParser::parse() yields {project, tag, phone}. Spec §4.1.

beforeEach(function () {
    $this->parser = new SupplierCsvParser;
});

it('parses empty CSV → yields nothing', function () {
    $rows = iterator_to_array($this->parser->parse(''));
    expect($rows)->toBeEmpty();
});

it('parses 1 row → yields 1 struct with project/tag/phone', function () {
    $csv = "Name;Tag;Phone\n"
         ."B1_example.com;mytag;79991234567\n";

    $rows = iterator_to_array($this->parser->parse($csv));

    expect($rows)->toHaveCount(1);
    expect($rows[0])->toMatchArray([
        'project' => 'B1_example.com',
        'tag' => 'mytag',
        'phone' => '79991234567',
    ]);
});

it('parses 1000 rows without OOM (streaming generator)', function () {
    $lines = ['Name;Tag;Phone'];
    for ($i = 1; $i <= 1000; $i++) {
        $lines[] = "B1_test.com;tag{$i};79991234567";
    }
    $csv = implode("\n", $lines)."\n";

    $count = 0;
    foreach ($this->parser->parse($csv) as $_) {
        $count++;
    }

    expect($count)->toBe(1000);
});

it('skips malformed rows with missing columns + logs warning', function () {
    Log::spy();

    $csv = "Name;Tag;Phone\n"
         ."B1_example.com;mytag;79991234567\n"
         ."broken-row-only-one-column\n"
         ."B1_another.com;tag2;79991234500\n";

    $rows = iterator_to_array($this->parser->parse($csv));

    expect($rows)->toHaveCount(2);
    expect($rows[0]['project'])->toBe('B1_example.com');
    expect($rows[1]['project'])->toBe('B1_another.com');

    Log::shouldHaveReceived('warning')
        ->with('supplier_csv_parser.malformed_row', Mockery::any())
        ->once();
});

it('handles BOM + CRLF line endings', function () {
    $bom = "\xEF\xBB\xBF";
    $csv = $bom."Name;Tag;Phone\r\n"
         ."B1_example.com;mytag;79991234567\r\n";

    $rows = iterator_to_array($this->parser->parse($csv));

    expect($rows)->toHaveCount(1);
    expect($rows[0]['project'])->toBe('B1_example.com');
});
