<?php
class AuditLogger {
    private $conn;
    private $user_id;
    
    public function __construct($conn, $user_id) {
        $this->conn = $conn;
        $this->user_id = $user_id;
    }
    
    /**
     * Log an admin action
     * 
     * @param string $action The type of action performed
     * @param string $details Details about the action
     * @param array $old_values Optional array of old values for update operations
     * @param array $new_values Optional array of new values for update operations
     * @return bool Whether the logging was successful
     */
    public function log($action, $details, $old_values = null, $new_values = null) {
        // Get client IP address
        $ip_address = $_SERVER['REMOTE_ADDR'] ?? '';
        
        // If we have old and new values, create a change log
        if ($old_values && $new_values) {
            $changes = $this->compareValues($old_values, $new_values);
            if (!empty($changes)) {
                $details .= "\nChanges:\n" . implode("\n", $changes);
            }
        }
        
        try {
            $sql = "INSERT INTO admin_logs (user_id, action, details, ip_address) VALUES (?, ?, ?, ?)";
            $stmt = $this->conn->prepare($sql);
            if ($stmt) {
                $stmt->bind_param("isss", $this->user_id, $action, $details, $ip_address);
                return $stmt->execute();
            }
        } catch (Throwable $e) {
            // Table may not exist (e.g. admin_logs); avoid breaking the app
            return false;
        }
        return false;
    }
    
    /**
     * Compare old and new values to generate a change log
     * 
     * @param array $old_values Original values
     * @param array $new_values Updated values
     * @return array Array of change descriptions
     */
    private function compareValues($old_values, $new_values) {
        $changes = array();
        
        foreach ($new_values as $key => $new_value) {
            if (isset($old_values[$key]) && $old_values[$key] !== $new_value) {
                $changes[] = "$key: {$old_values[$key]} → $new_value";
            }
        }
        
        return $changes;
    }
    
    /**
     * Log a company-related action
     * 
     * @param string $action Specific action (create/update/delete/suspend/activate)
     * @param int $company_id Company ID
     * @param string $company_name Company name
     * @param array $old_values Optional old values for updates
     * @param array $new_values Optional new values for updates
     * @return bool Success status
     */
    public function logCompanyAction($action, $company_id, $company_name, $old_values = null, $new_values = null) {
        $action = "company_$action";
        $details = "Company: $company_name (ID: $company_id)";
        return $this->log($action, $details, $old_values, $new_values);
    }
    
    /**
     * Log a user-related action
     * 
     * @param string $action Specific action (create/update/delete/suspend/activate)
     * @param int $affected_user_id The ID of the user being modified
     * @param string $username Username of affected user
     * @param array $old_values Optional old values for updates
     * @param array $new_values Optional new values for updates
     * @return bool Success status
     */
    public function logUserAction($action, $affected_user_id, $username, $old_values = null, $new_values = null) {
        $action = "user_$action";
        $details = "User: $username (ID: $affected_user_id)";
        return $this->log($action, $details, $old_values, $new_values);
    }
    
    /**
     * Log a security-related event
     * 
     * @param string $event_type Type of security event
     * @param string $details Additional details about the event
     * @return bool Success status
     */
    public function logSecurityEvent($event_type, $details) {
        $action = "security_$event_type";
        return $this->log($action, $details);
    }
    
    /**
     * Log a system configuration change
     * 
     * @param string $component Component being modified
     * @param string $details Change details
     * @param array $old_values Old configuration values
     * @param array $new_values New configuration values
     * @return bool Success status
     */
    public function logConfigChange($component, $details, $old_values = null, $new_values = null) {
        $action = "config_change";
        $details = "Component: $component\n$details";
        return $this->log($action, $details, $old_values, $new_values);
    }
}
?>