<?php

declare(strict_types=1);

namespace ImovelZapAi\AiGateway\Application\Services;

use ImovelZapAi\AiGateway\Domain\Exceptions\AiQuotaExceededException;
use ImovelZapAi\AiGateway\Infrastructure\Persistence\Eloquent\AiRequestLogModel;
use ImovelZapAi\AiGateway\Domain\Enums\AiRequestStatus;
use ImovelZapAi\Tenancy\Support\TenantContext;

final class AiQuotaGuard
{
    public function __construct(
        private readonly int $dailyTokenLimit,
        private readonly float $monthlyCostLimitUsd,
    ) {}

    public function assertWithinLimits(string $tenantId): void
    {
        if ($this->dailyTokenLimit > 0) {
            $tokensToday = (int) AiRequestLogModel::query()
                ->withoutGlobalScopes()
                ->where('tenant_id', $tenantId)
                ->where('status', AiRequestStatus::Success->value)
                ->where('created_at', '>=', now()->startOfDay())
                ->sum('total_tokens');

            if ($tokensToday >= $this->dailyTokenLimit) {
                throw AiQuotaExceededException::dailyTokens($tenantId, $this->dailyTokenLimit);
            }
        }

        if ($this->monthlyCostLimitUsd > 0) {
            $costThisMonth = (float) AiRequestLogModel::query()
                ->withoutGlobalScopes()
                ->where('tenant_id', $tenantId)
                ->where('status', AiRequestStatus::Success->value)
                ->where('created_at', '>=', now()->startOfMonth())
                ->sum('estimated_cost_usd');

            if ($costThisMonth >= $this->monthlyCostLimitUsd) {
                throw AiQuotaExceededException::monthlyCost($tenantId, $this->monthlyCostLimitUsd);
            }
        }
    }

    public function enforceTenantContext(string $tenantId): void
    {
        TenantContext::set($tenantId);
    }
}
