<?php
class AuditTrail {
    private $db;
    
    public function __construct($database) {
        $this->db = $database;
    }
    
    /**
     * Log a login attempt
     */
    public function logLoginAttempt($user_id, $user_type, $email, $status, $failure_reason = null) {
        try {
            $ip_address = $this->getClientIP();
            $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
            $session_id = session_id();
            
            $stmt = $this->db->prepare("
                INSERT INTO audit_trail (
                    user_id, user_type, email, action, ip_address, 
                    user_agent, status, failure_reason, session_id
                ) VALUES (?, ?, ?, 'login', ?, ?, ?, ?, ?)
            ");
            
            return $stmt->execute([
                $user_id, 
                $user_type, 
                $email, 
                $ip_address, 
                $user_agent, 
                $status, 
                $failure_reason, 
                $session_id
            ]);
            
        } catch (PDOException $e) {
            error_log("Error logging audit trail: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Log a logout action
     */
    public function logLogout($user_id, $user_type, $email) {
        try {
            $ip_address = $this->getClientIP();
            $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'Unknown';
            $session_id = session_id();
            
            $stmt = $this->db->prepare("
                INSERT INTO audit_trail (
                    user_id, user_type, email, action, ip_address, 
                    user_agent, status, session_id
                ) VALUES (?, ?, ?, 'logout', ?, ?, 'success', ?)
            ");
            
            return $stmt->execute([
                $user_id, 
                $user_type, 
                $email, 
                $ip_address, 
                $user_agent, 
                $session_id
            ]);
            
        } catch (PDOException $e) {
            error_log("Error logging logout: " . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Get client IP address (handles proxies)
     */
    private function getClientIP() {
        $ip_keys = ['HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 
                   'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR'];
        
        foreach ($ip_keys as $key) {
            if (array_key_exists($key, $_SERVER) && !empty($_SERVER[$key])) {
                $ip = $_SERVER[$key];
                if (strpos($ip, ',') !== false) {
                    $ip = trim(explode(',', $ip)[0]);
                }
                if (filter_var($ip, FILTER_VALIDATE_IP, 
                    FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
                    return $ip;
                }
            }
        }
        
        return $_SERVER['REMOTE_ADDR'] ?? 'unknown';
    }
    
    /**
     * Get audit trail records with pagination and filtering
     */
    public function getAuditTrail($filters = [], $page = 1, $limit = 50) {
        try {
            $where_conditions = [];
            $params = [];
            
            // Apply filters
            if (!empty($filters['user_type'])) {
                $where_conditions[] = "user_type = ?";
                $params[] = $filters['user_type'];
            }
            
            if (!empty($filters['email'])) {
                $where_conditions[] = "email LIKE ?";
                $params[] = '%' . $filters['email'] . '%';
            }
            
            if (!empty($filters['status'])) {
                $where_conditions[] = "status = ?";
                $params[] = $filters['status'];
            }
            
            if (!empty($filters['action'])) {
                $where_conditions[] = "action = ?";
                $params[] = $filters['action'];
            }
            
            if (!empty($filters['ip_address'])) {
                $where_conditions[] = "ip_address = ?";
                $params[] = $filters['ip_address'];
            }
            
            if (!empty($filters['date_from'])) {
                $where_conditions[] = "DATE(created_at) >= ?";
                $params[] = $filters['date_from'];
            }
            
            if (!empty($filters['date_to'])) {
                $where_conditions[] = "DATE(created_at) <= ?";
                $params[] = $filters['date_to'];
            }
            
            $where_clause = !empty($where_conditions) ? 
                "WHERE " . implode(" AND ", $where_conditions) : "";
            
            // Get total count
            $count_sql = "SELECT COUNT(*) as total FROM audit_trail $where_clause";
            $count_stmt = $this->db->prepare($count_sql);
            $count_stmt->execute($params);
            $total = $count_stmt->fetch()['total'];
            
            // Get records with pagination
            $offset = ($page - 1) * $limit;
            $sql = "SELECT * FROM audit_trail $where_clause 
                   ORDER BY created_at DESC LIMIT $limit OFFSET $offset";
            
            $stmt = $this->db->prepare($sql);
            $stmt->execute($params);
            $records = $stmt->fetchAll();
            
            return [
                'records' => $records,
                'total' => $total,
                'pages' => ceil($total / $limit),
                'current_page' => $page
            ];
            
        } catch (PDOException $e) {
            error_log("Error getting audit trail: " . $e->getMessage());
            return ['records' => [], 'total' => 0, 'pages' => 0, 'current_page' => 1];
        }
    }
    
    /**
     * Get login statistics
     */
    public function getLoginStats($days = 30) {
        try {
            $stmt = $this->db->prepare("
                SELECT 
                    DATE(created_at) as date,
                    user_type,
                    status,
                    COUNT(*) as count
                FROM audit_trail 
                WHERE action = 'login' AND created_at >= DATE_SUB(NOW(), INTERVAL ? DAY)
                GROUP BY DATE(created_at), user_type, status
                ORDER BY date DESC, user_type
            ");
            
            $stmt->execute([$days]);
            return $stmt->fetchAll();
            
        } catch (PDOException $e) {
            error_log("Error getting login stats: " . $e->getMessage());
            return [];
        }
    }
}
?>