<?php
/**
 * AI Usage Logger Service
 * Records every AI API call with token counts and estimated cost.
 */

namespace App\Core;

class AiUsageLogger
{
    /**
     * Cost per 1M tokens (input/output) for each model.
     * Update these when pricing changes.
     */
    private const MODEL_PRICING = [
        'gemini-1.5-flash' => [
            'input'  => 0.075,   // $0.075 per 1M input tokens
            'output' => 0.30,    // $0.30 per 1M output tokens
        ],
        'gemini-2.0-flash' => [
            'input'  => 0.10,
            'output' => 0.40,
        ],
        'gemini-1.5-pro' => [
            'input'  => 1.25,
            'output' => 5.00,
        ],
        'grok-2' => [
            'input'  => 2.00,
            'output' => 10.00,
        ],
        'whisper-large-v3' => [
            'input'  => 0.111,   // $0.111 per 1M input tokens (Groq)
            'output' => 0.0,
        ],
    ];

    /**
     * Log an AI usage event.
     *
     * @param string      $tenantId
     * @param string      $actionType  One of: invoice_extraction, voice_transcribe, voice_intent, report_generation, chatbot
     * @param string      $modelName   e.g. gemini-1.5-flash
     * @param int         $promptTokens
     * @param int         $completionTokens
     * @param string|null $userId
     * @param string|null $companyId
     * @param array|null  $metadata    Any extra info (invoice_id, etc.)
     */
    public static function log(
        string  $tenantId,
        string  $actionType,
        string  $modelName,
        int     $promptTokens,
        int     $completionTokens,
        ?string $userId = null,
        ?string $companyId = null,
        ?array  $metadata = null,
    ): void {
        $totalTokens   = $promptTokens + $completionTokens;
        $estimatedCost = self::estimateCost($modelName, $promptTokens, $completionTokens);

        try {
            $db   = Database::getInstance();
            $stmt = $db->prepare(
                "INSERT INTO ai_usage_log
                    (tenant_id, user_id, company_id, action_type, model_name,
                     prompt_tokens, completion_tokens, total_tokens, estimated_cost,
                     request_metadata, created_at)
                 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())"
            );
            $stmt->execute([
                $tenantId,
                $userId,
                $companyId,
                $actionType,
                $modelName,
                $promptTokens,
                $completionTokens,
                $totalTokens,
                $estimatedCost,
                $metadata ? json_encode($metadata, JSON_UNESCAPED_UNICODE) : null,
            ]);
        } catch (\Exception $e) {
            // Logging should never break the main flow
            error_log('[AiUsageLogger] Failed to log: ' . $e->getMessage());
        }
    }

    /**
     * Estimate cost in USD based on model pricing.
     */
    private static function estimateCost(string $model, int $inputTokens, int $outputTokens): float
    {
        $pricing = self::MODEL_PRICING[$model] ?? ['input' => 0.10, 'output' => 0.40];

        $inputCost  = ($inputTokens / 1_000_000) * $pricing['input'];
        $outputCost = ($outputTokens / 1_000_000) * $pricing['output'];

        return round($inputCost + $outputCost, 6);
    }
}
