<?php

namespace App\Core;

use App\Services\InvoiceExtractionService;

/**
 * Gemini AI Integration for Invoice Extraction
 * Optimized for Jordan UBL 2.1 Compliance
 */
class AI
{
    private static string $baseUrl = "https://generativelanguage.googleapis.com/v1beta/models/" . AIConfig::MODEL_NAME . ":generateContent";

    private static int $maxRetries = 3;

    /**
     * Extract Data from Invoice Image or PDF (Base64)
     */
    public static function extractInvoiceData(string $base64Data, string $mimeType): ?array
    {
        $apiKey = env('GEMINI_API_KEY');
        if (!$apiKey) {
            error_log('AI Error: GEMINI_API_KEY is missing');
            return null;
        }

        $prompt = AIConfig::getExtractionPrompt();

        $payload = [
            "contents" => [
                [
                    "parts" => [
                        ["text" => $prompt . " If the image is not an invoice, is blank, or is completely unreadable, return ONLY: {\"error\": \"invalid_invoice\"}. DO NOT guess or invent data."],
                        [
                            "inline_data" => [
                                "mime_type" => $mimeType,
                                "data" => $base64Data
                            ]
                        ]
                    ]
                ]
            ],
            "generationConfig" => [
                "response_mime_type" => "application/json"
            ]
        ];

        // Retry with exponential backoff for 503/429 errors
        for ($attempt = 1; $attempt <= self::$maxRetries; $attempt++) {
            $ch = curl_init(self::$baseUrl . "?key=" . $apiKey);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
            curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
            curl_setopt($ch, CURLOPT_TIMEOUT, 60);
            
            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $curlError = curl_error($ch);
            curl_close($ch);

            if ($curlError) {
                error_log("AI Error: cURL failed (attempt $attempt): $curlError");
                if ($attempt < self::$maxRetries) {
                    $wait = pow(2, $attempt) + rand(1, 3);
                    echo "  Retrying in {$wait}s (cURL error)...\n";
                    sleep($wait);
                    continue;
                }
                return null;
            }

            if ($httpCode === 200) {
                break; // Success
            }

            // Retry on 503 (overloaded) or 429 (rate limit)
            if (in_array($httpCode, [503, 429]) && $attempt < self::$maxRetries) {
                $wait = pow(2, $attempt) + rand(1, 3);
                echo "  Gemini $httpCode — retrying in {$wait}s (attempt $attempt/" . self::$maxRetries . ")...\n";
                sleep($wait);
                continue;
            }

            error_log("AI Error: Gemini API returned code $httpCode. Response: " . $response);
            return null;
        }

        if ($httpCode !== 200) {
            error_log("AI Error: All retries exhausted. Last code: $httpCode");
            return null;
        }

        $result = json_decode($response, true);
        $textResponse = $result['candidates'][0]['content']['parts'][0]['text'] ?? null;

        if (!$textResponse) return null;
        
        // --- ADDED FOR DEBUGGING ---
        @file_put_contents(STORAGE_PATH . '/logs/worker.log', "[" . date('Y-m-d H:i:s') . "] [AI_RAW_RESPONSE]\n" . $textResponse . "\n", FILE_APPEND);
        // ---------------------------

        $data = json_decode($textResponse, true);
        if (isset($data['error']) && $data['error'] === 'invalid_invoice') {
            return null;
        }

        // If the AI returns an array of invoices, extract the first one
        if (isset($data['invoices']) && is_array($data['invoices']) && count($data['invoices']) > 0) {
            $data = $data['invoices'][0];
        }

        // Track token usage from Gemini response
        $usage = $result['usageMetadata'] ?? [];
        if (!empty($usage)) {
            self::logTokenUsage($usage);
        }

        return $data;
    }

    /**
     * Log AI token usage to the database for cost tracking
     */
    private static function logTokenUsage(array $usage): void
    {
        try {
            $db = Database::getInstance();

            $inputTokens  = (int)($usage['promptTokenCount'] ?? 0);
            $outputTokens = (int)($usage['candidatesTokenCount'] ?? 0);
            $totalTokens  = (int)($usage['totalTokenCount'] ?? ($inputTokens + $outputTokens));

            // Gemini Flash Lite pricing: $0.075/1M input, $0.30/1M output
            $inputCost  = ($inputTokens / 1000000) * 0.075;
            $outputCost = ($outputTokens / 1000000) * 0.30;
            $totalCostUsd = $inputCost + $outputCost;
            $totalCostJod = $totalCostUsd * 0.709; // 1 USD ≈ 0.709 JOD

            $db->prepare("
                INSERT INTO ai_usage_log (id, input_tokens, output_tokens, total_tokens, cost_usd, cost_jod, model, created_at)
                VALUES (UUID(), ?, ?, ?, ?, ?, 'gemini-flash-lite', NOW())
            ")->execute([
                $inputTokens,
                $outputTokens,
                $totalTokens,
                round($totalCostUsd, 8),
                round($totalCostJod, 8),
            ]);
        } catch (\Exception $e) {
            // Never crash the main flow for logging
            error_log("[AI] Token usage log failed: " . $e->getMessage());
        }
    }

    /**
     * Get aggregated AI usage stats
     */
    public static function getUsageStats(?string $tenantId = null): array
    {
        try {
            $db = Database::getInstance();
            $stmt = $db->query("
                SELECT 
                    COUNT(*) as total_requests,
                    COALESCE(SUM(input_tokens), 0) as total_input_tokens,
                    COALESCE(SUM(output_tokens), 0) as total_output_tokens,
                    COALESCE(SUM(total_tokens), 0) as total_tokens,
                    COALESCE(SUM(cost_usd), 0) as total_cost_usd,
                    COALESCE(SUM(cost_jod), 0) as total_cost_jod,
                    COALESCE(AVG(total_tokens), 0) as avg_tokens_per_request,
                    COALESCE(AVG(cost_jod), 0) as avg_cost_jod_per_request
                FROM ai_usage_log
            ");
            return $stmt->fetch() ?: [];
        } catch (\Exception $e) {
            return [];
        }
    }
}
