<?php

/**
 * Head Cleanup REST API Controller
 *
 * @package ProRank\SEO\Core\RestApi
 * @since   0.1.0
 */

declare(strict_types=1);

namespace ProRank\SEO\Core\RestApi;

use ProRank\SEO\Core\Config\Settings;
use WP_REST_Controller;
use WP_REST_Server;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}


/**
 * Class HeadCleanupController
 * 
 * Handles REST API endpoints for head cleanup settings
 */


class HeadCleanupController extends WP_REST_Controller {
    private const OPTION_NAME = 'prorank_seo_head_cleanup';

    /**
     * Namespace
     *
     * @var string
     */
    protected $namespace = 'prorank-seo/v1';

    /**
     * Rest base
     *
     * @var string
     */
    protected $rest_base = 'settings/head_cleanup';

    /**
     * Register routes
     *
     * @return void
     */
    public function register_routes(): void {
        register_rest_route($this->namespace, '/' . $this->rest_base, [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [$this, 'get_settings'],
                'permission_callback' => [$this, 'get_settings_permissions_check'],
            ],
            [
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => [$this, 'update_settings'],
                'permission_callback' => [$this, 'update_settings_permissions_check'],
                'args'                => $this->get_endpoint_args_for_item_schema(WP_REST_Server::CREATABLE),
            ],
            'schema' => [$this, 'get_public_item_schema'],
        ]);

        // Get current head output for preview
        register_rest_route($this->namespace, '/' . $this->rest_base . '/preview', [
            'methods'             => WP_REST_Server::READABLE,
            'callback'            => [$this, 'get_head_preview'],
            'permission_callback' => [$this, 'get_settings_permissions_check'],
        ]);
    }

    /**
     * Get settings
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
     */
    public function get_settings($request) {
        $settings = $this->load_settings();

        return new WP_REST_Response([
            'settings' => $settings,
        ], 200);
    }

    /**
     * Update settings
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
     */
    public function update_settings($request) {
        $settings = [];

        // Boolean settings
        $boolean_settings = [
            'remove_rsd_link',
            'remove_wlwmanifest_link',
            'remove_wp_generator',
            'remove_feed_links',
            'remove_feed_links_extra',
            'remove_adjacent_posts_links',
            'remove_wp_shortlink',
            'remove_rest_api_links',
            'remove_oembed_links',
            'disable_embeds',
            'remove_emoji_scripts',
            'remove_dns_prefetch',
            'remove_version_numbers',
            'disable_xmlrpc',
            'remove_jquery_migrate',
            'disable_self_pingbacks',
            'remove_comment_urls',
            'limit_post_revisions',
        ];

        foreach ($boolean_settings as $setting) {
            if ($request->has_param($setting)) {
                $settings[$setting] = (bool) $request->get_param($setting);
            }
        }

        // Revision limit
        if ($request->has_param('revision_limit')) {
            $limit = absint($request->get_param('revision_limit'));
            $settings['revision_limit'] = max(1, min(50, $limit)); // Between 1 and 50
        }

        // Get existing settings to merge
        $existing = $this->load_settings();
        $settings = array_merge($existing, $settings);
        unset($settings['settings']);

        $result = update_option(self::OPTION_NAME, $settings);
        Settings::update('head_cleanup', $settings);

        if (!$result && get_option(self::OPTION_NAME, []) !== $settings) {
            return new WP_Error(
                'prorank_settings_save_failed',
                __('Failed to save settings.', 'prorank-seo'),
                ['status' => 500]
            );
        }

        return new WP_REST_Response([
            'success' => true,
            'settings' => $settings,
        ], 200);
    }

    /**
     * Load runtime head cleanup settings from the canonical option.
     *
     * @return array<string, mixed>
     */
    private function load_settings(): array {
        $defaults = [
            'remove_rsd_link' => false,
            'remove_wlwmanifest_link' => false,
            'remove_wp_generator' => false,
            'remove_feed_links' => false,
            'remove_feed_links_extra' => false,
            'remove_adjacent_posts_links' => false,
            'remove_wp_shortlink' => false,
            'remove_rest_api_links' => false,
            'remove_oembed_links' => false,
            'disable_embeds' => false,
            'remove_emoji_scripts' => false,
            'remove_dns_prefetch' => false,
            'remove_version_numbers' => false,
            'disable_xmlrpc' => false,
            'remove_jquery_migrate' => false,
            'disable_self_pingbacks' => false,
            'remove_comment_urls' => false,
            'limit_post_revisions' => false,
            'revision_limit' => 5,
            'strip_category_base' => false,
            'remove_replytocom' => false,
            'redirect_attachments' => false,
            'attachment_redirect_type' => 'parent',
        ];

        $settings = get_option(self::OPTION_NAME, []);
        $settings = is_array($settings) ? $settings : [];
        unset($settings['settings']);

        return wp_parse_args($settings, $defaults);
    }

    /**
     * Get head preview
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
     */
    public function get_head_preview($request) {
        // Get current head elements
        $elements = [
            'rsd_link' => $this->check_head_element('rsd_link'),
            'wlwmanifest_link' => $this->check_head_element('wlwmanifest_link'),
            'wp_generator' => $this->check_head_element('wp_generator'),
            'feed_links' => $this->check_head_element('feed_links'),
            'rest_api_links' => $this->check_head_element('rest_output_link_wp_head'),
            'emoji_scripts' => $this->check_emoji_scripts(),
            'jquery_migrate' => $this->check_jquery_migrate(),
            'xmlrpc' => $this->check_xmlrpc(),
        ];

        return new WP_REST_Response([
            'elements' => $elements,
            'active_count' => count(array_filter($elements)),
        ], 200);
    }

    /**
     * Check if head element is present
     *
     * @param string $function Function name to check
     * @return bool
     */
    private function check_head_element(string $function): bool {
        return has_action('wp_head', $function) !== false;
    }

    /**
     * Check if emoji scripts are enabled
     *
     * @return bool
     */
    private function check_emoji_scripts(): bool {
        return has_action('wp_head', 'print_emoji_detection_script') !== false;
    }

    /**
     * Check if jQuery Migrate is loaded
     *
     * @return bool
     */
    private function check_jquery_migrate(): bool {
        $response = wp_remote_get(
            home_url('/'),
            [
                'timeout'     => 10,
                'redirection' => 3,
            ]
        );

        if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) === 200) {
            $body = wp_remote_retrieve_body($response);
            return is_string($body) && strpos($body, 'jquery-migrate') !== false;
        }

        global $wp_scripts;

        if (!$wp_scripts instanceof \WP_Scripts) {
            return false;
        }

        if (isset($wp_scripts->registered['jquery'])) {
            $jquery = $wp_scripts->registered['jquery'];
            return in_array('jquery-migrate', $jquery->deps, true);
        }

        return false;
    }

    /**
     * Check if XML-RPC is enabled
     *
     * @return bool
     */
    private function check_xmlrpc(): bool {
        return apply_filters('xmlrpc_enabled', true);
    }

    /**
     * Check if a given request has access to get settings
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
     */
    public function get_settings_permissions_check($request) {
        return current_user_can('manage_options');
    }

    /**
     * Check if a given request has access to update settings
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return true|WP_Error True if the request has access to update settings, WP_Error object otherwise.
     */
    public function update_settings_permissions_check($request) {
        return current_user_can('manage_options');
    }

    /**
     * Get schema for settings
     *
     * @return array
     */
    public function get_item_schema(): array {
        if ($this->schema) {
            return $this->add_additional_fields_schema($this->schema);
        }

        $schema = [
            '$schema'    => 'http://json-schema.org/draft-04/schema#',
            'title'      => 'head-cleanup-settings',
            'type'       => 'object',
            'properties' => [
                'remove_rsd_link' => [
                    'description' => __('Remove Really Simple Discovery link.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'remove_wlwmanifest_link' => [
                    'description' => __('Remove Windows Live Writer manifest link.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'remove_wp_generator' => [
                    'description' => __('Remove WordPress version meta tag.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'remove_feed_links' => [
                    'description' => __('Remove RSS feed links.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'remove_feed_links_extra' => [
                    'description' => __('Remove extra RSS feed links.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'remove_adjacent_posts_links' => [
                    'description' => __('Remove adjacent posts links.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'remove_wp_shortlink' => [
                    'description' => __('Remove WordPress shortlink.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'remove_rest_api_links' => [
                    'description' => __('Remove REST API links.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'remove_oembed_links' => [
                    'description' => __('Remove oEmbed discovery links.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'disable_embeds' => [
                    'description' => __('Disable WordPress embeds and auto-embeds.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'remove_emoji_scripts' => [
                    'description' => __('Remove emoji scripts and styles.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'remove_dns_prefetch' => [
                    'description' => __('Remove DNS prefetch links.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'remove_version_numbers' => [
                    'description' => __('Remove version numbers from scripts and styles.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'disable_xmlrpc' => [
                    'description' => __('Disable XML-RPC.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'remove_jquery_migrate' => [
                    'description' => __('Remove jQuery Migrate.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'disable_self_pingbacks' => [
                    'description' => __('Disable self pingbacks.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'remove_comment_urls' => [
                    'description' => __('Remove website URLs from comment forms and new comments.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'limit_post_revisions' => [
                    'description' => __('Limit post revisions.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view', 'edit'],
                    'default'     => false,
                ],
                'revision_limit' => [
                    'description' => __('Number of revisions to keep.', 'prorank-seo'),
                    'type'        => 'integer',
                    'context'     => ['view', 'edit'],
                    'default'     => 5,
                    'minimum'     => 1,
                    'maximum'     => 50,
                ],
            ],
        ];

        $this->schema = $schema;

        return $this->add_additional_fields_schema($this->schema);
    }
}
