<?php

declare(strict_types=1);

use App\Models\PricingTier;
use App\Models\Project;
use App\Models\Tenant;
use App\Models\User;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Queue;
use Illuminate\Testing\TestResponse;
use Tests\Concerns\SharesSupplierPdo;

uses(DatabaseTransactions::class);
uses(SharesSupplierPdo::class);

beforeEach(function () {
    Queue::fake();
    DB::statement("SELECT set_config('app.current_tenant_id', '0', true)");
    PricingTier::query()->create([
        'tier_no' => 1,
        'leads_in_tier' => null,
        'price_per_lead_kopecks' => 5000, // 50₽/лид
        'is_active' => true,
        'effective_from' => now(),
    ]);
    // Баланс заведомо большой — преflight всегда проходит, тест про нормализацию.
    $this->tenant = Tenant::factory()->withRequisites()->create(['balance_rub' => '100000.00']);
    $this->user = User::factory()->create(['tenant_id' => $this->tenant->id]);
});

function createCallProject(string $rawPhone, string $name = 'Звонок'): TestResponse
{
    return test()->actingAs(test()->user)->postJson('/api/projects', [
        'name' => $name,
        'signal_type' => 'call',
        'signal_identifier' => $rawPhone,
        'daily_limit_target' => 5,
        'regions' => [],
        'delivery_days_mask' => 127,
    ]);
}

it('normalizes +7 (916) 123-45-67 to 79161234567 on create', function () {
    createCallProject('+7 (916) 123-45-67')->assertCreated();
    expect(Project::where('tenant_id', $this->tenant->id)->value('signal_identifier'))
        ->toBe('79161234567');
});

it('normalizes leading 8 to 7 on create', function () {
    createCallProject('8 916 123 45 67')->assertCreated();
    expect(Project::where('tenant_id', $this->tenant->id)->value('signal_identifier'))
        ->toBe('79161234567');
});

it('normalizes hyphenated 7-916-123-45-67 on create', function () {
    createCallProject('7-916-123-45-67')->assertCreated();
    expect(Project::where('tenant_id', $this->tenant->id)->value('signal_identifier'))
        ->toBe('79161234567');
});

it('keeps already canonical 79161234567 unchanged (idempotent)', function () {
    createCallProject('79161234567')->assertCreated();
    expect(Project::where('tenant_id', $this->tenant->id)->value('signal_identifier'))
        ->toBe('79161234567');
});

it('never stores a leading plus (routing matches without +)', function () {
    createCallProject('+79161234567')->assertCreated();
    $stored = Project::where('tenant_id', $this->tenant->id)->value('signal_identifier');
    expect($stored)->toBe('79161234567')
        ->and($stored)->not->toContain('+');
});

it('rejects real garbage with a helpful message naming the on-screen field', function () {
    $response = createCallProject('12345');
    $response->assertStatus(422);
    $msg = $response->json('errors.signal_identifier.0');
    expect($msg)->toContain('79161234567')   // показывает пример формата
        ->and($msg)->not->toContain('Источник'); // не всплывает внутреннее имя поля
});

it('does NOT normalize a site domain (only call is a phone)', function () {
    test()->actingAs($this->user)->postJson('/api/projects', [
        'name' => 'Сайт',
        'signal_type' => 'site',
        'signal_identifier' => 'my-site.ru',
        'daily_limit_target' => 5,
        'regions' => [],
        'delivery_days_mask' => 127,
    ])->assertCreated();
    expect(Project::where('tenant_id', $this->tenant->id)->value('signal_identifier'))
        ->toBe('my-site.ru');
});

it('normalizes phone on update of a call project', function () {
    $project = Project::factory()->for($this->tenant)->create([
        'signal_type' => 'call',
        'signal_identifier' => '79990001122',
        'is_active' => true,
        'daily_limit_target' => 5,
    ]);

    test()->actingAs($this->user)->patchJson("/api/projects/{$project->id}", [
        'signal_identifier' => '+7 (916) 123-45-67',
    ])->assertOk();

    expect($project->fresh()->signal_identifier)->toBe('79161234567');
});
