<?php

namespace App\Serp\Operations;

use App\Models\SerpBudgetEntry;
use App\Models\SerpOperationState;

final class RampUpPolicy
{
    public function __construct(private ActivationManager $activation) {}

    public function assertAllowsNewPaid(): void
    {
        if ($this->activation->state() !== ActivationState::Enabled) {
            return;
        }$state = SerpOperationState::query()->lockForUpdate()->find(1);
        if (! $state) {
            throw new OperationBlockedException('ramp_state_missing');
        }

        if (! $state->ramp_started_at) {
            $state->forceFill(['ramp_started_at' => now('UTC')])->save();
        }$age = $state->ramp_started_at->diffInMinutes(now('UTC'));
        $limit = $age < 60 ? (int) config('serp.ramp.first_hour_limit') : ($age < 360 ? (int) config('serp.ramp.six_hour_limit') : (int) config('serp.ramp.first_day_limit'));
        $count = SerpBudgetEntry::where('reserved_at', '>=', $state->ramp_started_at)->count();
        if ($count >= $limit) {
            throw new OperationBlockedException('ramp_up_limit');
        }
    }

    public function status(): array
    {
        $state = SerpOperationState::find(1);
        if (! $state?->ramp_started_at) {
            return ['started_at' => null, 'age_minutes' => null, 'used' => 0, 'limit' => (int) config('serp.ramp.first_hour_limit')];
        }$age = $state->ramp_started_at->diffInMinutes(now('UTC'));
        $limit = $age < 60 ? (int) config('serp.ramp.first_hour_limit') : ($age < 360 ? (int) config('serp.ramp.six_hour_limit') : (int) config('serp.ramp.first_day_limit'));

        return ['started_at' => $state->ramp_started_at->toAtomString(), 'age_minutes' => (int) $age, 'used' => SerpBudgetEntry::where('reserved_at', '>=', $state->ramp_started_at)->count(), 'limit' => $limit];
    }
}
