<?php
if (!defined('ABSPATH')) {
    exit;
}

/**
 * Activity Log Endpoint Handler
 * 
 * Handles all API requests related to the activity log system.
 * Supports retrieving logs with filtering and setting log preferences.
 */

/**
 * Get activity logs endpoint
 * 
 * @param WP_REST_Request $request The request object
 * @return WP_REST_Response Response object
 */
function wpsec_activity_log_get_endpoint($request) {
    // Validate API key
    if (!wpsec_validate_api_key()) {
        return new WP_Error(
            'rest_forbidden',
            'Sorry, you are not allowed to do that.',
            array('status' => 401)
        );
    }
    
    // Parse query parameters
    $args = array();
    
    // Date range filter
    if (!empty($request['start'])) {
        $args['start_date'] = sanitize_text_field($request['start']);
    }
    
    if (!empty($request['end'])) {
        $args['end_date'] = sanitize_text_field($request['end']);
    }
    
    // Severity filter
    if (!empty($request['severity'])) {
        $args['severity'] = sanitize_text_field($request['severity']);
    }
    
    // Event type filter
    if (!empty($request['event_type'])) {
        $args['event_type'] = sanitize_text_field($request['event_type']);
    }
    
    // User filter
    if (!empty($request['user_id'])) {
        $args['user_id'] = absint($request['user_id']);
    }
    
    if (!empty($request['username'])) {
        $args['username'] = sanitize_text_field($request['username']);
    }
    
    // IP address filter
    if (!empty($request['ip_address'])) {
        $args['ip_address'] = sanitize_text_field($request['ip_address']);
    }
    
    // Object filters
    if (!empty($request['object_type'])) {
        $args['object_type'] = sanitize_text_field($request['object_type']);
    }
    
    if (!empty($request['object_id'])) {
        $args['object_id'] = sanitize_text_field($request['object_id']);
    }
    
    // Pagination
    if (!empty($request['per_page'])) {
        $args['per_page'] = absint($request['per_page']);
    }
    
    if (!empty($request['page'])) {
        $args['page'] = absint($request['page']);
    }
    
    // Sorting
    if (!empty($request['orderby'])) {
        $args['orderby'] = sanitize_text_field($request['orderby']);
    }
    
    if (!empty($request['order'])) {
        $args['order'] = sanitize_text_field($request['order']);
    }
    
    // Get logs with filters
    $logs = wpsec_get_activity_logs($args);
    
    // Add information about available filters in response
    $response = array(
        'status' => 'success',
        'data' => $logs,
        'settings' => array(
            'retention_days' => get_option('wpsec_activity_log_retention_days', 14),
            'max_entries' => get_option('wpsec_activity_log_max_entries', 10000),
        ),
        'available_filters' => array(
            'start' => 'Date filter (YYYY-MM-DD)',
            'end' => 'Date filter (YYYY-MM-DD)',
            'severity' => array('info', 'warning', 'critical'),
            'event_type' => 'String (login_attempt, role_change, etc.)',
            'user_id' => 'Integer',
            'username' => 'String',
            'ip_address' => 'String',
            'object_type' => 'String (user, plugin, file, etc.)',
            'object_id' => 'String or Integer',
            'per_page' => 'Integer (default: 100)',
            'page' => 'Integer (default: 1)',
            'orderby' => array('id', 'timestamp', 'severity', 'event_type', 'user_id', 'username', 'ip_address'),
            'order' => array('ASC', 'DESC')
        )
    );
    
    return new WP_REST_Response($response, 200);
}

/**
 * Update activity log settings endpoint
 * 
 * @param WP_REST_Request $request The request object
 * @return WP_REST_Response Response object
 */
function wpsec_activity_log_settings_endpoint($request) {
    // Validate API key
    if (!wpsec_validate_api_key()) {
        return new WP_Error(
            'rest_forbidden',
            'Sorry, you are not allowed to do that.',
            array('status' => 401)
        );
    }
    
    // Get current settings
    $current_retention_days = get_option('wpsec_activity_log_retention_days', 14);
    $current_max_entries = get_option('wpsec_activity_log_max_entries', 10000);
    
    // Check if this is a settings update request
    if ($request->get_method() === 'POST') {
        $retention_days = $request->get_param('retention_days');
        $max_entries = $request->get_param('max_entries');
        
        // Validate retention days
        if ($retention_days !== null) {
            $retention_days = absint($retention_days);
            if ($retention_days < 1) {
                return new WP_Error(
                    'invalid_retention_days',
                    'Retention days must be at least 1',
                    array('status' => 400)
                );
            }
        } else {
            $retention_days = $current_retention_days;
        }
        
        // Validate max entries
        if ($max_entries !== null) {
            $max_entries = absint($max_entries);
            if ($max_entries < 100) {
                return new WP_Error(
                    'invalid_max_entries',
                    'Max entries must be at least 100',
                    array('status' => 400)
                );
            }
        } else {
            $max_entries = $current_max_entries;
        }
        
        // Update settings
        $updated = wpsec_update_activity_log_settings($retention_days, $max_entries);
        
        if (!$updated) {
            return new WP_Error(
                'update_failed',
                'Failed to update activity log settings',
                array('status' => 500)
            );
        }
        
        // Log the settings change
        wpsec_add_to_activity_log(
            'settings_change',
            sprintf('Activity log settings updated: retention_days=%d, max_entries=%d', $retention_days, $max_entries),
            WPSEC_LOG_INFO,
            'update',
            'settings',
            'activity_log'
        );
        
        $current_retention_days = $retention_days;
        $current_max_entries = $max_entries;
    }
    
    // Return current settings
    $response = array(
        'status' => 'success',
        'settings' => array(
            'retention_days' => $current_retention_days,
            'max_entries' => $current_max_entries,
        ),
        'message' => $request->get_method() === 'POST' ? 'Settings updated successfully' : 'Current settings retrieved'
    );
    
    return new WP_REST_Response($response, 200);
}

/**
 * Clear activity logs endpoint
 * 
 * @param WP_REST_Request $request The request object
 * @return WP_REST_Response Response object
 */
function wpsec_activity_log_clear_endpoint($request) {
    // Validate API key
    if (!wpsec_validate_api_key()) {
        return new WP_Error(
            'rest_forbidden',
            'Sorry, you are not allowed to do that.',
            array('status' => 401)
        );
    }
    
    global $wpdb;
    $table_name = $wpdb->prefix . 'wpsec_activity_log';
    
    // Check if we're preserving critical logs
    $preserve_critical = $request->get_param('preserve_critical');
    $preserve_critical = $preserve_critical === 'true' || $preserve_critical === '1' || $preserve_critical === true;
    
    // Optionally keep critical logs
    if ($preserve_critical) {
        $wpdb->query("DELETE FROM $table_name WHERE severity != 'critical'");
        $cleared = $wpdb->rows_affected;
        $message = sprintf('%d non-critical log entries cleared', $cleared);
    } else {
        $wpdb->query("TRUNCATE TABLE $table_name");
        $message = 'All log entries cleared';
    }
    
    // Log this action
    wpsec_add_to_activity_log(
        'logs_cleared',
        $message,
        WPSEC_LOG_WARNING,
        $preserve_critical ? 'partial_clear' : 'full_clear',
        'activity_log',
        ''
    );
    
    $response = array(
        'status' => 'success',
        'message' => $message
    );
    
    return new WP_REST_Response($response, 200);
}

/**
 * Get log summary endpoint
 * 
 * @param WP_REST_Request $request The request object
 * @return WP_REST_Response Response object
 */
function wpsec_activity_log_summary_endpoint($request) {
    // Validate API key
    if (!wpsec_validate_api_key()) {
        return new WP_Error(
            'rest_forbidden',
            'Sorry, you are not allowed to do that.',
            array('status' => 401)
        );
    }
    
    global $wpdb;
    $table_name = $wpdb->prefix . 'wpsec_activity_log';
    
    // Get date range
    $days = absint($request->get_param('days') ?: 7);
    if ($days < 1 || $days > 90) {
        $days = 7; // Default to 7 days if invalid
    }
    
    $date = gmdate('Y-m-d H:i:s', strtotime("-$days days"));
    
    // Get total count
    $total_count = $wpdb->get_var("SELECT COUNT(*) FROM $table_name");
    
    // Get counts by severity
    $severity_counts = $wpdb->get_results(
        "SELECT severity, COUNT(*) as count FROM $table_name GROUP BY severity",
        OBJECT_K
    );
    
    // Initialize all severities to ensure they exist in response
    $severities = array(
        WPSEC_LOG_INFO => 0,
        WPSEC_LOG_WARNING => 0,
        WPSEC_LOG_CRITICAL => 0
    );
    
    foreach ($severity_counts as $severity => $data) {
        $severities[$severity] = (int) $data->count;
    }
    
    // Get recent activity counts by day
    $daily_counts = $wpdb->get_results(
        $wpdb->prepare(
            "SELECT 
                DATE(timestamp) as date,
                COUNT(*) as total,
                SUM(CASE WHEN severity = 'info' THEN 1 ELSE 0 END) as info,
                SUM(CASE WHEN severity = 'warning' THEN 1 ELSE 0 END) as warning,
                SUM(CASE WHEN severity = 'critical' THEN 1 ELSE 0 END) as critical
            FROM 
                $table_name
            WHERE 
                timestamp >= %s
            GROUP BY 
                DATE(timestamp)
            ORDER BY 
                date ASC",
            $date
        )
    );
    
    // Get top event types
    $top_events = $wpdb->get_results(
        $wpdb->prepare(
            "SELECT 
                event_type,
                COUNT(*) as count
            FROM 
                $table_name
            WHERE 
                timestamp >= %s
            GROUP BY 
                event_type
            ORDER BY 
                count DESC
            LIMIT 10",
            $date
        )
    );
    
    // Get recent critical events
    $critical_events = $wpdb->get_results(
        $wpdb->prepare(
            "SELECT 
                *
            FROM 
                $table_name
            WHERE 
                severity = 'critical'
                AND timestamp >= %s
            ORDER BY 
                timestamp DESC
            LIMIT 10",
            $date
        )
    );
    
    $response = array(
        'status' => 'success',
        'data' => array(
            'total_count' => (int) $total_count,
            'severity_counts' => $severities,
            'daily_activity' => $daily_counts,
            'top_events' => $top_events,
            'recent_critical_events' => $critical_events,
            'timeframe_days' => $days
        )
    );
    
    return new WP_REST_Response($response, 200);
}

/**
 * Export activity logs endpoint
 * 
 * @param WP_REST_Request $request The request object
 * @return WP_REST_Response Response object
 */
function wpsec_activity_log_export_endpoint($request) {
    // Validate API key
    if (!wpsec_validate_api_key()) {
        return new WP_Error(
            'rest_forbidden',
            'Sorry, you are not allowed to do that.',
            array('status' => 401)
        );
    }
    
    // Parse query parameters for filtering
    $args = array();
    
    // Date range filter
    if (!empty($request['start'])) {
        $args['start_date'] = sanitize_text_field($request['start']);
    }
    
    if (!empty($request['end'])) {
        $args['end_date'] = sanitize_text_field($request['end']);
    }
    
    // Severity filter
    if (!empty($request['severity'])) {
        $args['severity'] = sanitize_text_field($request['severity']);
    }
    
    // Set pagination to retrieve all records
    $args['per_page'] = 10000; // Use a high number to get all logs
    
    // Get logs with filters
    $logs = wpsec_get_activity_logs($args);
    
    // Format for export
    $export_data = array();
    foreach ($logs['items'] as $log) {
        $export_data[] = array(
            'id' => $log->id,
            'timestamp' => $log->timestamp,
            'ip_address' => $log->ip_address,
            'user_id' => $log->user_id,
            'username' => $log->username,
            'event_type' => $log->event_type,
            'event_context' => $log->event_context,
            'object_type' => $log->object_type,
            'object_id' => $log->object_id,
            'description' => $log->description,
            'severity' => $log->severity
        );
    }
    
    $response = array(
        'status' => 'success',
        'data' => $export_data,
        'total' => $logs['total'],
        'export_date' => current_time('mysql'),
        'filters' => $args
    );
    
    return new WP_REST_Response($response, 200);
}
