<?php
/**
 * Şüpheli Aktivite Tespit Sistemi
 * Kullanıcı davranışlarını analiz ederek şüpheli aktiviteleri tespit eder
 */

class SuspiciousActivityDetector {
    private $pdo;
    private $user_id;
    private $session_id;
    
    public function __construct($pdo, $user_id = null, $session_id = null) {
        $this->pdo = $pdo;
        $this->user_id = $user_id;
        $this->session_id = $session_id;
    }
    
    /**
     * Çoklu giriş denemesi kontrolü
     */
    public function checkMultipleLoginAttempts($user_id, $ip_address, $time_window = 300) {
        try {
            $stmt = $this->pdo->prepare("
                SELECT COUNT(*) as attempt_count 
                FROM user_login_logs 
                WHERE user_id = ? 
                AND ip_address = ? 
                AND login_time > DATE_SUB(NOW(), INTERVAL ? SECOND)
                AND status = 'failed'
            ");
            $stmt->execute([$user_id, $ip_address, $time_window]);
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            
            $attempt_count = $result['attempt_count'];
            
            if ($attempt_count >= 5) {
                $this->createAlert($user_id, 'multiple_login_attempts', [
                    'attempt_count' => $attempt_count,
                    'ip_address' => $ip_address,
                    'time_window' => $time_window
                ], 'high');
                return true;
            }
            
            return false;
        } catch (PDOException $e) {
            error_log("Multiple login attempts check error: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Farklı lokasyonlardan giriş kontrolü
     */
    public function checkMultipleLocations($user_id, $current_ip, $time_window = 3600) {
        try {
            $stmt = $this->pdo->prepare("
                SELECT DISTINCT ip_address, COUNT(*) as login_count
                FROM user_login_logs 
                WHERE user_id = ? 
                AND login_time > DATE_SUB(NOW(), INTERVAL ? SECOND)
                AND status = 'success'
                GROUP BY ip_address
            ");
            $stmt->execute([$user_id, $time_window]);
            $locations = $stmt->fetchAll(PDO::FETCH_ASSOC);
            
            if (count($locations) >= 3) {
                $this->createAlert($user_id, 'multiple_locations', [
                    'location_count' => count($locations),
                    'locations' => $locations,
                    'current_ip' => $current_ip
                ], 'medium');
                return true;
            }
            
            return false;
        } catch (PDOException $e) {
            error_log("Multiple locations check error: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Hızlı bahis kontrolü
     */
    public function checkRapidBetting($user_id, $time_window = 60, $bet_threshold = 10) {
        try {
            $stmt = $this->pdo->prepare("
                SELECT COUNT(*) as bet_count, SUM(amount) as total_amount
                FROM bets 
                WHERE user_id = ? 
                AND created_at > DATE_SUB(NOW(), INTERVAL ? SECOND)
            ");
            $stmt->execute([$user_id, $time_window]);
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            
            $bet_count = $result['bet_count'];
            $total_amount = $result['total_amount'] ?? 0;
            
            if ($bet_count >= $bet_threshold) {
                $this->createAlert($user_id, 'rapid_betting', [
                    'bet_count' => $bet_count,
                    'total_amount' => $total_amount,
                    'time_window' => $time_window
                ], 'medium');
                return true;
            }
            
            return false;
        } catch (PDOException $e) {
            error_log("Rapid betting check error: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Anormal kazanç kontrolü
     */
    public function checkUnusualWinnings($user_id, $win_threshold = 10000, $time_window = 3600) {
        try {
            $stmt = $this->pdo->prepare("
                SELECT SUM(win_amount) as total_winnings, COUNT(*) as win_count
                FROM bets 
                WHERE user_id = ? 
                AND status = 'won'
                AND created_at > DATE_SUB(NOW(), INTERVAL ? SECOND)
            ");
            $stmt->execute([$user_id, $time_window]);
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            
            $total_winnings = $result['total_winnings'] ?? 0;
            $win_count = $result['win_count'] ?? 0;
            
            if ($total_winnings >= $win_threshold) {
                $this->createAlert($user_id, 'unusual_winnings', [
                    'total_winnings' => $total_winnings,
                    'win_count' => $win_count,
                    'time_window' => $time_window
                ], 'high');
                return true;
            }
            
            return false;
        } catch (PDOException $e) {
            error_log("Unusual winnings check error: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Büyük para yatırma kontrolü
     */
    public function checkLargeDeposits($user_id, $amount, $threshold = 5000) {
        try {
            if ($amount >= $threshold) {
                // Son 24 saatteki toplam yatırımları kontrol et
                $stmt = $this->pdo->prepare("
                    SELECT SUM(amount) as total_deposits, COUNT(*) as deposit_count
                    FROM transactions 
                    WHERE user_id = ? 
                    AND type = 'deposit'
                    AND status = 'completed'
                    AND created_at > DATE_SUB(NOW(), INTERVAL 24 HOUR)
                ");
                $stmt->execute([$user_id]);
                $result = $stmt->fetch(PDO::FETCH_ASSOC);
                
                $total_deposits = $result['total_deposits'] ?? 0;
                $deposit_count = $result['deposit_count'] ?? 0;
                
                $this->createAlert($user_id, 'large_deposit', [
                    'current_amount' => $amount,
                    'daily_total' => $total_deposits,
                    'deposit_count' => $deposit_count,
                    'threshold' => $threshold
                ], 'medium');
                return true;
            }
            
            return false;
        } catch (PDOException $e) {
            error_log("Large deposits check error: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Büyük para çekme kontrolü
     */
    public function checkLargeWithdrawals($user_id, $amount, $threshold = 3000) {
        try {
            if ($amount >= $threshold) {
                // Kullanıcının hesap yaşını kontrol et
                $stmt = $this->pdo->prepare("
                    SELECT DATEDIFF(NOW(), created_at) as account_age
                    FROM kullanicilar 
                    WHERE id = ?
                ");
                $stmt->execute([$user_id]);
                $result = $stmt->fetch(PDO::FETCH_ASSOC);
                
                $account_age = $result['account_age'] ?? 0;
                
                $risk_level = 'medium';
                if ($account_age < 7) {
                    $risk_level = 'high';
                } elseif ($amount >= $threshold * 2) {
                    $risk_level = 'high';
                }
                
                $this->createAlert($user_id, 'large_withdrawal', [
                    'amount' => $amount,
                    'threshold' => $threshold,
                    'account_age' => $account_age
                ], $risk_level);
                return true;
            }
            
            return false;
        } catch (PDOException $e) {
            error_log("Large withdrawals check error: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Cihaz değişikliği kontrolü
     */
    public function checkDeviceChange($user_id, $user_agent, $fingerprint = null) {
        try {
            $stmt = $this->pdo->prepare("
                SELECT DISTINCT user_agent, device_fingerprint
                FROM user_sessions 
                WHERE user_id = ? 
                AND created_at > DATE_SUB(NOW(), INTERVAL 30 DAY)
                ORDER BY created_at DESC
                LIMIT 5
            ");
            $stmt->execute([$user_id]);
            $recent_devices = $stmt->fetchAll(PDO::FETCH_ASSOC);
            
            $is_new_device = true;
            foreach ($recent_devices as $device) {
                if ($device['user_agent'] === $user_agent || 
                    ($fingerprint && $device['device_fingerprint'] === $fingerprint)) {
                    $is_new_device = false;
                    break;
                }
            }
            
            if ($is_new_device && count($recent_devices) > 0) {
                $this->createAlert($user_id, 'device_change', [
                    'new_user_agent' => $user_agent,
                    'new_fingerprint' => $fingerprint,
                    'recent_devices' => count($recent_devices)
                ], 'low');
                return true;
            }
            
            return false;
        } catch (PDOException $e) {
            error_log("Device change check error: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Şüpheli aktivite uyarısı oluştur
     */
    private function createAlert($user_id, $activity_type, $activity_data, $risk_level) {
        try {
            // Risk skorunu hesapla
            $risk_score = $this->calculateRiskScore($activity_type, $activity_data, $risk_level);
            
            $stmt = $this->pdo->prepare("
                INSERT INTO detected_suspicious_activities 
                (user_id, rule_id, session_id, activity_type, activity_data, risk_score, risk_level, detection_method, confidence_score, ip_address, user_agent, created_at, status)
                VALUES (?, ?, ?, ?, ?, ?, ?, 'rule_based', ?, ?, ?, NOW(), 'active')
            ");
            
            $rule_id = $this->getRuleIdByType($activity_type);
            $ip_address = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
            $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown';
            
            $stmt->execute([
                $user_id,
                $rule_id,
                $this->session_id,
                $activity_type,
                json_encode($activity_data),
                $risk_score,
                $risk_level,
                85.0, // Confidence score
                $ip_address,
                $user_agent
            ]);
            
            // Admin bildirimini tetikle
            $this->notifyAdmins($user_id, $activity_type, $risk_level, $activity_data);
            
            return $this->pdo->lastInsertId();
        } catch (PDOException $e) {
            error_log("Create alert error: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Risk skorunu hesapla
     */
    private function calculateRiskScore($activity_type, $activity_data, $risk_level) {
        $base_scores = [
            'low' => 25,
            'medium' => 50,
            'high' => 75,
            'critical' => 95
        ];
        
        $score = $base_scores[$risk_level] ?? 50;
        
        // Aktivite tipine göre ek skorlama
        switch ($activity_type) {
            case 'multiple_login_attempts':
                $score += min(($activity_data['attempt_count'] ?? 0) * 5, 20);
                break;
            case 'rapid_betting':
                $score += min(($activity_data['bet_count'] ?? 0) * 2, 15);
                break;
            case 'unusual_winnings':
                $score += min(($activity_data['total_winnings'] ?? 0) / 1000, 20);
                break;
        }
        
        return min($score, 100);
    }
    
    /**
     * Aktivite tipine göre kural ID'sini al
     */
    private function getRuleIdByType($activity_type) {
        try {
            $stmt = $this->pdo->prepare("
                SELECT id FROM alert_rules 
                WHERE rule_type = ? AND is_active = 1 
                LIMIT 1
            ");
            $stmt->execute([$activity_type]);
            $result = $stmt->fetch(PDO::FETCH_ASSOC);
            
            return $result['id'] ?? 1; // Varsayılan kural ID'si
        } catch (PDOException $e) {
            error_log("Get rule ID error: " . $e->getMessage());
            return 1;
        }
    }
    
    /**
     * Adminleri bilgilendir
     */
    private function notifyAdmins($user_id, $activity_type, $risk_level, $activity_data) {
        try {
            // Kullanıcı bilgilerini al
            $stmt = $this->pdo->prepare("SELECT username, email FROM kullanicilar WHERE id = ?");
            $stmt->execute([$user_id]);
            $user = $stmt->fetch(PDO::FETCH_ASSOC);
            
            // Bildirim mesajını oluştur
            $message = "Şüpheli Aktivite Tespit Edildi!\n\n";
            $message .= "Kullanıcı: " . ($user['username'] ?? 'Bilinmeyen') . "\n";
            $message .= "Aktivite Tipi: " . $activity_type . "\n";
            $message .= "Risk Seviyesi: " . strtoupper($risk_level) . "\n";
            $message .= "Detaylar: " . json_encode($activity_data, JSON_UNESCAPED_UNICODE) . "\n";
            $message .= "Zaman: " . date('Y-m-d H:i:s') . "\n";
            
            // Alert notifications tablosuna kaydet
            $stmt = $this->pdo->prepare("
                INSERT INTO alert_notifications 
                (suspicious_activity_id, notification_type, recipient_type, recipient_id, message, status, created_at)
                VALUES (?, 'email', 'admin', ?, ?, 'pending', NOW())
            ");
            
            // Son eklenen şüpheli aktivite ID'sini al
            $activity_id = $this->pdo->lastInsertId();
            
            $stmt->execute([
                $activity_id,
                1, // Admin user ID
                $message
            ]);
            
        } catch (PDOException $e) {
            error_log("Notify admins error: " . $e->getMessage());
        }
    }
    
    /**
     * Tüm kontrolleri çalıştır
     */
    public function runAllChecks($user_id, $context = []) {
        $alerts = [];
        
        // IP adresi ve user agent bilgilerini al
        $ip_address = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
        $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown';
        
        // Çoklu giriş kontrolü
        if ($this->checkMultipleLoginAttempts($user_id, $ip_address)) {
            $alerts[] = 'multiple_login_attempts';
        }
        
        // Çoklu lokasyon kontrolü
        if ($this->checkMultipleLocations($user_id, $ip_address)) {
            $alerts[] = 'multiple_locations';
        }
        
        // Hızlı bahis kontrolü
        if ($this->checkRapidBetting($user_id)) {
            $alerts[] = 'rapid_betting';
        }
        
        // Anormal kazanç kontrolü
        if ($this->checkUnusualWinnings($user_id)) {
            $alerts[] = 'unusual_winnings';
        }
        
        // Cihaz değişikliği kontrolü
        if ($this->checkDeviceChange($user_id, $user_agent)) {
            $alerts[] = 'device_change';
        }
        
        // Bağlam bazlı kontroller
        if (isset($context['deposit_amount'])) {
            if ($this->checkLargeDeposits($user_id, $context['deposit_amount'])) {
                $alerts[] = 'large_deposit';
            }
        }
        
        if (isset($context['withdrawal_amount'])) {
            if ($this->checkLargeWithdrawals($user_id, $context['withdrawal_amount'])) {
                $alerts[] = 'large_withdrawal';
            }
        }
        
        return $alerts;
    }
}
?>