<?php

declare(strict_types=1);

namespace App\Services\Billing;

use App\Models\PricingTier;
use Illuminate\Database\Eloquent\Collection;
use RuntimeException;

/**
 * Pure resolver: «в какую ступень pricing_tiers попадает N-й лид» (1-based).
 *
 * Логика: tier 1 покрывает 1..leads_in_tier_1; tier 2 — следующие leads_in_tier_2;
 * tier 7 с leads_in_tier=NULL ловит всё свыше суммарного объёма tiers 1-6.
 *
 * Spec: docs/superpowers/specs/2026-05-11-plan4-billing-csv-admin-design.md §3.1
 */
final class PricingTierResolver
{
    /**
     * @param  Collection<int, PricingTier>  $tiers  активные ступени (не обязательно отсортированы)
     * @param  int  $leadOrdinal  номер лида в текущем месяце (1-based)
     */
    public function resolveForCount(Collection $tiers, int $leadOrdinal): PricingTier
    {
        if ($leadOrdinal < 1) {
            throw new \InvalidArgumentException("leadOrdinal must be >= 1, got {$leadOrdinal}");
        }

        if ($tiers->isEmpty()) {
            throw new RuntimeException('No active pricing tiers — cannot resolve');
        }

        /** @var Collection<int, PricingTier> $sorted */
        $sorted = $tiers->sortBy('tier_no')->values();

        $cumulative = 0;
        foreach ($sorted as $tier) {
            // tier 7 (или любой с leads_in_tier=NULL) — «всё свыше»
            if ($tier->leads_in_tier === null) {
                return $tier;
            }

            $cumulative += (int) $tier->leads_in_tier;
            if ($leadOrdinal <= $cumulative) {
                return $tier;
            }
        }

        // Если ни одна ступень не покрыла (leadOrdinal > сумма всех leads_in_tier
        // И ни у одной не было NULL) — возвращаем последнюю как fallback.
        return $sorted->last();
    }
}
