<?php
/**
 * ============================================================
 * AI Manager for Finggu
 * - Multi-provider fallback system
 * - Rate limit detection (HTTP 429)
 * - Daily usage tracking in DB
 * - Timeout protection (60s per request)
 * - Error logging per provider
 * ============================================================
 */

function ai_generate_with_fallback($prompt, $pdo) {

    // Get all API keys from DB
    $stmt = $pdo->prepare("SELECT setting_key, setting_value FROM finggu_settings WHERE setting_key LIKE '%_api_key'");
    $stmt->execute();
    $allKeys = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);

    // ✅ Provider priority list (order = fallback order)
    $providers = [
        [
            'id'       => 'gemini',
            'name'     => 'Google Gemini',
            'key'      => $allKeys['gemini_api_key'] ?? '',
            'function' => 'ai_provider_gemini'
        ],
        [
            'id'       => 'groq',
            'name'     => 'Groq (Llama 3.3)',
            'key'      => $allKeys['groq_api_key'] ?? '',
            'function' => 'ai_provider_groq'
        ],
        [
            'id'       => 'openrouter',
            'name'     => 'OpenRouter',
            'key'      => $allKeys['openrouter_api_key'] ?? '',
            'function' => 'ai_provider_openrouter'
        ],
        [
            'id'       => 'mistral',
            'name'     => 'Mistral AI',
            'key'      => $allKeys['mistral_api_key'] ?? '',
            'function' => 'ai_provider_mistral'
        ],
        [
            'id'       => 'together',
            'name'     => 'Together AI',
            'key'      => $allKeys['together_api_key'] ?? '',
            'function' => 'ai_provider_together'
        ],
        [
            'id'       => 'cohere',
            'name'     => 'Cohere',
            'key'      => $allKeys['cohere_api_key'] ?? '',
            'function' => 'ai_provider_cohere'
        ],
    ];

    $errors = [];

    foreach ($providers as $provider) {

        // Skip if no API key saved
        if (empty($provider['key'])) {
            $errors[] = $provider['name'] . ": No API key configured";
            continue;
        }

        // ✅ Check if this provider hit daily limit
        if (ai_is_rate_limited($provider['id'], $pdo)) {
            $errors[] = $provider['name'] . ": Skipped (daily limit reached)";
            continue;
        }

        try {
            $result = call_user_func($provider['function'], $prompt, $provider['key']);

            if ($result['success']) {
                // ✅ Log successful usage
                ai_log_usage($provider['id'], 'success', $pdo);
                return [
                    'success'  => true,
                    'content'  => $result['content'],
                    'provider' => $provider['name']
                ];
            } else {
                // ✅ Log failure with reason
                $errorMsg = $result['error'] ?? 'Unknown error';
                ai_log_usage($provider['id'], $errorMsg, $pdo);
                $errors[] = $provider['name'] . ": " . $errorMsg;
            }

        } catch (Exception $e) {
            ai_log_usage($provider['id'], $e->getMessage(), $pdo);
            $errors[] = $provider['name'] . ": " . $e->getMessage();
        }
    }

    return [
        'success' => false,
        'error'   => "All providers failed. Details: " . implode(" | ", $errors)
    ];
}


// ============================================================
// ✅ USAGE TRACKER — Logs to finggu_ai_logs table
// ============================================================

function ai_log_usage($provider, $status, $pdo) {
    try {
        $pdo->exec("
            CREATE TABLE IF NOT EXISTS finggu_ai_logs (
                id INT AUTO_INCREMENT PRIMARY KEY,
                provider VARCHAR(50),
                status VARCHAR(255),
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
        ");
        $stmt = $pdo->prepare("INSERT INTO finggu_ai_logs (provider, status) VALUES (?, ?)");
        $stmt->execute([$provider, $status]);
    } catch (Exception $e) {
        // Silently fail — logging should never break generation
    }
}


// ============================================================
// ✅ RATE LIMIT CHECKER — Based on daily success count in DB
// ============================================================

// Safe daily limits (slightly below actual free limits as buffer)
$AI_DAILY_LIMITS = [
    'gemini'     => 1400,  // Actual: 1500/day  → using 1400 (safety buffer)
    'groq'       => 13000, // Actual: 14400/day → using 13000 (safety buffer)
    'openrouter' => 180,   // Actual: ~200/day  → using 180 (safety buffer)
    'mistral'    => 900,   // Generous monthly limit
    'together'   => 400,   // Based on $25 free credits
    'cohere'     => 30,    // Actual: 1000/month trial → ~30/day
];

function ai_is_rate_limited($provider, $pdo) {
    global $AI_DAILY_LIMITS;
    $limit = $AI_DAILY_LIMITS[$provider] ?? 100;

    try {
        $stmt = $pdo->prepare("
            SELECT COUNT(*) FROM finggu_ai_logs
            WHERE provider = ?
            AND status = 'success'
            AND DATE(created_at) = CURDATE()
        ");
        $stmt->execute([$provider]);
        $usedToday = (int) $stmt->fetchColumn();
        return $usedToday >= $limit;
    } catch (Exception $e) {
        return false; // If table doesn't exist yet, don't block
    }
}


// ============================================================
// ✅ PROVIDER: Google Gemini
// ============================================================

function ai_provider_gemini($prompt, $apiKey) {
    $models = [
        'gemini-2.0-flash',
        'gemini-1.5-flash-latest',
        'gemini-1.5-pro-latest'
    ];

    $lastResponse = null;
    foreach ($models as $model) {
        $version = (strpos($model, 'latest') !== false) ? 'v1beta' : 'v1';
        $url = "https://generativelanguage.googleapis.com/$version/models/$model:generateContent?key=$apiKey";

        $response = ai_curl_post($url, [
            "contents" => [["parts" => [["text" => $prompt]]]],
            "generationConfig" => [
                "maxOutputTokens" => 8192, // ✅ Ensure enough space for 2000 words
                "temperature" => 0.7
            ]
        ], ['Content-Type: application/json']);

        $lastResponse = $response;

        if ($response['http_code'] === 200) {
            $data = json_decode($response['body'], true);
            $text = $data['candidates'][0]['content']['parts'][0]['text'] ?? '';
            if ($text) return ['success' => true, 'content' => $text];
        }

        if ($response['http_code'] === 429) {
            return ['success' => false, 'error' => 'Rate limited (429) — daily quota hit'];
        }
    }

    return ['success' => false, 'error' => 'All Gemini models failed. HTTP: ' . ($lastResponse['http_code'] ?? 'N/A')];
}


// ============================================================
// ✅ PROVIDER: Groq
// ============================================================

function ai_provider_groq($prompt, $apiKey) {
    return ai_openai_compatible_call(
        'https://api.groq.com/openai/v1/chat/completions',
        $apiKey,
        'llama-3.3-70b-versatile',
        $prompt
    );
}


// ============================================================
// ✅ PROVIDER: OpenRouter (confirmed free model)
// ============================================================

function ai_provider_openrouter($prompt, $apiKey) {
    return ai_openai_compatible_call(
        'https://openrouter.ai/api/v1/chat/completions',
        $apiKey,
        'meta-llama/llama-4-scout:free',  // ✅ Confirmed free model on OpenRouter
        $prompt,
        [
            'HTTP-Referer: https://finggu.com',
            'X-Title: Finggu Content System'
        ]
    );
}


// ============================================================
// ✅ PROVIDER: Mistral AI
// ============================================================

function ai_provider_mistral($prompt, $apiKey) {
    return ai_openai_compatible_call(
        'https://api.mistral.ai/v1/chat/completions',
        $apiKey,
        'mistral-small-latest',  // ✅ Free tier eligible
        $prompt
    );
}


// ============================================================
// ✅ PROVIDER: Together AI
// ============================================================

function ai_provider_together($prompt, $apiKey) {
    return ai_openai_compatible_call(
        'https://api.together.xyz/v1/chat/completions',
        $apiKey,
        'meta-llama/Llama-3.3-70B-Instruct-Turbo',
        $prompt
    );
}


// ============================================================
// ✅ PROVIDER: Cohere (Fixed — uses correct Cohere v2 API format)
// ============================================================

function ai_provider_cohere($prompt, $apiKey) {
    $url = 'https://api.cohere.com/v2/chat';

    $response = ai_curl_post($url, [
        'model'    => 'command-r-plus',
        'messages' => [['role' => 'user', 'content' => $prompt]]
    ], [
        'Content-Type: application/json',
        'Authorization: Bearer ' . $apiKey,
        'X-Client-Name: finggu'
    ]);

    if ($response['http_code'] === 200) {
        $data = json_decode($response['body'], true);
        // ✅ Cohere v2 response format (different from OpenAI)
        $text = $data['message']['content'][0]['text'] ?? '';
        if ($text) return ['success' => true, 'content' => $text];
        return ['success' => false, 'error' => 'Empty response from Cohere'];
    }

    if ($response['http_code'] === 429) {
        return ['success' => false, 'error' => 'Rate limited (429)'];
    }

    $errorBody = json_decode($response['body'], true);
    $errorMsg  = $errorBody['message'] ?? $response['body'] ?? 'Unknown';
    return ['success' => false, 'error' => "Cohere HTTP {$response['http_code']}: $errorMsg"];
}


// ============================================================
// ✅ GENERIC: OpenAI-Compatible API Call
// ============================================================

function ai_openai_compatible_call($url, $apiKey, $model, $prompt, $extraHeaders = []) {
    $headers = array_merge([
        'Content-Type: application/json',
        'Authorization: Bearer ' . $apiKey
    ], $extraHeaders);

    $response = ai_curl_post($url, [
        'model'       => $model,
        'messages'    => [['role' => 'user', 'content' => $prompt]],
        'temperature' => 0.7,
        'max_tokens'  => 8192 // ✅ Ensure enough space for 2000 words
    ], $headers);

    if ($response['http_code'] === 200) {
        $data = json_decode($response['body'], true);
        $text = $data['choices'][0]['message']['content'] ?? '';
        if ($text) return ['success' => true, 'content' => $text];
        return ['success' => false, 'error' => 'Empty response from model'];
    }

    if ($response['http_code'] === 429) {
        return ['success' => false, 'error' => 'Rate limited (429)'];
    }

    $errorBody = json_decode($response['body'], true);
    $errorMsg  = $errorBody['error']['message'] ?? $response['body'] ?? 'Unknown';
    return ['success' => false, 'error' => "HTTP {$response['http_code']}: $errorMsg"];
}


// ============================================================
// ✅ CORE: cURL Helper with Timeout Protection
// ============================================================

function ai_curl_post($url, $payload, $headers) {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => json_encode($payload),
        CURLOPT_HTTPHEADER     => $headers,
        CURLOPT_TIMEOUT        => 120,   // ✅ Max 120s per API call (for 2000 words)
        CURLOPT_CONNECTTIMEOUT => 20,    // ✅ Max 20s to establish connection
        CURLOPT_SSL_VERIFYPEER => true,
    ]);

    $body     = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlErr  = curl_error($ch);
    curl_close($ch);

    if ($curlErr) {
        return ['http_code' => 0, 'body' => 'cURL Error: ' . $curlErr];
    }

    return ['http_code' => $httpCode, 'body' => $body];
}


// ============================================================
// ✅ HELPER: Get Today's Usage Stats (use in dashboard)
// ============================================================

function ai_get_today_stats($pdo) {
    global $AI_DAILY_LIMITS;
    try {
        $stmt = $pdo->query("
            SELECT 
                provider,
                SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) AS success_count,
                SUM(CASE WHEN status != 'success' THEN 1 ELSE 0 END) AS fail_count
            FROM finggu_ai_logs
            WHERE DATE(created_at) = CURDATE()
            GROUP BY provider
        ");
        $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);

        // Add limit info to each row
        foreach ($rows as &$row) {
            $row['daily_limit'] = $AI_DAILY_LIMITS[$row['provider']] ?? 'N/A';
            $row['remaining']   = max(0, $row['daily_limit'] - $row['success_count']);
        }
        return $rows;
    } catch (Exception $e) {
        return [];
    }
}
