<?php

declare(strict_types=1);

namespace WPUltimateSecurity\UltimateSecurity\Modules\Maintenance;

use WPUltimateSecurity\UltimateSecurity\Modules\Base\AbstractModule;
use WPUltimateSecurity\UltimateSecurity\Support\Helpers\Utils;
use WP_REST_Request;
use WP_REST_Response;

class MoreTools extends AbstractModule
{
    public const MODULE_ID = 'maintenance.more_tools';

    protected const VERSION = '2.0.0';

    /**
     * Get unique module identifier.
     */
    public static function getId(): string
    {
        return self::MODULE_ID;
    }

    /**
     * Get human-readable module name.
     */
    public static function getName(): string
    {
        return __('More Tools', 'ultimate-security');
    }

    /**
     * Get module domain.
     */
    public static function getDomain(): string
    {
        return 'maintenance';
    }

    /**
     * Boot the module after registration.
     */
    public static function boot(): void
    {
        // Registration code here
        add_action('rest_api_init', [self::class, 'register_routes']);
    }

    public static function register_routes()
    {
        register_rest_route('ultimate-security/v1', '/rest-status', [
            'methods' => 'GET',
            'callback' => [self::class, 'get_rest_status'],
            'permission_callback' => function () {
                return current_user_can('manage_options');
            },
        ]);

        register_rest_route('ultimate-security/v1', '/ping', [
            'methods' => ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'],
            'callback' => function () {
                return ['status' => 'alive'];
            },
            'permission_callback' => '__return_true', // ✅ allow without auth
        ]);

        register_rest_route('ultimate-security/v1', '/cron-status', [
            'methods' => 'GET',
            'callback' => [self::class, 'get_cron_status'],
            'permission_callback' => function () {
                return current_user_can('manage_options');
            },
        ]);

        register_rest_route('ultimate-security/v1', '/run-cron', [
            'methods' => 'POST',
            'callback' => [self::class, 'run_cron'],
            'permission_callback' => function () {
                return current_user_can('manage_options');
            },
            'args' => [
                'event' => [
                    'type' => 'string',
                ],
            ],
        ]);

        register_rest_route('ultimate-security/v1', '/server-status', [
            'methods' => 'GET',
            'callback' => [self::class, 'get_server_status'],
            'permission_callback' => function () {
                return current_user_can('manage_options');
            },
        ]);



        // Reset settings to defaults
        register_rest_route('ultimate-security/v1', '/reset-settings', [
            'methods' => 'POST',
            'callback' => [self::class, 'reset_settings'],
            'permission_callback' => function () {
                return current_user_can('manage_options');
            },
        ]);

        // Clear plugin cache/transients
        register_rest_route('ultimate-security/v1', '/clear-cache', [
            'methods' => 'POST',
            'callback' => [self::class, 'clear_cache'],
            'permission_callback' => function () {
                return current_user_can('manage_options');
            },
        ]);

    }
    public static function get_rest_status(WP_REST_Request $request)
    {
        $methods = [
            'GET',
            'POST',
            'PUT',
            'PATCH',
            'DELETE',
            'HEAD',
            'OPTIONS',
        ];

        $results = [];

        foreach ($methods as $method) {
            $test = wp_remote_request(
                rest_url('ultimate-security/v1/ping'),
                [
                    'method' => $method,
                    'timeout' => 5,
                ]
            );

            $key = strtolower($method) . '_request_status';

            if (is_wp_error($test)) {
                $results[$key] = 'Error: ' . $test->get_error_message();
                continue;
            }

            $code = wp_remote_retrieve_response_code($test);

            // HEAD often returns 200 with no body — that's fine
            // OPTIONS often returns 200 or 204 — also fine
            $results[$key] = ($code >= 200 && $code < 300) ? 'OK' : (string) $code;
        }

        return new WP_REST_Response($results);
    }


    public static function get_cron_status(WP_REST_Request $request)
    {
        $crons = _get_cron_array();
        $response = [];

        if (!$crons) {
            return new WP_REST_Response([], 200);
        }

        foreach ($crons as $timestamp => $cron) {
            foreach ($cron as $hook => $instances) {
                // Only show your plugin's events
                if (strpos($hook, 'ultimate_security') !== 0) {
                    continue;
                }

                // Skip orphaned hooks (no function hooked to this event)
                if (!has_action($hook)) {
                    continue;
                }

                foreach ($instances as $sig => $details) {
                    $next_run = ($timestamp > time())
                        ? "In " . human_time_diff(time(), $timestamp)
                        : "Missed";

                    // Get last manual run time from transient
                    $last_run_data = get_transient('ultimate_security_cron_last_run_' . md5($hook));
                    $last_run = null;
                    if ($last_run_data && isset($last_run_data['timestamp'])) {
                        $last_run = human_time_diff($last_run_data['timestamp'], current_time('timestamp')) . ' ago';
                    }

                    $response[] = [
                        'event' => $hook,
                        'next_run' => $next_run,
                        'schedule' => $details['schedule'] ?? 'One-time',
                        'action' => 'Run Manually',
                        'last_manual_run' => $last_run,
                    ];
                }
            }
        }

        return new WP_REST_Response($response, 200);
    }

    public static function get_server_status(WP_REST_Request $request)
    {
        $memory_limit = ini_get('memory_limit');
        $max_execution_time = ini_get('max_execution_time');
        $current_usage = memory_get_usage(true);

        $memory_limit_bytes = wp_convert_hr_to_bytes($memory_limit);
        $usage_percent = $memory_limit_bytes > 0 ? round(($current_usage / $memory_limit_bytes) * 100, 2) : 0;

        return new WP_REST_Response(
            [
                'memory_limit' => $memory_limit,
                'current_usage' => size_format($current_usage),
                'usage_percent' => $usage_percent . '%',
                'max_execution_time' => $max_execution_time . ' seconds',
            ]
        );
    }

    public static function run_cron(WP_REST_Request $request)
    {
        $event = sanitize_text_field($request->get_param('event'));
        $crons = _get_cron_array();

        $eventFound = false;

        if ($crons) {
            foreach ($crons as $timestamp => $cron) {
                if (isset($cron[$event])) {
                    $eventFound = true;
                    // Run the cron hook manually
                    do_action($event);

                    // Save last run timestamp for history tracking
                    set_transient(
                        'ultimate_security_cron_last_run_' . md5($event),
                        [
                            'timestamp' => current_time('timestamp'),
                            'success' => true,
                        ],
                        WEEK_IN_SECONDS
                    );

                    break;
                }
            }
        }

        if (!$eventFound) {
            return new WP_REST_Response(
                ['success' => false, 'message' => "Event '$event' not scheduled."],
                404
            );
        }

        return new WP_REST_Response(
            ['success' => true, 'message' => "Event '$event' executed successfully."],
            200
        );
    }

    /**
     * Reset all plugin settings to defaults
     */
    public static function reset_settings(WP_REST_Request $request)
    {
        // Get default options from Utils
        $defaults = Utils::ultimate_security_get_default_options();

        // Update with defaults
        Utils::ultimate_security_update_option($defaults);

        return new WP_REST_Response([
            'success' => true,
            'message' => 'All settings have been reset to defaults.',
        ], 200);
    }

    /**
     * Clear all plugin transients and caches
     */
    public static function clear_cache(WP_REST_Request $request)
    {
        global $wpdb;

        // Delete all transients with ultimate_security prefix
        $deleted = $wpdb->query(
            $wpdb->prepare(
                "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s",
                '_transient_ultimate_security%',
                '_transient_timeout_ultimate_security%'
            )
        );

        // Also delete from sitemeta for multisite
        if (is_multisite()) {
            $wpdb->query(
                $wpdb->prepare(
                    "DELETE FROM {$wpdb->sitemeta} WHERE meta_key LIKE %s OR meta_key LIKE %s",
                    '_site_transient_ultimate_security%',
                    '_site_transient_timeout_ultimate_security%'
                )
            );
        }

        $cache_count = max(0, intval($deleted / 2));

        return new WP_REST_Response([
            'success' => true,
            'message' => sprintf('Cleared %d cache entries.', $cache_count),
            'deleted_count' => $cache_count,
        ], 200);
    }

}
