<?php

declare(strict_types=1);

use App\Models\PricingTier;
use App\Services\Billing\PricingTierResolver;
use Illuminate\Database\Eloquent\Collection;
use Tests\TestCase;

uses(TestCase::class);

beforeEach(function () {
    $this->resolver = new PricingTierResolver;

    // 7-tier сетка in-memory (без БД)
    $this->tiers = new Collection([
        new PricingTier(['tier_no' => 1, 'leads_in_tier' => 100,  'price_per_lead_kopecks' => 50000]),
        new PricingTier(['tier_no' => 2, 'leads_in_tier' => 200,  'price_per_lead_kopecks' => 45000]),
        new PricingTier(['tier_no' => 3, 'leads_in_tier' => 400,  'price_per_lead_kopecks' => 40000]),
        new PricingTier(['tier_no' => 4, 'leads_in_tier' => 800,  'price_per_lead_kopecks' => 35000]),
        new PricingTier(['tier_no' => 5, 'leads_in_tier' => 1500, 'price_per_lead_kopecks' => 30000]),
        new PricingTier(['tier_no' => 6, 'leads_in_tier' => 3000, 'price_per_lead_kopecks' => 27000]),
        new PricingTier(['tier_no' => 7, 'leads_in_tier' => null, 'price_per_lead_kopecks' => 25000]),
    ]);
});

it('returns tier 1 for the 1st lead', function () {
    $tier = $this->resolver->resolveForCount($this->tiers, 1);
    expect($tier->tier_no)->toBe(1);
});

it('returns tier 1 at upper bound (100th lead)', function () {
    $tier = $this->resolver->resolveForCount($this->tiers, 100);
    expect($tier->tier_no)->toBe(1);
});

it('crosses to tier 2 at 101st lead', function () {
    $tier = $this->resolver->resolveForCount($this->tiers, 101);
    expect($tier->tier_no)->toBe(2);
});

it('returns tier 6 at cumulative sum of tiers 1-6 (6000th lead)', function () {
    // 100 + 200 + 400 + 800 + 1500 + 3000 = 6000; last in tier 6 = 6000th lead
    $tier = $this->resolver->resolveForCount($this->tiers, 6000);
    expect($tier->tier_no)->toBe(6);
});

it('returns tier 7 (unlimited) for 6001st lead', function () {
    $tier = $this->resolver->resolveForCount($this->tiers, 6001);
    expect($tier->tier_no)->toBe(7);
});

it('returns tier 7 for 1_000_000th lead (unlimited)', function () {
    $tier = $this->resolver->resolveForCount($this->tiers, 1_000_000);
    expect($tier->tier_no)->toBe(7);
});

it('throws RuntimeException on empty tiers collection', function () {
    expect(fn () => $this->resolver->resolveForCount(new Collection, 1))
        ->toThrow(RuntimeException::class, 'No active pricing tiers');
});

it('throws InvalidArgumentException on zero or negative ordinal', function () {
    expect(fn () => $this->resolver->resolveForCount($this->tiers, 0))
        ->toThrow(InvalidArgumentException::class, 'leadOrdinal must be >= 1');

    expect(fn () => $this->resolver->resolveForCount($this->tiers, -5))
        ->toThrow(InvalidArgumentException::class, 'leadOrdinal must be >= 1');
});
