<?php
declare(strict_types=1);


/**
 * Head Cleanup Module
 *
 * Removes unnecessary elements from the WordPress head section.
 *
 * @package ProRank\SEO\Modules\TechnicalSeo
 * @since   1.0.0
 */

namespace ProRank\SEO\Modules\TechnicalSEO;

use ProRank\SEO\Modules\BaseModule;

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


/**
 * HeadCleanupModule class
 *
 * @since 1.0.0
 */


class HeadCleanupModule extends BaseModule {
    /**
     * Module slug
     *
     * @var string
     */
    protected string $slug = 'head_cleanup';
    
    /**
     * Module name
     *
     * @var string
     */
    protected string $name = 'Head Cleanup';
    
    /**
     * Module description
     *
     * @var string
     */
    protected string $description = 'Remove unnecessary code from your site\'s head section for better performance and security.';
    
    /**
     * Required feature tier
     *
     * @var string
     */
    protected string $feature_tier = 'free';
    
    /**
     * Parent module slug
     *
     * @var string|null
     */
    protected ?string $parent_slug = 'technical-seo';

    /**
     * Settings cache
     *
     * @var array|null
     */
    private $settings = null;

    /**
     * Initialize module
     *
     * @return void
     */
    public function init(): void {
        // Load settings
        $this->load_settings();

        // Hook into WordPress head cleanup actions
        $this->setup_head_cleanup();
        
        // Setup URL cleanup features (Tasks 4.19-4.21)
        $this->setup_url_cleanup();
        
        // Register REST endpoints
        add_action('rest_api_init', [$this, 'register_rest_routes']);
    }

    /**
     * Load module settings
     *
     * @return void
     */
    private function load_settings(): void {
        $defaults = [
            // Essential cleanup
            'remove_wp_generator' => false,
            'remove_rsd_link' => false,
            'remove_wlwmanifest_link' => false,
            'remove_emoji_scripts' => false,
            'remove_wp_shortlink' => false,
            
            // Feed links
            'remove_feed_links' => false,
            'remove_feed_links_extra' => false,
            
            // Adjacent posts
            'remove_adjacent_posts_links' => false,
            
            // API and oEmbed
            'remove_rest_api_links' => false,
            'remove_oembed_links' => false,
            'disable_embeds' => false,
            'disable_xmlrpc' => false,
            
            // Scripts and performance
            'remove_dns_prefetch' => false,
            'remove_version_numbers' => false,
            'remove_jquery_migrate' => false,
            
            // Security
            'disable_self_pingbacks' => false,
            'remove_comment_urls' => false,
            'limit_post_revisions' => false,
            'revision_limit' => 5,
            
            // URL cleanup (Tasks 4.19-4.21)
            'strip_category_base' => false,
            'remove_replytocom' => false,
            'redirect_attachments' => false,
            'attachment_redirect_type' => 'parent',
        ];

        $this->settings = wp_parse_args(
            get_option('prorank_seo_head_cleanup', []),
            $defaults
        );
    }

    /**
     * Setup head cleanup actions
     *
     * @return void
     */
    private function setup_head_cleanup(): void {
        // WordPress generator meta tag
        if ($this->settings['remove_wp_generator']) {
            remove_action('wp_head', 'wp_generator');
            add_filter('the_generator', '__return_empty_string');
        }

        // RSD (Really Simple Discovery) link
        if ($this->settings['remove_rsd_link']) {
            remove_action('wp_head', 'rsd_link');
        }

        // Windows Live Writer manifest link
        if ($this->settings['remove_wlwmanifest_link']) {
            remove_action('wp_head', 'wlwmanifest_link');
        }

        // WordPress shortlink
        if ($this->settings['remove_wp_shortlink']) {
            remove_action('wp_head', 'wp_shortlink_wp_head');
            remove_action('template_redirect', 'wp_shortlink_header', 11);
        }

        // Feed links
        if ($this->settings['remove_feed_links']) {
            remove_action('wp_head', 'feed_links', 2);
        }

        // Extra feed links (category, tag, etc.)
        if ($this->settings['remove_feed_links_extra']) {
            remove_action('wp_head', 'feed_links_extra', 3);
        }

        // Adjacent posts links (rel=prev/next)
        if ($this->settings['remove_adjacent_posts_links']) {
            remove_action('wp_head', 'adjacent_posts_rel_link');
            remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
        }

        // REST API links
        if ($this->settings['remove_rest_api_links']) {
            remove_action('wp_head', 'rest_output_link_wp_head');
            remove_action('wp_head', 'wp_oembed_add_discovery_links');
            remove_action('template_redirect', 'rest_output_link_header', 11);
        }

        // oEmbed links
        if ($this->settings['remove_oembed_links']) {
            remove_action('wp_head', 'wp_oembed_add_discovery_links');
            remove_action('wp_head', 'wp_oembed_add_host_js');
            
            // Remove oEmbed-specific JavaScript
            add_action('wp_footer', function() {
                wp_dequeue_script('wp-embed');
            });
        }

        if ($this->settings['disable_embeds']) {
            $this->disable_embeds();
        }

        // Emoji scripts and styles
        if ($this->settings['remove_emoji_scripts']) {
            remove_action('wp_head', 'print_emoji_detection_script', 7);
            remove_action('admin_print_scripts', 'print_emoji_detection_script');
            remove_action('wp_print_styles', 'print_emoji_styles');
            remove_action('admin_print_styles', 'print_emoji_styles');
            remove_filter('the_content_feed', 'wp_staticize_emoji');
            remove_filter('comment_text_rss', 'wp_staticize_emoji');
            remove_filter('wp_mail', 'wp_staticize_emoji_for_email');
            
            // Remove TinyMCE emoji plugin
            add_filter('tiny_mce_plugins', function($plugins) {
                return is_array($plugins) ? array_diff($plugins, ['wpemoji']) : [];
            });
            
            // Remove emoji CDN hostname from DNS prefetching hints
            add_filter('wp_resource_hints', function($urls, $relation_type) {
                if ($relation_type === 'dns-prefetch') {
                    $emoji_svg_url = apply_filters('emoji_svg_url', 'https://s.w.org/images/core/emoji/14.0.0/svg/');
                    $urls = array_filter($urls, function($url) use ($emoji_svg_url) {
                        return strpos($url, 's.w.org') === false;
                    });
                }
                return $urls;
            }, 10, 2);
        }

        // DNS prefetch for s.w.org
        if ($this->settings['remove_dns_prefetch']) {
            add_filter('wp_resource_hints', function($urls, $relation_type) {
                if ($relation_type === 'dns-prefetch') {
                    $urls = array_filter($urls, function($url) {
                        return strpos($url, 's.w.org') === false;
                    });
                }
                return $urls;
            }, 10, 2);
        }

        // Remove version numbers from scripts and styles
        if ($this->settings['remove_version_numbers']) {
            add_filter('style_loader_src', [$this, 'remove_version_from_url'], 9999);
            add_filter('script_loader_src', [$this, 'remove_version_from_url'], 9999);
        }

        // Remove jQuery Migrate
        if ($this->settings['remove_jquery_migrate']) {
            add_action('wp_default_scripts', function($scripts) {
                if (!is_admin() && isset($scripts->registered['jquery'])) {
                    $script = $scripts->registered['jquery'];
                    if ($script->deps) {
                        $script->deps = array_diff($script->deps, ['jquery-migrate']);
                    }
                }
            }, 100);

            add_action('wp_enqueue_scripts', function() {
                if (is_admin()) {
                    return;
                }

                global $wp_scripts;

                if ($wp_scripts instanceof \WP_Scripts && isset($wp_scripts->registered['jquery'])) {
                    $jquery = $wp_scripts->registered['jquery'];
                    if ($jquery->deps) {
                        $jquery->deps = array_diff($jquery->deps, ['jquery-migrate']);
                    }
                }

                wp_dequeue_script('jquery-migrate');
                wp_deregister_script('jquery-migrate');
            }, 100);
        }

        // Disable XML-RPC
        if ($this->settings['disable_xmlrpc']) {
            add_filter('xmlrpc_enabled', '__return_false');
            
            // Remove XML-RPC headers
            add_filter('wp_headers', function($headers) {
                unset($headers['X-Pingback']);
                return $headers;
            });
            
            // Remove XML-RPC link from head
            remove_action('wp_head', 'xmlrpc_rsd_link');
        }

        // Disable self pingbacks
        if ($this->settings['disable_self_pingbacks']) {
            add_action('pre_ping', function(&$links) {
                $home = get_option('home');
                foreach ($links as $l => $link) {
                    if (strpos($link, $home) === 0) {
                        unset($links[$l]);
                    }
                }
            });
        }

        if ($this->settings['remove_comment_urls']) {
            add_filter('comment_form_default_fields', function($fields) {
                unset($fields['url']);
                return $fields;
            }, 20);

            add_filter('preprocess_comment', function($commentdata) {
                $commentdata['comment_author_url'] = '';
                return $commentdata;
            });

            add_filter('get_comment_author_url', '__return_empty_string');
        }

        // Limit post revisions while respecting a hard-disabled wp-config setting.
        if ($this->settings['limit_post_revisions']) {
            add_filter('wp_revisions_to_keep', function($num, $post) {
                $configured_limit = max(1, (int) $this->settings['revision_limit']);

                // Respect wp-config or post-type settings that disable revisions entirely.
                if ((int) $num === 0) {
                    return 0;
                }

                // Unlimited or negative values should be capped by the plugin setting.
                if ((int) $num < 0) {
                    return $configured_limit;
                }

                return min((int) $num, $configured_limit);
            }, 10, 2);
        }
    }

    /**
     * Setup URL cleanup features
     *
     * @return void
     */
    private function setup_url_cleanup(): void {
        // Task 4.19: Strip category base
        if ($this->settings['strip_category_base']) {
            // Add rewrite rules
            add_action('init', [$this, 'add_category_rewrite_rules'], 1);
            add_filter('category_link', [$this, 'remove_category_base_from_permalink']);
            add_action('template_redirect', [$this, 'redirect_old_category_urls']);
        }

        // Task 4.20: Remove ?replytocom parameter
        if ($this->settings['remove_replytocom']) {
            add_filter('comment_reply_link', [$this, 'remove_replytocom_parameter']);
            add_action('template_redirect', [$this, 'redirect_replytocom_urls']);
        }

        // Task 4.21: Redirect attachment pages
        if ($this->settings['redirect_attachments']) {
            add_action('template_redirect', [$this, 'redirect_attachment_pages']);
        }
    }

    /**
     * Disable WordPress embed discovery, routes, scripts, and auto-embeds.
     */
    private function disable_embeds(): void {
        remove_action('rest_api_init', 'wp_oembed_register_route');
        remove_filter('oembed_dataparse', 'wp_filter_oembed_result', 10);
        remove_action('wp_head', 'wp_oembed_add_discovery_links');
        remove_action('wp_head', 'wp_oembed_add_host_js');

        add_filter('embed_oembed_discover', '__return_false');

        add_filter('tiny_mce_plugins', function($plugins) {
            return is_array($plugins) ? array_diff($plugins, ['wpembed']) : [];
        });

        add_action('wp_enqueue_scripts', function() {
            wp_dequeue_script('wp-embed');
            wp_deregister_script('wp-embed');
        }, 100);

        add_action('template_redirect', function() {
            if (!function_exists('is_embed') || !is_embed()) {
                return;
            }

            $target = wp_get_referer();
            if (!$target) {
                $target = home_url('/');
            }

            wp_safe_redirect($target, 301);
            exit;
        }, 1);

        global $wp_embed;
        if ($wp_embed instanceof \WP_Embed) {
            remove_filter('the_content', [$wp_embed, 'autoembed'], 8);
            remove_filter('widget_text_content', [$wp_embed, 'autoembed'], 8);
            remove_filter('widget_block_content', [$wp_embed, 'autoembed'], 8);
        }
    }

    /**
     * Remove version parameter from URL
     *
     * @param string $url The URL to process
     * @return string
     */
    public function remove_version_from_url(string $url): string {
        if (!$url) {
            return $url;
        }
        if ($this->is_prorank_build_asset_url($url)) {
            return $url;
        }

        // Parse URL and remove ver parameter
        $parsed = wp_parse_url($url);
        if (isset($parsed['query'])) {
            parse_str($parsed['query'], $query);
            if (isset($query['ver'])) {
                // Use WP helper so relative URLs and scheme-less URLs are handled safely.
                $url = remove_query_arg('ver', $url);
            }
        }

        return $url;
    }

    /**
     * Keep version query strings for assets that are updated in-place.
     * This avoids stale caches on long-lived immutable cache policies.
     *
     * @param string $url
     * @return bool
     */
    private function is_prorank_build_asset_url(string $url): bool {
        $path = (string) wp_parse_url($url, PHP_URL_PATH);
        if ($path === '') {
            return false;
        }

        return strpos($path, '/wp-content/plugins/prorank-seo/build/') !== false
            || strpos($path, '/wp-content/plugins/prorank-seo/build/') !== false
            || strpos($path, '/wp-content/uploads/elementor/css/') !== false;
    }

    /**
     * Add category rewrite rules without base
     *
     * @return void
     */
    public function add_category_rewrite_rules(): void {
        // Get all categories
        $categories = get_categories(['hide_empty' => false]);
        
        foreach ($categories as $category) {
            $category_nicename = $category->slug;
            if ($category->parent == $category->cat_ID) {
                $category->parent = 0;
            } elseif ($category->parent != 0) {
                $category_nicename = get_category_parents($category->parent, false, '/', true) . $category_nicename;
            }
            
            // Add rewrite rule
            add_rewrite_rule(
                $category_nicename . '/(?:feed/)?(feed|rdf|rss|rss2|atom)/?$',
                'index.php?category_name=' . $category_nicename . '&feed=$matches[1]',
                'top'
            );
            add_rewrite_rule(
                $category_nicename . '/page/?([0-9]{1,})/?$',
                'index.php?category_name=' . $category_nicename . '&paged=$matches[1]',
                'top'
            );
            add_rewrite_rule(
                $category_nicename . '/?$',
                'index.php?category_name=' . $category_nicename,
                'top'
            );
        }
    }

    /**
     * Remove category base from permalink
     *
     * @param string $link Category link
     * @return string
     */
    public function remove_category_base_from_permalink(string $link): string {
        $category_base = get_option('category_base', 'category');
        if (empty($category_base)) {
            $category_base = 'category';
        }
        
        // Remove category base
        $link = str_replace('/' . $category_base . '/', '/', $link);
        
        return $link;
    }

    /**
     * Redirect old category URLs with base
     *
     * @return void
     */
    public function redirect_old_category_urls(): void {
        if (!is_category()) {
            return;
        }

        $host = prorank_get_server_var( 'HTTP_HOST' );
        $request_uri = prorank_get_server_var( 'REQUEST_URI' );
        $current_url = ( is_ssl() ? 'https://' : 'http://' ) . $host . $request_uri;
        $category_base = get_option('category_base', 'category');
        
        if (strpos($current_url, '/' . $category_base . '/') !== false) {
            $new_url = str_replace('/' . $category_base . '/', '/', $current_url);
            wp_redirect($new_url, 301);
            exit;
        }
    }

    /**
     * Remove replytocom parameter from comment links
     *
     * @param string $link Comment reply link
     * @return string
     */
    public function remove_replytocom_parameter(string $link): string {
        return preg_replace('/href=\'(.*?)(\?replytocom=.*?)#(.*)\'/', 'href=\'$1#$3\'', $link);
    }

    /**
     * Redirect URLs with replytocom parameter
     *
     * @return void
     */
    public function redirect_replytocom_urls(): void {
        if (prorank_has_query_var('replytocom')) {
            $redirect_url = remove_query_arg('replytocom');
            $redirect_url .= '#comment-' . absint(prorank_get_query_var('replytocom'));
            wp_redirect($redirect_url, 301);
            exit;
        }
    }

    /**
     * Redirect attachment pages
     *
     * @return void
     */
    public function redirect_attachment_pages(): void {
        if (!is_attachment()) {
            return;
        }

        global $post;
        if (!$post) {
            return;
        }

        $redirect_url = '';
        
        if ($this->settings['attachment_redirect_type'] === 'parent') {
            // Redirect to parent post
            if ($post->post_parent) {
                $redirect_url = get_permalink($post->post_parent);
            } else {
                // No parent, redirect to homepage
                $redirect_url = home_url('/');
            }
        } else {
            // Redirect to media file URL
            $redirect_url = wp_get_attachment_url($post->ID);
        }

        if ($redirect_url) {
            wp_redirect($redirect_url, 301);
            exit;
        }
    }

    /**
     * Register REST API routes
     *
     * @return void
     */
    public function register_rest_routes(): void {
        // Quick settings endpoint for sidebar shell
        register_rest_route('prorank-seo/v1', '/settings/head_cleanup_quick', [
            'methods' => 'GET',
            'callback' => [$this, 'get_quick_settings'],
            'permission_callback' => [$this, 'check_permissions'],
        ]);

        register_rest_route('prorank-seo/v1', '/settings/head_cleanup_quick', [
            'methods' => 'POST',
            'callback' => [$this, 'update_quick_settings'],
            'permission_callback' => [$this, 'check_permissions'],
        ]);
    }

    /**
     * Check REST API permissions
     *
     * @return bool
     */
    public function check_permissions(): bool {
        return current_user_can('manage_options');
    }

    /**
     * Get settings via REST API
     *
     * @return \WP_REST_Response
     */
    public function get_settings(): \WP_REST_Response {
        return rest_ensure_response([
            'success' => true,
            'data' => $this->settings,
        ]);
    }

    /**
     * Get quick settings for sidebar shell
     *
     * @return \WP_REST_Response
     */
    public function get_quick_settings(): \WP_REST_Response {
        $quick_settings = [
            'remove_wp_generator' => $this->settings['remove_wp_generator'],
            'remove_rsd_link' => $this->settings['remove_rsd_link'],
            'remove_wlwmanifest_link' => $this->settings['remove_wlwmanifest_link'],
            'remove_emoji_scripts' => $this->settings['remove_emoji_scripts'],
            'remove_wp_shortlink' => $this->settings['remove_wp_shortlink'],
            'strip_category_base' => $this->settings['strip_category_base'],
            'remove_replytocom' => $this->settings['remove_replytocom'],
            'redirect_attachments' => $this->settings['redirect_attachments'],
            'attachment_redirect_type' => $this->settings['attachment_redirect_type'],
        ];

        return rest_ensure_response([
            'success' => true,
            'data' => $quick_settings,
        ]);
    }

    /**
     * Update settings via REST API
     *
     * @param \WP_REST_Request $request Request object
     * @return \WP_REST_Response
     */
    public function update_settings(\WP_REST_Request $request): \WP_REST_Response {
        $params = $request->get_params();
        
        // Merge with existing settings
        $this->settings = wp_parse_args($params, $this->settings);
        
        // Save settings
        update_option('prorank_seo_head_cleanup', $this->settings);
        
        // Flush rewrite rules if URL settings changed
        if (isset($params['strip_category_base'])) {
            flush_rewrite_rules();
        }

        return rest_ensure_response([
            'success' => true,
            'message' => __('Settings saved successfully.', 'prorank-seo'),
        ]);
    }

    /**
     * Update quick settings via REST API
     *
     * @param \WP_REST_Request $request Request object
     * @return \WP_REST_Response
     */
    public function update_quick_settings(\WP_REST_Request $request): \WP_REST_Response {
        $params = $request->get_params();
        
        // Update only quick settings
        $quick_keys = [
            'remove_wp_generator',
            'remove_rsd_link',
            'remove_wlwmanifest_link',
            'remove_emoji_scripts',
            'remove_wp_shortlink',
            'strip_category_base',
            'remove_replytocom',
            'redirect_attachments',
            'attachment_redirect_type',
        ];

        foreach ($quick_keys as $key) {
            if (isset($params[$key])) {
                $this->settings[$key] = $params[$key];
            }
        }
        
        // Save settings
        update_option('prorank_seo_head_cleanup', $this->settings);
        
        // Flush rewrite rules if URL settings changed
        if (isset($params['strip_category_base'])) {
            flush_rewrite_rules();
        }

        return rest_ensure_response([
            'success' => true,
            'message' => __('Quick settings saved successfully.', 'prorank-seo'),
        ]);
    }

    /**
     * Get head preview data
     *
     * @return \WP_REST_Response
     */
    public function get_head_preview(): \WP_REST_Response {
        $elements = [
            'rsd_link' => !$this->settings['remove_rsd_link'],
            'wlw_manifest' => !$this->settings['remove_wlwmanifest_link'],
            'wp_generator' => !$this->settings['remove_wp_generator'],
            'feed_links' => !$this->settings['remove_feed_links'],
            'feed_links_extra' => !$this->settings['remove_feed_links_extra'],
            'adjacent_posts' => !$this->settings['remove_adjacent_posts_links'],
            'wp_shortlink' => !$this->settings['remove_wp_shortlink'],
            'rest_api_links' => !$this->settings['remove_rest_api_links'],
            'oembed_links' => !$this->settings['remove_oembed_links'],
            'embeds' => !$this->settings['disable_embeds'],
            'emoji_scripts' => !$this->settings['remove_emoji_scripts'],
            'dns_prefetch' => !$this->settings['remove_dns_prefetch'],
            'version_numbers' => !$this->settings['remove_version_numbers'],
        ];

        $active_count = count(array_filter($elements));

        return rest_ensure_response([
            'success' => true,
            'data' => [
                'elements' => $elements,
                'active_count' => $active_count,
            ],
        ]);
    }

    /**
     * Get settings schema
     *
     * @return array
     */
    private function get_settings_schema(): array {
        return [
            'remove_wp_generator' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'remove_rsd_link' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'remove_wlwmanifest_link' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'remove_emoji_scripts' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'remove_wp_shortlink' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'remove_feed_links' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'remove_feed_links_extra' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'remove_adjacent_posts_links' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'remove_rest_api_links' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'remove_oembed_links' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'disable_embeds' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'disable_xmlrpc' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'remove_dns_prefetch' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'remove_version_numbers' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'remove_jquery_migrate' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'disable_self_pingbacks' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'remove_comment_urls' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'limit_post_revisions' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'revision_limit' => [
                'type' => 'integer',
                'default' => 5,
                'minimum' => 1,
                'maximum' => 50,
            ],
            'strip_category_base' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'remove_replytocom' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'redirect_attachments' => [
                'type' => 'boolean',
                'default' => false,
            ],
            'attachment_redirect_type' => [
                'type' => 'string',
                'enum' => ['parent', 'file'],
                'default' => 'parent',
            ],
        ];
    }

    /**
     * Initialize module hooks
     *
     * @return void
     */
    public function init_hooks(): void {
        // Hooks are initialized in the init() method for this module
    }
}
