<?php

/**
 * Sentinel REST API Class
 *
 * Handles REST API endpoints for external integrations.
 * Follows WordPress REST API standards and Sentinel's existing patterns.
 */

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

class Sentinel_Rest_API
{

    /**
     * API namespace (different from theme's sentinel/v1 to avoid conflicts)
     */
    const NAMESPACE = 'sentinel-plugin/v1';

    /**
     * Initialize REST API hooks
     */
    public static function init()
    {
        // Only initialize if API access is enabled in settings
        $settings = get_option('sentinel_log_management', array());
        if (empty($settings['api_access'])) {
            return; // API access disabled
        }

        // Register REST API routes
        add_action('rest_api_init', array(__CLASS__, 'register_routes'));
    }

    /**
     * Register all REST API routes
     */
    public static function register_routes()
    {
        // GET /wp-json/sentinel-plugin/v1/logs - Get activity logs
        register_rest_route(self::NAMESPACE, '/logs', array(
            'methods' => WP_REST_Server::READABLE,
            'callback' => array(__CLASS__, 'get_logs'),
            'permission_callback' => array(__CLASS__, 'check_permissions'),
            'args' => array(
                'limit' => array(
                    'default' => 50,
                    'sanitize_callback' => 'absint',
                    'validate_callback' => array(__CLASS__, 'validate_limit'),
                ),
                'offset' => array(
                    'default' => 0,
                    'sanitize_callback' => 'absint',
                ),
                'event_key' => array(
                    'sanitize_callback' => 'sanitize_text_field',
                ),
                'priority' => array(
                    'sanitize_callback' => 'sanitize_text_field',
                ),
                'user_id' => array(
                    'sanitize_callback' => 'absint',
                ),
            ),
        ));

        // GET /wp-json/sentinel-plugin/v1/stats - Get statistics
        register_rest_route(self::NAMESPACE, '/stats', array(
            'methods' => WP_REST_Server::READABLE,
            'callback' => array(__CLASS__, 'get_stats'),
            'permission_callback' => array(__CLASS__, 'check_permissions'),
        ));


        // GET /wp-json/sentinel-plugin/v1/events/types - Get registered event types
        register_rest_route(self::NAMESPACE, '/events/types', array(
            'methods' => WP_REST_Server::READABLE,
            'callback' => array(__CLASS__, 'get_event_types'),
            'permission_callback' => array(__CLASS__, 'check_permissions'),
        ));
    }

    /**
     * Check API permissions
     */
    public static function check_permissions($request)
    {
        // First check if API access is enabled
        $settings = get_option('sentinel_log_management', array());
        if (empty($settings['api_access'])) {
            error_log('[Sentinel] REST API access denied - API access disabled in settings');
            return new WP_Error('rest_forbidden', 'API access is disabled.', array('status' => 403));
        }

        // Check for API key authentication
        $api_key = $request->get_header('X-Sentinel-API-Key');
        if (empty($api_key)) {
            // Check query parameter as fallback
            $api_key = $request->get_param('api_key');
        }

        if (!empty($api_key)) {
            // Validate API key against stored value
            $stored_api_key = $settings['api_key'] ?? '';
            if (!empty($stored_api_key) && hash_equals($stored_api_key, $api_key)) {
                return true; // Valid API key
            } else {
                error_log('[Sentinel] REST API access denied - Invalid API key provided');
                return new WP_Error('rest_forbidden', 'Invalid API key.', array('status' => 403));
            }
        }

        // Try to authenticate using WordPress cookies if available
        $cookie_user = self::authenticate_via_cookies();

        if ($cookie_user && user_can($cookie_user->ID, 'manage_options')) {
            // Set the current user for this request
            wp_set_current_user($cookie_user->ID);
            return true; // Admin user authenticated via cookies
        }

        // Fallback: Standard WordPress authentication check
        $current_user = wp_get_current_user();
        $user_id = $current_user ? $current_user->ID : 0;
        $can_manage = current_user_can('manage_options');

        if ($can_manage || ($user_id > 0 && user_can($user_id, 'manage_options'))) {
            return true; // Admin user with proper capabilities
        }

        // Additional check for WordPress REST API nonce (if provided)
        $nonce = $request->get_header('X-WP-Nonce');
        if (empty($nonce)) {
            $nonce = $request->get_param('_wpnonce');
        }

        if (!empty($nonce) && wp_verify_nonce($nonce, 'wp_rest') && $user_id > 0 && user_can($user_id, 'manage_options')) {
            return true; // Valid nonce with admin user
        }

        // Deny access - no valid authentication method
        return new WP_Error('rest_forbidden', 'API access requires authentication (API key or admin login).', array('status' => 403));
    }

    /**
     * Authenticate user via WordPress cookies for REST API access
     */
    private static function authenticate_via_cookies()
    {
        // Try WordPress's built-in cookie validation
        $user_id = wp_validate_auth_cookie('', 'logged_in');
        if (!$user_id) {
            $user_id = wp_validate_auth_cookie('', 'auth');
        }

        if ($user_id) {
            return get_user_by('id', $user_id);
        }

        return null;
    }

    /**
     * Get logs endpoint - follows patterns from logs.php admin page
     */
    public static function get_logs($request)
    {
        global $wpdb;

        // API request processing

        try {
            $table = $wpdb->prefix . 'sentinel_logs';

            // Build query following same pattern as admin logs page
            $where_conditions = array();
            $where_values = array();

            // Filter by event key if provided
            if ($request->get_param('event_key')) {
                $where_conditions[] = 'event_key = %s';
                $where_values[] = $request->get_param('event_key');
            }

            // Filter by priority if provided
            if ($request->get_param('priority')) {
                $where_conditions[] = 'priority = %s';
                $where_values[] = $request->get_param('priority');
            }

            // Filter by user ID if provided
            if ($request->get_param('user_id')) {
                $where_conditions[] = 'user_id = %d';
                $where_values[] = $request->get_param('user_id');
            }

            // Build WHERE clause
            $where_clause = '';
            if (!empty($where_conditions)) {
                $where_clause = 'WHERE ' . implode(' AND ', $where_conditions);
            }

            // Get total count for pagination info
            $count_query = "SELECT COUNT(*) FROM $table $where_clause";
            $total = empty($where_values)
                ? $wpdb->get_var($count_query)
                : $wpdb->get_var($wpdb->prepare($count_query, $where_values));

            // Get logs with limit and offset
            $limit = $request->get_param('limit');
            $offset = $request->get_param('offset');

            $query = "SELECT * FROM $table $where_clause ORDER BY created_at DESC LIMIT %d OFFSET %d";
            $query_values = array_merge($where_values, array($limit, $offset));

            $logs = $wpdb->get_results($wpdb->prepare($query, $query_values));

            // Format response following WordPress REST API standards
            $response_data = array(
                'logs' => array(),
                'pagination' => array(
                    'total' => intval($total),
                    'limit' => intval($limit),
                    'offset' => intval($offset),
                    'pages' => ceil($total / $limit),
                )
            );

            // Format each log entry
            foreach ($logs as $log) {
                $log_data = array(
                    'id' => intval($log->id),
                    'event_key' => $log->event_key,
                    'category' => $log->category,
                    'priority' => $log->priority,
                    'user_id' => intval($log->user_id),
                    'ip_address' => $log->ip_address,
                    'url' => $log->url,
                    'data' => !empty($log->data) ? json_decode($log->data, true) : array(),
                    'created_at' => $log->created_at,
                );

                // Add user information if available (following admin page pattern)
                if ($log->user_id > 0) {
                    $user = get_user_by('id', $log->user_id);
                    if ($user) {
                        $log_data['user'] = array(
                            'username' => $user->user_login,
                            'display_name' => $user->display_name,
                        );
                    }
                }

                $response_data['logs'][] = $log_data;
            }

            return rest_ensure_response($response_data);
        } catch (Exception $e) {
            error_log('[Sentinel] REST API: get_logs error - ' . $e->getMessage());
            return new WP_Error('rest_internal_error', 'Internal server error', array('status' => 500));
        }
    }

    /**
     * Get statistics endpoint - follows patterns from dashboard
     */
    public static function get_stats($request)
    {

        try {
            global $wpdb;
            $table = $wpdb->prefix . 'sentinel_logs';

            // Get basic stats following dashboard pattern
            $today_logs = $wpdb->get_var("SELECT COUNT(*) FROM $table WHERE DATE(created_at) = CURDATE()");
            $total_logs = $wpdb->get_var("SELECT COUNT(*) FROM $table");
            $active_users_today = $wpdb->get_var("SELECT COUNT(DISTINCT user_id) FROM $table WHERE DATE(created_at) = CURDATE() AND user_id > 0");

            // Get event counts by category
            $categories = $wpdb->get_results("SELECT category, COUNT(*) as count FROM $table GROUP BY category ORDER BY count DESC");

            // Get event counts by priority
            $priorities = $wpdb->get_results("SELECT priority, COUNT(*) as count FROM $table GROUP BY priority ORDER BY count DESC");

            $response_data = array(
                'summary' => array(
                    'total_logs' => intval($total_logs),
                    'today_logs' => intval($today_logs),
                    'active_users_today' => intval($active_users_today),
                ),
                'categories' => array(),
                'priorities' => array(),
            );

            // Format categories
            foreach ($categories as $category) {
                $response_data['categories'][] = array(
                    'name' => $category->category,
                    'count' => intval($category->count),
                );
            }

            // Format priorities
            foreach ($priorities as $priority) {
                $response_data['priorities'][] = array(
                    'name' => $priority->priority,
                    'count' => intval($priority->count),
                );
            }

            return rest_ensure_response($response_data);
        } catch (Exception $e) {
            error_log('[Sentinel] REST API: get_stats error - ' . $e->getMessage());
            return new WP_Error('rest_internal_error', 'Internal server error', array('status' => 500));
        }
    }



    /**
     * Get event types endpoint
     */
    public static function get_event_types($request)
    {

        try {
            // Use existing events registry
            $events = Sentinel_Events::get_all_events();

            $response_data = array(
                'event_types' => array(),
                'total' => count($events),
            );

            foreach ($events as $event_key => $config) {
                $response_data['event_types'][] = array(
                    'key' => $event_key,
                    'label' => isset($config['label']) ? $config['label'] : $event_key,
                    'category' => $config['category'],
                    'priority' => $config['priority'],
                    'description' => isset($config['description']) ? $config['description'] : '',
                );
            }

            return rest_ensure_response($response_data);
        } catch (Exception $e) {
            error_log('[Sentinel] REST API: get_event_types error - ' . $e->getMessage());
            return new WP_Error('rest_internal_error', 'Internal server error', array('status' => 500));
        }
    }

    /**
     * Validate limit parameter
     */
    public static function validate_limit($param, $request, $key)
    {
        if ($param < 1 || $param > 1000) {
            return new WP_Error('rest_invalid_param', 'Limit must be between 1 and 1000', array('status' => 400));
        }
        return true;
    }
}
