<?php
/**
 * سودانا — KPI Logger v21
 * تسجيل كل طلب بتفاصيل التكلفة والأداء
 */
class KPILogger {

    public static function log(array $data): void {
        try {
            $uuid = sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
                mt_rand(0,0xffff), mt_rand(0,0xffff), mt_rand(0,0xffff),
                mt_rand(0,0x0fff)|0x4000, mt_rand(0,0x3fff)|0x8000,
                mt_rand(0,0xffff), mt_rand(0,0xffff), mt_rand(0,0xffff)
            );
            db()->prepare(
                'INSERT INTO ai_requests
                 (request_uuid, user_id, session_id, service, intent,
                  ie_rule_id,
                  ie_confidence, ie_hit, cache_hit, ai_used, model_used,
                  input_tokens, output_tokens, cost_usd, latency_ms,
                  failover_used, error_occurred, user_tier)
                 VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)'
            )->execute([
                $uuid,
                $data['user_id']       ?? null,
                $data['session_id']    ?? null,
                $data['service']       ?? 'general',
                $data['intent']        ?? null,
                $data['ie_rule_id']    ?? null,
                $data['ie_confidence'] ?? null,
                (int)($data['ie_hit']       ?? 0),
                (int)($data['cache_hit']    ?? 0),
                (int)($data['ai_used']      ?? 0),
                $data['model_used']    ?? null,
                $data['input_tokens']  ?? null,
                $data['output_tokens'] ?? null,
                $data['cost_usd']      ?? 0,
                $data['latency_ms']    ?? 0,
                (int)($data['failover_used']  ?? 0),
                (int)($data['error_occurred'] ?? 0),
                $data['user_tier']     ?? 'guest',
            ]);

            // Update system_metrics (load monitoring)
            self::updateMetrics($data['ai_used'] ?? false, $data['latency_ms'] ?? 0);

        } catch (Throwable $e) {
            error_log('[KPILogger] ' . $e->getMessage());
        }
    }

    private static function updateMetrics(bool $aiUsed, int $latency): void {
        try {
            $minute = date('Y-m-d H:i:00');
            db()->prepare(
                'INSERT INTO system_metrics (metric_minute, requests_count, ai_calls_count)
                 VALUES (?, 1, ?)
                 ON DUPLICATE KEY UPDATE
                   requests_count   = requests_count + 1,
                   ai_calls_count   = ai_calls_count + VALUES(ai_calls_count)'
            )->execute([$minute, (int)$aiUsed]);

            // C3 FIX: Dynamically compute load_level based on last-minute RPM
            // 0=normal, 1=elevated, 2=high, 3=critical, 4=overload
            $rpm = (int)(db()->prepare(
                'SELECT SUM(requests_count) FROM system_metrics
                 WHERE metric_minute >= DATE_SUB(NOW(), INTERVAL 1 MINUTE)'
            )->execute() ?: 0);
            $st = db()->prepare('SELECT SUM(requests_count) FROM system_metrics WHERE metric_minute >= DATE_SUB(NOW(), INTERVAL 1 MINUTE)');
            $st->execute();
            $rpm = (int)$st->fetchColumn();

            $loadLevel = match(true) {
                $rpm >= 500 => 4,  // overload: AI off all
                $rpm >= 300 => 3,  // critical: AI off free users
                $rpm >= 150 => 2,  // high: throttle
                $rpm >= 60  => 1,  // elevated
                default     => 0,  // normal
            };

            db()->prepare(
                'UPDATE system_metrics SET load_level=?,
                 ai_disabled_free = ?,
                 ai_disabled_all  = ?
                 WHERE metric_minute=?'
            )->execute([$loadLevel, $loadLevel >= 3 ? 1 : 0, $loadLevel >= 4 ? 1 : 0, $minute]);

        } catch (Throwable $ignored) {}
    }

    public static function getLoadLevel(): int {
        try {
            $st = db()->prepare(
                'SELECT load_level FROM system_metrics
                 ORDER BY metric_minute DESC LIMIT 1'
            );
            $st->execute();
            return (int)($st->fetchColumn() ?? 0);
        } catch (Throwable $ignored) {}
        return 0;
    }

    public static function estimateCost(string $model, int $inputTokens, int $outputTokens): float {
        return match(true) {
            str_contains($model, 'gemini')  => ($inputTokens * 0.00000015) + ($outputTokens * 0.0000006),
            str_contains($model, 'claude')  => ($inputTokens * 0.00000025) + ($outputTokens * 0.00000125),
            str_contains($model, 'gpt')     => ($inputTokens * 0.00000015) + ($outputTokens * 0.0000006),
            default                         => 0.0,
        };
    }
}
