<?php
/**
 * Server-side Game Validation API
 * Copyright (c) 2026 Wspólnie - wspolpraca@togethere.cloud
 * Weryfikuje wyniki gier po stronie serwera
 */

// Ochrona przed bezpośrednim dostępem
if (!defined('VALID_REQUEST')) {
    die('Direct access not permitted');
}

class GameValidator {
    private $db;
    private $maxScore = 10;
    private $minGameDuration = 30; // sekundy
    private $maxGameDuration = 600; // 10 minut
    
    public function __construct($db) {
        $this->db = $db;
    }
    
    /**
     * Waliduje wynik gry
     * @param array $gameData - Dane z gry
     * @return array - Rezultat walidacji
     */
    public function validateGameResult($gameData) {
        $errors = [];
        
        // 1. Sprawdź czy wszystkie wymagane pola są obecne
        $requiredFields = ['playerScore', 'botScore', 'gameDuration', 'difficulty', 'sessionToken'];
        foreach ($requiredFields as $field) {
            if (!isset($gameData[$field])) {
                $errors[] = "Missing required field: $field";
            }
        }
        
        if (!empty($errors)) {
            return ['valid' => false, 'errors' => $errors];
        }
        
        // 2. Sprawdź token sesji
        if (!$this->validateSessionToken($gameData['sessionToken'])) {
            $errors[] = "Invalid session token";
        }
        
        // 3. Sprawdź wyniki
        if ($gameData['playerScore'] > $this->maxScore || $gameData['botScore'] > $this->maxScore) {
            $errors[] = "Score exceeds maximum allowed";
        }
        
        if ($gameData['playerScore'] < 0 || $gameData['botScore'] < 0) {
            $errors[] = "Negative scores not allowed";
        }
        
        // Jeden z graczy musi mieć 10 punktów
        if ($gameData['playerScore'] != $this->maxScore && $gameData['botScore'] != $this->maxScore) {
            $errors[] = "Invalid game end condition";
        }
        
        // 4. Sprawdź czas gry
        if ($gameData['gameDuration'] < $this->minGameDuration) {
            $errors[] = "Game duration too short (possible speed hack)";
        }
        
        if ($gameData['gameDuration'] > $this->maxGameDuration) {
            $errors[] = "Game duration too long";
        }
        
        // 5. Sprawdź statystyki gracza (wykryj cheating)
        if (!$this->checkPlayerStats($gameData)) {
            $errors[] = "Suspicious player statistics detected";
        }
        
        // 6. Rate limiting - max 10 gier na godzinę
        if (!$this->checkRateLimit($gameData['userId'])) {
            $errors[] = "Too many games in short time";
        }
        
        if (!empty($errors)) {
            $this->logSuspiciousActivity($gameData, $errors);
            return ['valid' => false, 'errors' => $errors];
        }
        
        return ['valid' => true, 'message' => 'Game result validated successfully'];
    }
    
    /**
     * Waliduje token sesji
     */
    private function validateSessionToken($token) {
        // TODO: Zaimplementuj weryfikację tokenu z bazy danych
        // Token powinien być generowany przy starcie gry i weryfikowany tutaj
        
        if (empty($token) || strlen($token) < 32) {
            return false;
        }
        
        // Przykładowa weryfikacja (zaimplementuj według swojej logiki)
        /*
        $stmt = $this->db->prepare("SELECT * FROM game_sessions WHERE token = ? AND expires_at > NOW()");
        $stmt->execute([$token]);
        return $stmt->rowCount() > 0;
        */
        
        return true; // Tymczasowo
    }
    
    /**
     * Sprawdza statystyki gracza pod kątem cheating
     */
    private function checkPlayerStats($gameData) {
        // Przykładowe sprawdzenia:
        
        // 1. Niemożliwy czas reakcji
        if (isset($gameData['averageReactionTime']) && $gameData['averageReactionTime'] < 50) {
            return false; // Ludzki czas reakcji to ~150-250ms
        }
        
        // 2. Idealna celność (100%) jest podejrzana
        if (isset($gameData['accuracy']) && $gameData['accuracy'] >= 99) {
            return false;
        }
        
        // 3. Sprawdź historię gracza
        $userId = $gameData['userId'] ?? null;
        if ($userId) {
            $winRate = $this->getPlayerWinRate($userId);
            if ($winRate > 95) { // 95%+ win rate jest podejrzane
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * Sprawdza rate limiting
     */
    private function checkRateLimit($userId) {
        if (!$userId) return true;
        
        // TODO: Zaimplementuj sprawdzanie w bazie
        /*
        $stmt = $this->db->prepare("
            SELECT COUNT(*) as game_count 
            FROM game_results 
            WHERE user_id = ? AND created_at > DATE_SUB(NOW(), INTERVAL 1 HOUR)
        ");
        $stmt->execute([$userId]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        
        return $result['game_count'] < 10;
        */
        
        return true; // Tymczasowo
    }
    
    /**
     * Pobiera współczynnik wygranych gracza
     */
    private function getPlayerWinRate($userId) {
        // TODO: Zaimplementuj
        /*
        $stmt = $this->db->prepare("
            SELECT 
                (SUM(CASE WHEN player_score = 10 THEN 1 ELSE 0 END) * 100.0 / COUNT(*)) as win_rate
            FROM game_results 
            WHERE user_id = ?
        ");
        $stmt->execute([$userId]);
        $result = $stmt->fetch(PDO::FETCH_ASSOC);
        return $result['win_rate'] ?? 0;
        */
        
        return 50; // Tymczasowo
    }
    
    /**
     * Loguje podejrzaną aktywność
     */
    private function logSuspiciousActivity($gameData, $errors) {
        // TODO: Zapisz do bazy danych lub pliku log
        $logEntry = [
            'timestamp' => date('Y-m-d H:i:s'),
            'user_id' => $gameData['userId'] ?? 'unknown',
            'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
            'errors' => $errors,
            'data' => $gameData
        ];
        
        // Zapisz do pliku log
        $logFile = __DIR__ . '/../../logs/suspicious_activity.log';
        file_put_contents($logFile, json_encode($logEntry) . PHP_EOL, FILE_APPEND);
        
        // Opcjonalnie: wyślij alert do adminów
        // mail('admin@example.com', 'Suspicious game activity', json_encode($logEntry));
    }
    
    /**
     * Zapisuje zweryfikowany wynik gry
     */
    public function saveGameResult($gameData) {
        // TODO: Zapisz do bazy danych
        /*
        $stmt = $this->db->prepare("
            INSERT INTO game_results 
            (user_id, player_score, bot_score, difficulty, game_duration, created_at)
            VALUES (?, ?, ?, ?, ?, NOW())
        ");
        
        return $stmt->execute([
            $gameData['userId'],
            $gameData['playerScore'],
            $gameData['botScore'],
            $gameData['difficulty'],
            $gameData['gameDuration']
        ]);
        */
        
        return true;
    }
}

/**
 * Endpoint API do walidacji wyników
 */
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    define('VALID_REQUEST', true);
    
    header('Content-Type: application/json');
    
    // Pobierz dane z requestu
    $input = file_get_contents('php://input');
    $gameData = json_decode($input, true);
    
    if (!$gameData) {
        http_response_code(400);
        echo json_encode(['error' => 'Invalid JSON data']);
        exit;
    }
    
    // TODO: Połącz z bazą danych
    // $db = new PDO(...);
    $db = null;
    
    $validator = new GameValidator($db);
    $result = $validator->validateGameResult($gameData);
    
    if ($result['valid']) {
        $validator->saveGameResult($gameData);
        http_response_code(200);
        echo json_encode([
            'success' => true,
            'message' => 'Game result validated and saved'
        ]);
    } else {
        http_response_code(400);
        echo json_encode([
            'success' => false,
            'errors' => $result['errors']
        ]);
    }
}
?>
