<?php

declare(strict_types=1);

use App\Models\BalanceTransaction;
use App\Models\ReportJob;
use App\Models\Tenant;
use App\Services\Reports\Providers\BillingSummaryProvider;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Illuminate\Support\Carbon;

uses(DatabaseTransactions::class);

beforeEach(function () {
    $this->tenant = Tenant::factory()->create();
});

function seedBillingTx(int $tenantId, string $type, float $amount, ?Carbon $at = null): void
{
    BalanceTransaction::create([
        'tenant_id' => $tenantId,
        'type' => $type,
        'amount_rub' => $amount,
        'amount_leads' => 0,
        'description' => 'test',
        'created_at' => $at ?? Carbon::now()->startOfMonth()->addDays(10),
    ]);
}

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

test('headers: 3 колонки', function () {
    expect((new BillingSummaryProvider)->headers())
        ->toBe(['Тип операции', 'Количество', 'Сумма (₽)']);
});

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

test('агрегирует balance_transactions по типу: count + сумма', function () {
    seedBillingTx($this->tenant->id, 'topup', 5000);
    seedBillingTx($this->tenant->id, 'topup', 3000);
    seedBillingTx($this->tenant->id, 'lead_charge', -250);

    $rows = (new BillingSummaryProvider)->rows(billingJob($this->tenant->id));

    // ORDER BY type → 'lead_charge' < 'topup'.
    expect($rows)->toHaveCount(2);
    expect($rows[0])->toBe(['Списание за лиды', 1, '-250.00']);
    expect($rows[1])->toBe(['Пополнение', 2, '8000.00']);
});

test('исключает транзакции вне периода', function () {
    seedBillingTx($this->tenant->id, 'topup', 5000);
    // «Вне периода» берём из СЛЕДУЮЩЕГО месяца: партиции balance_transactions заводятся
    // наперёд (pg_partman premake), а назад со временем удаляются — past-дата (subMonths)
    // рано или поздно упирается в отсутствующую старую партицию.
    seedBillingTx($this->tenant->id, 'topup', 1000, Carbon::now()->addMonth()->day(15));

    $rows = (new BillingSummaryProvider)->rows(billingJob($this->tenant->id));

    expect($rows)->toHaveCount(1);
    expect($rows[0])->toBe(['Пополнение', 1, '5000.00']);
});

test('изолирует по tenant_id', function () {
    $other = Tenant::factory()->create();
    seedBillingTx($other->id, 'topup', 9999);

    $rows = (new BillingSummaryProvider)->rows(billingJob($this->tenant->id));

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