<?php
/**
 * =========================================================================
 * api/router.php - DYNAMIC TRAFFIC CONTROLLER (UNLIMITED SLOTS)
 * =========================================================================
 * Membaca API keys dari tabel `api_keys` (dinamis, unlimited).
 * Menggabungkan fungsi routing + health monitoring dalam 1 tabel.
 * Developer: Sikawarsito, S.Kom
 * =========================================================================
 */

/**
 * Ambil key terbaik yang siap pakai untuk provider tertentu.
 * Baca langsung dari tabel `api_keys` — tidak lagi dari settings.
 * 
 * @param string $provider 'gemini' atau 'groq'
 * @param mysqli $conn Database connection
 * @return array|null ['key' => '...', 'slot' => id] atau null jika semua habis
 */
function getBestKey($provider, $conn) {
    $provider = mysqli_real_escape_string($conn, $provider);
    
    // 1. Auto-recovery: pulihkan key yang cooldown-nya sudah lewat
    mysqli_query($conn, "UPDATE api_keys SET status = 'ready', cooldown_until = NULL, fail_count = 0 
                         WHERE provider = '$provider' AND status = 'cooldown' AND cooldown_until <= NOW()");

    // 2. Ambil 1 key yang siap pakai (round-robin via ORDER BY last_used ASC)
    $q = mysqli_query($conn, "SELECT id, api_key FROM api_keys 
                              WHERE provider = '$provider' AND status = 'ready' 
                              ORDER BY last_used ASC LIMIT 1");
    
    if ($q && $row = mysqli_fetch_assoc($q)) {
        // 3. Tandai sebagai sedang dipakai
        mysqli_query($conn, "UPDATE api_keys SET last_used = NOW() WHERE id = " . (int)$row['id']);
        return ['key' => trim($row['api_key']), 'slot' => (int)$row['id']];
    }
    
    return null; // Semua key habis / sedang cooldown / tidak ada key
}

/**
 * Laporkan hasil penggunaan key.
 * Langsung update status di tabel `api_keys`.
 * 
 * @param int $key_id ID dari api_keys
 * @param bool $is_success Berhasil atau gagal
 * @param int $http_code HTTP status code
 * @param mysqli $conn Database connection
 */
function reportTrafficStatus($key_id, $is_success, $http_code, $conn) {
    $key_id = (int)$key_id;
    
    if ($is_success) {
        // Sukses: reset semua counter dan status
        mysqli_query($conn, "UPDATE api_keys SET status = 'ready', fail_count = 0, cooldown_until = NULL WHERE id = $key_id");
    } else {
        // Ambil fail_count saat ini untuk progressive cooldown
        $d = mysqli_fetch_assoc(mysqli_query($conn, "SELECT fail_count FROM api_keys WHERE id = $key_id"));
        $current_fails = ($d['fail_count'] ?? 0) + 1;

        if ($http_code == 400 || $http_code == 401 || $http_code == 403) {
            // Key invalid/revoked → suspend permanen sampai admin fix
            mysqli_query($conn, "UPDATE api_keys SET status = 'suspended', fail_count = 999 WHERE id = $key_id");

        } else if ($http_code == 429) {
            // RATE LIMITED → Progressive Cooldown (120s, 240s, 480s, max 600s)
            $cooldown_sec = min(120 * pow(2, $current_fails - 1), 600);
            mysqli_query($conn, "UPDATE api_keys SET status = 'cooldown', fail_count = $current_fails, 
                                 cooldown_until = DATE_ADD(NOW(), INTERVAL $cooldown_sec SECOND) WHERE id = $key_id");

        } else {
            // Error server umum (500, 502, 503) → toleransi 3x, lalu cooldown
            if ($current_fails < 3) {
                mysqli_query($conn, "UPDATE api_keys SET fail_count = $current_fails WHERE id = $key_id");
            } else {
                $cooldown_sec = min(45 * pow(2, $current_fails - 3), 300);
                mysqli_query($conn, "UPDATE api_keys SET status = 'cooldown', fail_count = $current_fails, 
                                      cooldown_until = DATE_ADD(NOW(), INTERVAL $cooldown_sec SECOND) WHERE id = $key_id");
            }
        }
    }
}