<?php

declare(strict_types=1);

namespace ImovelZapAi\AiGateway\Application\Services;

use ImovelZapAi\AiGateway\Application\Data\AiCompletionRequest;
use ImovelZapAi\AiGateway\Application\Data\AiCompletionResponse;
use ImovelZapAi\AiGateway\Application\Data\AiTokenUsageData;
use ImovelZapAi\AiGateway\Domain\Enums\AiRequestStatus;
use ImovelZapAi\AiGateway\Domain\Exceptions\AiGatewayException;
use ImovelZapAi\AiGateway\Domain\Exceptions\AiQuotaExceededException;
use ImovelZapAi\AiGateway\Infrastructure\Persistence\Eloquent\AiRequestLogModel;
use ImovelZapAi\AiGateway\Infrastructure\Services\AiProviderResolver;
use Illuminate\Support\Str;
use Throwable;

final class AiRequestLogger
{
    public function logSuccess(
        string $requestId,
        AiCompletionRequest $request,
        AiCompletionResponse $response,
    ): void {
        $this->persist($requestId, $request, [
            'status' => AiRequestStatus::Success->value,
            'provider' => $response->provider->value,
            'model' => $response->model,
            'input_tokens' => $response->tokenUsage->inputTokens,
            'output_tokens' => $response->tokenUsage->outputTokens,
            'total_tokens' => $response->tokenUsage->total(),
            'estimated_cost_usd' => $response->estimatedCostUsd,
            'latency_ms' => $response->latencyMs,
        ]);
    }

    public function logFailure(
        string $requestId,
        AiCompletionRequest $request,
        AiRequestStatus $status,
        Throwable $exception,
        int $latencyMs = 0,
    ): void {
        $this->persist($requestId, $request, [
            'status' => $status->value,
            'provider' => config('ai_gateway.default_provider', 'null'),
            'model' => $request->model,
            'input_tokens' => 0,
            'output_tokens' => 0,
            'total_tokens' => 0,
            'estimated_cost_usd' => 0,
            'latency_ms' => $latencyMs,
            'error_message' => Str::limit($exception->getMessage(), 1000),
        ]);
    }

    /**
     * @param  array<string, mixed>  $attributes
     */
    private function persist(string $requestId, AiCompletionRequest $request, array $attributes): void
    {
        AiRequestLogModel::query()->create([
            'id' => $requestId,
            'tenant_id' => $request->tenantId,
            'user_id' => $request->userId,
            'task_type' => $request->taskType->value,
            'metadata' => $request->metadata,
            ...$attributes,
        ]);
    }
}
