<?php

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

class SEO_Fury_Robots {

    public function __construct() {
        $this->init_hooks();
    }

    private function init_hooks() {
        add_filter('robots_txt', array($this, 'filter_robots_txt'), 10, 2);
        add_action('wp_ajax_seo_reset_robots', array($this, 'ajax_reset_robots'));
        add_action('wp_ajax_seo_delete_physical_robots', array($this, 'ajax_delete_physical_robots'));
        add_action('wp_ajax_seo_fury_preview_robots', array($this, 'ajax_preview_robots'));

        // If a physical robots.txt file exists, Apache/Nginx serves it directly
        // and WordPress never runs. We intercept the request early via
        // init + REQUEST_URI so our virtual robots.txt always wins.
        add_action('init', array($this, 'maybe_intercept_robots'), 0);
    }

    public function register_settings() {
        $sanitize_checkbox = array('sanitize_callback' => 'absint');
        $sanitize_textarea = array('sanitize_callback' => 'sanitize_textarea_field');

        register_setting('seo_fury_robots_group', 'seo_fury_robots_enabled', $sanitize_checkbox);
        register_setting('seo_fury_robots_group', 'seo_fury_robots_content', $sanitize_textarea);
        register_setting('seo_fury_robots_group', 'seo_fury_robots_user_agents', $sanitize_textarea);
        register_setting('seo_fury_robots_group', 'seo_fury_robots_crawl_delay', $sanitize_textarea);
        register_setting('seo_fury_robots_group', 'seo_fury_robots_use_dynamic_vars', $sanitize_checkbox);
        register_setting('seo_fury_robots_group', 'seo_fury_robots_block_ai_bots', $sanitize_checkbox);
        register_setting('seo_fury_robots_group', 'seo_fury_robots_ai_bots_granular', array(
            'sanitize_callback' => array($this, 'sanitize_ai_bots_granular'),
        ));
        register_setting('seo_fury_robots_group', 'seo_fury_robots_block_archive_bots', $sanitize_checkbox);

        add_settings_section(
            'seo_fury_robots_section',
            '',
            array($this, 'robots_section_callback'),
            'seo_fury_robots_group'
        );

        add_settings_field('seo_fury_robots_enabled', __('Enable virtual robots.txt', 'seo-fury'), array($this, 'robots_enabled_callback'), 'seo_fury_robots_group', 'seo_fury_robots_section');
        add_settings_field('seo_fury_robots_content', __('robots.txt Content', 'seo-fury'), array($this, 'robots_content_callback'), 'seo_fury_robots_group', 'seo_fury_robots_section');
        add_settings_field('seo_fury_robots_user_agents', __('Additional User-agent Blocks', 'seo-fury'), array($this, 'robots_user_agents_callback'), 'seo_fury_robots_group', 'seo_fury_robots_section');
        add_settings_field('seo_fury_robots_crawl_delay', __('Crawl-delay for bots', 'seo-fury'), array($this, 'robots_crawl_delay_callback'), 'seo_fury_robots_group', 'seo_fury_robots_section');
        add_settings_field('seo_fury_robots_use_dynamic_vars', __('Use dynamic variables', 'seo-fury'), array($this, 'robots_use_dynamic_vars_callback'), 'seo_fury_robots_group', 'seo_fury_robots_section');
        add_settings_field('seo_fury_robots_block_ai_bots', __('Block AI bots', 'seo-fury'), array($this, 'robots_block_ai_bots_callback'), 'seo_fury_robots_group', 'seo_fury_robots_section');
        add_settings_field('seo_fury_robots_block_archive_bots', __('Block web archive bots', 'seo-fury'), array($this, 'robots_block_archive_bots_callback'), 'seo_fury_robots_group', 'seo_fury_robots_section');
        add_settings_field('seo_fury_robots_reset', __('Reset settings', 'seo-fury'), array($this, 'robots_reset_callback'), 'seo_fury_robots_group', 'seo_fury_robots_section');
        add_settings_field('seo_fury_robots_link', __('Current robots.txt', 'seo-fury'), array($this, 'robots_link_callback'), 'seo_fury_robots_group', 'seo_fury_robots_section');
    }

    public function robots_section_callback() {
        $robots_path = ABSPATH . 'robots.txt';
        if (file_exists($robots_path)) {
            $physical_content = file_get_contents($robots_path);
            ?>
            <div class="notice notice-warning inline">
                <p>
                    <strong><?php esc_html_e('Warning!', 'seo-fury'); ?></strong> <?php esc_html_e('A physical robots.txt file was found in the site root.', 'seo-fury'); ?>
                    <?php esc_html_e('The plugin will override it with the virtual version, but it is recommended to delete the physical file to avoid confusion.', 'seo-fury'); ?>
                </p>
                <p>
                    <button type="button" id="seo-delete-physical-robots" class="button button-secondary" style="color: #d63638; border-color: #d63638;">
                        <?php esc_html_e('Delete physical robots.txt', 'seo-fury'); ?>
                    </button>
                    <span id="seo-delete-robots-status" style="margin-left: 10px;"></span>
                </p>
                <details>
                    <summary><?php esc_html_e('Show physical file contents', 'seo-fury'); ?></summary>
                    <pre style="background: var(--sf-gray-100, #f5f5f5); padding: 10px; overflow: auto; max-height: 300px;"><?php echo esc_html($physical_content); ?></pre>
                </details>
            </div>
            <script>
            jQuery(document).ready(function($) {
                $('#seo-delete-physical-robots').on('click', function() {
                    if (!confirm('<?php echo esc_js(__('Delete the physical robots.txt file? The virtual robots.txt from SEO Fury will be used instead.', 'seo-fury')); ?>')) {
                        return;
                    }
                    var $btn = $(this);
                    var $status = $('#seo-delete-robots-status');
                    $btn.prop('disabled', true);
                    $status.html('<span style="color: orange;">...</span>');
                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: {
                            action: 'seo_delete_physical_robots',
                            _ajax_nonce: '<?php echo esc_js( wp_create_nonce('seo_delete_physical_robots_nonce') ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>'
                        },
                        success: function(response) {
                            if (response.success) {
                                $status.html('<span style="color: green;">' + response.data + '</span>');
                                setTimeout(function() { location.reload(); }, 800);
                            } else {
                                $status.html('<span style="color: red;">' + (response.data || 'Error') + '</span>');
                                $btn.prop('disabled', false);
                            }
                        },
                        error: function() {
                            $status.html('<span style="color: red;">AJAX error</span>');
                            $btn.prop('disabled', false);
                        }
                    });
                });
            });
            </script>
            <?php
        } else {
            ?>
            <div class="notice notice-info inline">
                <p>
                    <?php esc_html_e('No physical robots.txt file found in the site root.', 'seo-fury'); ?>
                    <?php esc_html_e('The virtual WordPress robots.txt is used.', 'seo-fury'); ?>
                </p>
            </div>
            <?php
        }
    }

    public function robots_enabled_callback() {
        $enabled = get_option('seo_fury_robots_enabled', 1);
        ?>
        <label>
            <input type="checkbox" name="seo_fury_robots_enabled" value="1" <?php checked($enabled, 1); ?> />
            <?php esc_html_e('Enable virtual robots.txt', 'seo-fury'); ?>
        </label>
        <?php
    }

    public function robots_content_callback() {
        $content = get_option('seo_fury_robots_content', '');
        if (empty($content)) {
            $content = $this->get_default_robots_template();
        }
        ?>
        <textarea name="seo_fury_robots_content" rows="20" cols="80" class="large-text code" style="font-family: monospace; width: 100%;"><?php echo esc_textarea($content); ?></textarea>
        <p class="description">
            <?php esc_html_e('robots.txt editor. Available variables:', 'seo-fury'); ?>
            <code>{site_url}</code>,
            <code>{home_url}</code>,
            <code>{uploads_path}</code>.
        </p>

        <div id="sf-robots-preview-wrap" data-nonce="<?php echo esc_attr( wp_create_nonce( 'seo_fury_robots_preview' ) ); ?>" style="margin-top:12px;">
            <button type="button" class="button" id="sf-robots-preview-btn"><?php esc_html_e( 'Preview &amp; check robots.txt', 'seo-fury' ); ?></button>
            <p class="description" style="margin-top:6px;"><?php esc_html_e( 'Shows the full robots.txt as it is currently served (save your changes first), including sitemaps, AI-bot and crawl-delay blocks, and flags common problems.', 'seo-fury' ); ?></p>
            <div id="sf-robots-lint" style="margin-top:8px;"></div>
            <pre id="sf-robots-preview" style="display:none;background:#1e1e2e;color:#e5e7eb;padding:14px;border-radius:8px;overflow:auto;max-height:340px;font-size:12px;line-height:1.5;"></pre>
        </div>
        <script>
        (function($){
            var $wrap = $('#sf-robots-preview-wrap'); if (!$wrap.length) { return; }
            var nonce = $wrap.data('nonce');
            var icons = { error: '⛔', warning: '⚠️', info: 'ℹ️' };
            var colors = { error: '#d63638', warning: '#bd8600', info: '#2271b1' };
            $('#sf-robots-preview-btn').on('click', function(){
                var btn = $(this); var orig = btn.text();
                btn.prop('disabled', true).text('…');
                $.post(ajaxurl, { action: 'seo_fury_preview_robots', nonce: nonce }, function(r){
                    if (!r || !r.success) { $('#sf-robots-lint').html('<span style="color:#d63638;">' + <?php echo wp_json_encode( __( 'Could not generate preview.', 'seo-fury' ) ); ?> + '</span>'); return; }
                    $('#sf-robots-preview').text(r.data.content).show();
                    var w = r.data.warnings || [];
                    if (!w.length) {
                        $('#sf-robots-lint').html('<div style="color:#00a32a;">✅ ' + <?php echo wp_json_encode( __( 'No problems detected.', 'seo-fury' ) ); ?> + '</div>');
                    } else {
                        var html = '';
                        w.forEach(function(item){
                            var c = colors[item.type] || '#555';
                            html += '<div style="color:' + c + ';margin:2px 0;">' + (icons[item.type] || '') + ' ' + $('<span>').text(item.msg).html() + '</div>';
                        });
                        $('#sf-robots-lint').html(html);
                    }
                }).always(function(){ btn.prop('disabled', false).text(orig); });
            });
        })(jQuery);
        </script>
        <?php
    }

    public function robots_user_agents_callback() {
        $ua_rules = get_option('seo_fury_robots_user_agents', '');
        if (is_array($ua_rules)) {
            $ua_rules = implode("\n", $ua_rules);
        }
        $presets = $this->get_preset_rules();
        ?>
        <textarea name="seo_fury_robots_user_agents" id="seo-robots-ua-rules" rows="10" cols="80" class="large-text code" style="font-family: monospace; width: 100%;"><?php echo esc_textarea($ua_rules); ?></textarea>

        <div style="margin-top: 10px;">
            <strong style="display: block; margin-bottom: 8px;"><?php esc_html_e('Quick add rules:', 'seo-fury'); ?></strong>
            <div style="display: flex; flex-wrap: wrap; gap: 6px;">
                <?php foreach ($presets as $key => $preset) : ?>
                    <button type="button" class="button seo-robots-preset-btn"
                            data-rules="<?php echo esc_attr($preset['rules']); ?>">
                        + <?php echo esc_html($preset['label']); ?>
                    </button>
                <?php endforeach; ?>
            </div>
        </div>

        <p class="description">
            <?php esc_html_e('Additional rule blocks for specific user agents. Click buttons above to quickly add preset rules.', 'seo-fury'); ?>
        </p>

        <script>
        jQuery(document).ready(function($) {
            $('.seo-robots-preset-btn').on('click', function() {
                var $textarea = $('#seo-robots-ua-rules');
                var rules = $(this).data('rules');
                var current = $textarea.val().trim();
                if (current.length > 0) {
                    $textarea.val(current + '\n\n' + rules);
                } else {
                    $textarea.val(rules);
                }
                // Scroll textarea to bottom
                $textarea[0].scrollTop = $textarea[0].scrollHeight;
            });
        });
        </script>
        <?php
    }

    public function robots_crawl_delay_callback() {
        $crawl_delay = get_option('seo_fury_robots_crawl_delay', '');
        ?>
        <div class="seo-alert info" style="margin: 0 0 12px;">
            <p style="margin: 0 0 6px;"><strong><?php esc_html_e('What is Crawl-delay?', 'seo-fury'); ?></strong></p>
            <p style="margin: 0 0 6px;">
                <?php
                printf(
                    /* translators: %s: Crawl-delay directive name */
                    esc_html__('%s tells search engine bots how many seconds to wait between requests to your site. Useful when aggressive crawling overloads the server (slow hosting, high traffic, large catalogs).', 'seo-fury'),
                    '<code>Crawl-delay</code>'
                );
                ?>
            </p>
            <p style="margin: 0 0 6px;">
                <strong><?php esc_html_e('Who respects it:', 'seo-fury'); ?></strong>
                <?php esc_html_e('Bing, Yandex, Baidu, DuckDuckBot — supported.', 'seo-fury'); ?>
                <strong><?php esc_html_e('Googlebot — ignores', 'seo-fury'); ?></strong>
                <?php
                printf(
                    /* translators: %s: Google Search Console name */
                    esc_html__('this directive; set the crawl rate in %s instead.', 'seo-fury'),
                    'Google Search Console'
                );
                ?>
            </p>
            <p style="margin: 0;">
                <strong><?php esc_html_e('When to leave empty:', 'seo-fury'); ?></strong>
                <?php esc_html_e('In most cases this field should be empty — modern servers handle bot traffic fine, and adding delays slows down indexing.', 'seo-fury'); ?>
            </p>
        </div>
        <textarea name="seo_fury_robots_crawl_delay" rows="5" cols="80" class="large-text code" style="font-family: monospace; width: 100%;"><?php echo esc_textarea($crawl_delay); ?></textarea>
        <p class="description">
            <?php
            printf(
                /* translators: %s: code example of format */
                esc_html__('Format: one line = %s, for example:', 'seo-fury'),
                '<code>User-agent:Name = seconds</code>'
            );
            ?><br>
            <code>Googlebot=2</code><br>
            <code>Yandex=5</code><br>
            <?php
            printf(
                /* translators: %s: Crawl-delay directive name */
                esc_html__('Converted to %s directives for the listed bots.', 'seo-fury'),
                '<code>Crawl-delay</code>'
            );
            ?>
        </p>
        <?php
    }

    public function robots_use_dynamic_vars_callback() {
        $use_vars = get_option('seo_fury_robots_use_dynamic_vars', 1);
        ?>
        <label>
            <input type="checkbox" name="seo_fury_robots_use_dynamic_vars" value="1" <?php checked($use_vars, 1); ?> />
            <?php esc_html_e('Automatically replace', 'seo-fury'); ?> <code>{site_url}</code>, <code>{home_url}</code>, <code>{uploads_path}</code>
        </label>
        <?php
    }

    public function robots_block_ai_bots_callback() {
        $block_ai = get_option('seo_fury_robots_block_ai_bots', 0);
        $core = SEO_Fury_Core::get_instance();
        $pro = $core->get_pro_features();
        $is_pro = $pro->is_pro();
        $should_hide = function_exists('seo_fury_hide_branding') ? seo_fury_hide_branding() : false;

        $granular = get_option('seo_fury_robots_ai_bots_granular', array());

        $ai_bots = array(
            'GPTBot'          => __('GPTBot (OpenAI training)', 'seo-fury'),
            'ChatGPT-User'    => __('ChatGPT-User (ChatGPT browsing)', 'seo-fury'),
            'Google-Extended' => __('Google-Extended (Gemini/Bard)', 'seo-fury'),
            'ClaudeBot'       => __('ClaudeBot (Anthropic training)', 'seo-fury'),
            'Claude-Web'      => __('Claude-Web (Anthropic browsing)', 'seo-fury'),
            'Omgilibot'       => __('Omgilibot (Omgili)', 'seo-fury'),
            'FacebookBot'     => __('FacebookBot (Meta AI)', 'seo-fury'),
            'Bytespider'      => __('Bytespider (TikTok/ByteDance)', 'seo-fury'),
            'PerplexityBot'   => __('PerplexityBot (Perplexity AI)', 'seo-fury'),
            'Applebot-Extended' => __('Applebot-Extended (Apple AI)', 'seo-fury'),
            'cohere-ai'       => __('cohere-ai (Cohere)', 'seo-fury'),
            'Diffbot'         => __('Diffbot', 'seo-fury'),
        );
        ?>
        <div style="<?php echo esc_attr( !$is_pro ? 'opacity: 0.5;' : '' ); ?>">
            <label style="margin-bottom:10px;display:block;">
                <input type="checkbox" name="seo_fury_robots_block_ai_bots" value="1" <?php checked($block_ai, 1); ?> <?php echo esc_attr( !$is_pro ? 'disabled' : '' ); ?> id="seo-fury-block-ai-master" />
                <strong><?php esc_html_e('Block ALL AI crawlers', 'seo-fury'); ?></strong>
                <?php if (!$is_pro): ?>
                    <span style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 2px 8px; border-radius: 3px; font-size: 11px; font-weight: 600; margin-left: 8px;"><?php esc_html_e('PRO', 'seo-fury'); ?></span>
                <?php endif; ?>
            </label>

            <p class="description" style="margin-bottom:10px;">
                <?php esc_html_e('Or choose individual AI bots to block:', 'seo-fury'); ?>
            </p>

            <div style="display:grid;grid-template-columns:repeat(auto-fill, minmax(260px, 1fr));gap:6px 16px;padding:12px;background:var(--sf-gray-50, #f9f9f9);border:1px solid var(--sf-gray-200, #ddd);border-radius:6px;">
                <?php foreach ($ai_bots as $bot_ua => $bot_label): ?>
                    <label style="display:flex;align-items:center;gap:6px;font-size:13px;">
                        <input type="checkbox" name="seo_fury_robots_ai_bots_granular[]" value="<?php echo esc_attr($bot_ua); ?>"
                            <?php echo esc_attr( in_array($bot_ua, $granular, true) ? 'checked' : '' ); ?>
                            <?php echo esc_attr( !$is_pro ? 'disabled' : '' ); ?>
                            class="seo-fury-ai-bot-toggle" />
                        <?php echo esc_html($bot_label); ?>
                    </label>
                <?php endforeach; ?>
            </div>
        </div>
        <p class="description" style="margin-top:8px;">
            <?php esc_html_e('Master toggle blocks all AI bots. Individual toggles give you fine-grained control.', 'seo-fury'); ?>
            <?php if (!$is_pro && !$should_hide): ?>
                <br><strong style="color: #667eea;"><a href="https://seo-fury.com/#pricing" target="_blank"><?php esc_html_e('Upgrade to PRO', 'seo-fury'); ?></a> <?php esc_html_e('to unlock', 'seo-fury'); ?></strong>
            <?php endif; ?>
        </p>
        <?php
    }

    /**
     * Sanitize granular AI bots array.
     */
    public function sanitize_ai_bots_granular($input) {
        if (!is_array($input)) {
            return array();
        }
        return array_map('sanitize_text_field', $input);
    }

    public function robots_block_archive_bots_callback() {
        $block_archive = get_option('seo_fury_robots_block_archive_bots', 0);
        $core = SEO_Fury_Core::get_instance();
        $pro = $core->get_pro_features();
        $is_pro = $pro->is_pro();
        $should_hide = function_exists('seo_fury_hide_branding') ? seo_fury_hide_branding() : false;
        ?>
        <label style="<?php echo esc_attr( !$is_pro ? 'opacity: 0.5;' : '' ); ?>">
            <input type="checkbox" name="seo_fury_robots_block_archive_bots" value="1" <?php checked($block_archive, 1); ?> <?php echo esc_attr( !$is_pro ? 'disabled' : '' ); ?> />
            <?php esc_html_e('Block web archive bots (Wayback Machine, Archive.org, archive.is, and others)', 'seo-fury'); ?>
            <?php if (!$is_pro): ?>
                <span style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 2px 8px; border-radius: 3px; font-size: 11px; font-weight: 600; margin-left: 8px;"><?php esc_html_e('PRO', 'seo-fury'); ?></span>
            <?php endif; ?>
        </label>
        <p class="description">
            <?php esc_html_e('When enabled, web archive services cannot store copies of your site.', 'seo-fury'); ?>
            <?php esc_html_e('This helps protect unique content and prevents unauthorized archiving.', 'seo-fury'); ?>
            <?php if (!$is_pro && !$should_hide): ?>
                <br><strong style="color: #667eea;"><a href="https://seo-fury.com/#pricing" target="_blank"><?php esc_html_e('Upgrade to PRO', 'seo-fury'); ?></a> <?php esc_html_e('to unlock', 'seo-fury'); ?></strong>
            <?php endif; ?>
        </p>
        <?php
    }

    public function robots_reset_callback() {
        ?>
        <button type="button" id="seo-reset-robots" class="button button-secondary">
            <?php esc_html_e('Reset to defaults', 'seo-fury'); ?>
        </button>
        <span id="seo-reset-robots-status" style="margin-left: 10px;"></span>
        <p class="description">
            <?php esc_html_e('Restores robots.txt to default values.', 'seo-fury'); ?>
            <?php esc_html_e('All custom changes will be lost.', 'seo-fury'); ?>
        </p>
        <script>
        jQuery(document).ready(function($) {
            $('#seo-reset-robots').on('click', function() {
                if (!confirm('<?php echo esc_js(__('Are you sure? All robots.txt settings will be reset.', 'seo-fury')); ?>')) {
                    return;
                }
                var $btn = $(this);
                var $status = $('#seo-reset-robots-status');
                $btn.prop('disabled', true);
                $status.html('<span style="color: orange;"><?php echo esc_js(__('Resetting...', 'seo-fury')); ?></span>');
                $.ajax({
                    url: ajaxurl,
                    type: 'POST',
                    data: {
                        action: 'seo_reset_robots',
                        _ajax_nonce: '<?php echo esc_js( wp_create_nonce('seo_reset_robots_nonce') ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>'
                    },
                    success: function(response) {
                        if (response.success) {
                            $status.html('<span style="color: green;"><?php echo esc_js(__('Reset complete!', 'seo-fury')); ?></span>');
                            setTimeout(function() { location.reload(); }, 800);
                        } else {
                            $status.html('<span style="color: red;"><?php echo esc_js(__('Error:', 'seo-fury')); ?> ' + (response.data || '<?php echo esc_js(__('unknown', 'seo-fury')); ?>') + '</span>');
                            $btn.prop('disabled', false);
                        }
                    },
                    error: function() {
                        $status.html('<span style="color: red;"><?php echo esc_js(__('AJAX error', 'seo-fury')); ?></span>');
                        $btn.prop('disabled', false);
                    }
                });
            });
        });
        </script>
        <?php
    }

    public function robots_link_callback() {
        $robots_url = home_url('/robots.txt');
        ?>
        <a href="<?php echo esc_url($robots_url); ?>" target="_blank" style="font-size: 14px; font-weight: 600;">
            <?php echo esc_html($robots_url); ?>
        </a>
        <?php
    }

    public function ajax_reset_robots() {
        check_ajax_referer('seo_reset_robots_nonce', '_ajax_nonce');
        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('Insufficient permissions.', 'seo-fury'));
        }
        $default = $this->get_default_robots_template();
        update_option('seo_fury_robots_content', $default);
        update_option('seo_fury_robots_enabled', 1);
        update_option('seo_fury_robots_user_agents', '');
        update_option('seo_fury_robots_crawl_delay', '');
        update_option('seo_fury_robots_use_dynamic_vars', 1);
        update_option('seo_fury_robots_block_ai_bots', 0);
        update_option('seo_fury_robots_ai_bots_granular', array());
        update_option('seo_fury_robots_block_archive_bots', 0);
        wp_send_json_success(__('Settings reset.', 'seo-fury'));
    }

    /**
     * Delete the physical robots.txt file from the site root.
     */
    public function ajax_delete_physical_robots() {
        check_ajax_referer( 'seo_delete_physical_robots_nonce', '_ajax_nonce' );

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( __( 'Insufficient permissions.', 'seo-fury' ) );
        }

        $robots_path = ABSPATH . 'robots.txt';

        if ( ! file_exists( $robots_path ) ) {
            wp_send_json_success( __( 'File does not exist — already removed.', 'seo-fury' ) );
        }

        if ( ! is_writable( $robots_path ) ) { // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_is_writable
            wp_send_json_error( __( 'Cannot delete: file is not writable. Check file permissions.', 'seo-fury' ) );
        }

        if ( wp_delete_file( $robots_path ) || ! file_exists( $robots_path ) ) {
            wp_send_json_success( __( 'Physical robots.txt deleted. The virtual version is now active.', 'seo-fury' ) );
        }

        // wp_delete_file doesn't return a value in older WP, check manually.
        if ( ! file_exists( $robots_path ) ) {
            wp_send_json_success( __( 'Physical robots.txt deleted. The virtual version is now active.', 'seo-fury' ) );
        }

        wp_send_json_error( __( 'Failed to delete the file. Please remove it manually via FTP/SSH.', 'seo-fury' ) );
    }

    private function get_default_robots_template() {
        $template = 'User-agent: *' . "\n"
            . 'Disallow: /wp-admin/' . "\n"
            . 'Allow: /wp-admin/admin-ajax.php' . "\n"
            . 'Disallow: /wp-login.php' . "\n"
            . 'Disallow: /xmlrpc.php' . "\n"
            . 'Disallow: /trackback/' . "\n"
            . 'Disallow: /feed/' . "\n"
            . 'Disallow: /comments/' . "\n"
            . 'Disallow: /wp-json/' . "\n"
            . 'Disallow: /?rest_route=' . "\n"
            . 'Disallow: /?s=' . "\n"
            . 'Disallow: /*?replytocom=' . "\n"
            . 'Disallow: /*?attachment_id=' . "\n"
            . 'Disallow: /*/embed/' . "\n"
            . 'Disallow: /wp-includes/' . "\n"
            . 'Disallow: /cgi-bin/' . "\n"
            . 'Disallow: /wp-content/plugins/' . "\n"
            . 'Disallow: /wp-content/cache/' . "\n"
            . 'Disallow: /author/' . "\n"
            . 'Disallow: /tag/' . "\n"
            . 'Disallow: /*?p=' . "\n"
            . 'Disallow: /*&preview=true' . "\n"
            . 'Allow: /wp-content/uploads/' . "\n"
            . "\n"
            . 'User-agent: Googlebot' . "\n"
            . 'Disallow: /wp-admin/' . "\n"
            . 'Allow: /wp-admin/admin-ajax.php' . "\n"
            . 'Allow: /wp-content/uploads/' . "\n"
            . 'Allow: /wp-content/themes/' . "\n"
            . "\n"
            . 'User-agent: Yandex' . "\n"
            . 'Disallow: /wp-admin/' . "\n"
            . 'Allow: /wp-admin/admin-ajax.php' . "\n"
            . 'Disallow: /wp-includes/' . "\n"
            . 'Disallow: /cgi-bin/' . "\n"
            . 'Disallow: /wp-content/plugins/' . "\n"
            . 'Disallow: /wp-content/cache/' . "\n"
            . 'Disallow: /author/' . "\n"
            . 'Disallow: /*?replytocom=' . "\n"
            . 'Disallow: /*?p=' . "\n"
            . 'Allow: /wp-content/uploads/' . "\n"
            . 'Allow: /wp-content/themes/' . "\n"
            . 'Clean-param: utm_source&utm_medium&utm_campaign' . "\n"
            . "\n"
            . 'User-agent: Bingbot' . "\n"
            . 'Disallow: /wp-admin/' . "\n"
            . 'Allow: /wp-admin/admin-ajax.php' . "\n"
            . 'Allow: /wp-content/uploads/' . "\n"
            . 'Allow: /wp-content/themes/' . "\n"
            . 'Crawl-delay: 1';
        return $template;
    }

    private function get_preset_rules() {
        return array(
            'googlebot' => array(
                'label' => 'Googlebot',
                'rules' => "User-agent: Googlebot\nDisallow: /wp-admin/\nAllow: /wp-admin/admin-ajax.php\nAllow: /wp-content/uploads/\nAllow: /wp-content/themes/",
            ),
            'googlebot_image' => array(
                'label' => 'Googlebot-Image',
                'rules' => "User-agent: Googlebot-Image\nDisallow: /wp-includes/\nAllow: /wp-content/uploads/",
            ),
            'yandex' => array(
                'label' => 'Yandex',
                'rules' => "User-agent: Yandex\nDisallow: /wp-admin/\nAllow: /wp-admin/admin-ajax.php\nDisallow: /wp-includes/\nDisallow: /cgi-bin/\nDisallow: /wp-content/plugins/\nDisallow: /wp-content/cache/\nDisallow: /author/\nDisallow: /*?replytocom=\nAllow: /wp-content/uploads/\nAllow: /wp-content/themes/\nClean-param: utm_source&utm_medium&utm_campaign",
            ),
            'bingbot' => array(
                'label' => 'Bingbot',
                'rules' => "User-agent: Bingbot\nDisallow: /wp-admin/\nAllow: /wp-admin/admin-ajax.php\nAllow: /wp-content/uploads/\nCrawl-delay: 1",
            ),
            'baiduspider' => array(
                'label' => 'Baiduspider',
                'rules' => "User-agent: Baiduspider\nDisallow: /wp-admin/\nDisallow: /wp-includes/\nDisallow: /wp-content/plugins/\nCrawl-delay: 2",
            ),
            'duckduckbot' => array(
                'label' => 'DuckDuckBot',
                'rules' => "User-agent: DuckDuckBot\nDisallow: /wp-admin/\nAllow: /wp-admin/admin-ajax.php\nAllow: /wp-content/uploads/",
            ),
        );
    }

    private function apply_dynamic_vars($content) {
        $uploads = wp_upload_dir();
        $repl = array(
            '{site_url}'     => site_url('/'),
            '{home_url}'     => home_url('/'),
            '{uploads_path}' => isset($uploads['baseurl']) ? trailingslashit($uploads['baseurl']) : '',
        );
        return strtr($content, $repl);
    }

    private function build_crawl_delay_block() {
        $raw = get_option('seo_fury_robots_crawl_delay', '');
        if (empty($raw)) {
            return '';
        }
        $lines = explode("\n", $raw);
        $out = '';
        foreach ($lines as $line) {
            $line = trim($line);
            if (empty($line) || strpos($line, '=') === false) {
                continue;
            }
            list($agent, $delay) = array_map('trim', explode('=', $line, 2));
            // Constrain to safe values so a crafted option can't inject extra
            // robots directives: agent = UA token chars only, delay = a number.
            $agent = preg_replace('/[^A-Za-z0-9_\-\*\.]/', '', $agent);
            $delay = preg_replace('/[^0-9.]/', '', $delay);
            if ($agent === '' || $delay === '' || !is_numeric($delay)) {
                continue;
            }
            $out .= "User-agent: {$agent}\nCrawl-delay: {$delay}\n\n";
        }
        return $out;
    }

    private function build_ai_bots_block() {
        $block_all = get_option('seo_fury_robots_block_ai_bots', 0);
        $granular  = get_option('seo_fury_robots_ai_bots_granular', array());

        // Determine which bots to block
        $bots_to_block = array();

        if ($block_all) {
            // Master toggle: block all known AI bots
            $bots_to_block = array(
                'GPTBot', 'ChatGPT-User', 'Google-Extended', 'Omgilibot',
                'ClaudeBot', 'Claude-Web', 'FacebookBot', 'Bytespider',
                'PerplexityBot', 'Applebot-Extended', 'cohere-ai', 'Diffbot',
            );
        } elseif (!empty($granular) && is_array($granular)) {
            // Granular toggles
            $bots_to_block = $granular;
        }

        if (empty($bots_to_block)) {
            return '';
        }

        $out = "# Block AI bots\n";
        foreach ($bots_to_block as $bot) {
            $bot = sanitize_text_field($bot);
            $out .= "User-agent: {$bot}\nDisallow: /\n\n";
        }

        return $out;
    }

    private function build_archive_bots_block() {
        $block_archive = get_option('seo_fury_robots_block_archive_bots', 0);
        if (!$block_archive) {
            return '';
        }
        $core = SEO_Fury_Core::get_instance();
        $pro = $core->get_pro_features();
        if (!$pro->is_pro()) {
            return '';
        }
        $archive_block = '# Block web archive bots' . "\n"
            . 'User-agent: ia_archiver' . "\n"
            . 'Disallow: /' . "\n"
            . "\n"
            . 'User-agent: archive.org_bot' . "\n"
            . 'Disallow: /' . "\n"
            . "\n"
            . 'User-agent: Wayback' . "\n"
            . 'Disallow: /' . "\n"
            . "\n"
            . 'User-agent: archive-it' . "\n"
            . 'Disallow: /' . "\n"
            . "\n"
            . 'User-agent: ArchiveBot' . "\n"
            . 'Disallow: /' . "\n"
            . "\n"
            . 'User-agent: webcitation' . "\n"
            . 'Disallow: /' . "\n"
            . "\n"
            . 'User-agent: Archivarix' . "\n"
            . 'Disallow: /' . "\n"
            . "\n"
            . 'User-agent: Citoid' . "\n"
            . 'Disallow: /' . "\n";
        return $archive_block;
    }

    private function build_sitemaps_block() {
        $sitemap_enabled = get_option('seo_fury_sitemap_enabled', 1);
        if (!$sitemap_enabled) {
            return '';
        }
        $out = "\n# Sitemap\n";
        $xml_url = home_url('sitemap.xml');
        $out .= "Sitemap: {$xml_url}\n";

        // Добавляем ссылки на карты сайта таксономий
        $taxonomies = get_option('seo_fury_sitemap_taxonomies', array());
        if (is_array($taxonomies) && !empty($taxonomies)) {
            foreach ($taxonomies as $taxonomy) {
                $tax_obj = get_taxonomy($taxonomy);
                if (!$tax_obj) {
                    continue;
                }
                $tax_url = home_url("sitemap-tax-{$taxonomy}.xml");
                $out .= "Sitemap: {$tax_url}\n";
            }
        }

        // News sitemap
        if (get_option('seo_fury_sitemap_news_enabled', 0)) {
            $out .= "Sitemap: " . home_url('sitemap-news.xml') . "\n";
        }

        // Video sitemap
        if (get_option('seo_fury_sitemap_video_enabled', 0)) {
            $out .= "Sitemap: " . home_url('sitemap-videos.xml') . "\n";
        }

        return $out;
    }

    /**
     * Intercept /robots.txt requests when a physical file exists.
     *
     * When a physical robots.txt sits in ABSPATH, the web server (Apache / Nginx)
     * normally serves it directly and WordPress never processes the request.
     * However, some hosting setups route everything through index.php (e.g.
     * certain Nginx configs, LiteSpeed, or when .htaccess rewrite rules don't
     * exclude robots.txt). In those cases, WordPress IS reached but returns
     * the physical file instead of the virtual one.
     *
     * This method covers the "WordPress IS reached" scenario. For cases where
     * the web server serves the file directly, the admin panel shows a warning
     * and offers to delete or rename the physical file.
     */
    public function maybe_intercept_robots() {
        if ( is_admin() ) {
            return;
        }

        $enabled = get_option( 'seo_fury_robots_enabled', 1 );
        if ( ! $enabled ) {
            return;
        }

        // Only act on /robots.txt requests.
        $request_uri = isset( $_SERVER['REQUEST_URI'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
        $request_path = strtok( $request_uri, '?' );

        if ( '/robots.txt' !== $request_path ) {
            return;
        }

        // A physical file exists — we need to override it.
        if ( ! file_exists( ABSPATH . 'robots.txt' ) ) {
            // No physical file → WordPress will use the `robots_txt` filter
            // automatically via do_robots(). Nothing extra needed.
            return;
        }

        // Build our virtual robots.txt content (same logic as filter_robots_txt).
        $public = get_option( 'blog_public' );
        $output = $this->filter_robots_txt( '', $public );

        // Send it and stop execution so the physical file is never served.
        header( 'Content-Type: text/plain; charset=UTF-8' );
        header( 'X-Robots-Source: seo-fury-virtual' );
        status_header( 200 );
        echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- plain-text robots directives
        exit;
    }

    /**
     * Build the full virtual robots.txt exactly as it is served on the
     * front-end (template + dynamic vars + sitemaps + AI/archive blocks +
     * crawl-delay + custom UA rules). Used by both the front-end filter and the
     * admin preview.
     */
    public function compose_robots_txt() {
        $content = get_option('seo_fury_robots_content', '');
        if (empty($content)) {
            $content = $this->get_default_robots_template();
        }
        if (get_option('seo_fury_robots_use_dynamic_vars', 1)) {
            $content = $this->apply_dynamic_vars($content);
        }
        $content .= "\n" . $this->build_sitemaps_block();
        $ai_block = $this->build_ai_bots_block();
        if (!empty($ai_block)) {
            $content .= "\n" . $ai_block;
        }
        $archive_block = $this->build_archive_bots_block();
        if (!empty($archive_block)) {
            $content .= "\n" . $archive_block;
        }
        $content .= $this->build_crawl_delay_block();
        $ua_rules = get_option('seo_fury_robots_user_agents', array());
        if (is_array($ua_rules) && !empty($ua_rules)) {
            $content .= "\n" . implode("\n", $ua_rules) . "\n";
        } elseif (is_string($ua_rules) && !empty($ua_rules)) {
            $content .= "\n" . $ua_rules . "\n";
        }
        return trim($content) . "\n";
    }

    public function filter_robots_txt($output, $public) {
        if (is_admin()) {
            return $output;
        }
        if (!get_option('seo_fury_robots_enabled', 1)) {
            return $output;
        }
        return $this->compose_robots_txt();
    }

    /**
     * Static analysis of a robots.txt body. Returns an array of
     * {type:'error'|'warning'|'info', msg} entries.
     */
    public function lint_robots($content) {
        $warnings   = array();
        $lines      = preg_split('/\r\n|\n|\r/', (string) $content);
        $current_ua = null;
        $ua_seen    = array();
        $has_sitemap = false;
        $blocks_all  = false;

        foreach ($lines as $raw) {
            $line = trim($raw);
            if ($line === '' || strpos($line, '#') === 0) {
                continue;
            }
            if (preg_match('/^User-agent:\s*(.+)$/i', $line, $m)) {
                $current_ua = trim($m[1]);
                $key = strtolower($current_ua);
                $ua_seen[$key] = isset($ua_seen[$key]) ? $ua_seen[$key] + 1 : 1;
                continue;
            }
            if (preg_match('/^Sitemap:/i', $line)) {
                $has_sitemap = true;
                continue;
            }
            if (preg_match('/^(Disallow|Allow|Crawl-delay|Clean-param|Host):/i', $line)) {
                if ($current_ua === null) {
                    /* translators: %s: the offending directive line */
                    $warnings[] = array('type' => 'error', 'msg' => sprintf(__('Directive “%s” appears before any User-agent line and will be ignored.', 'seo-fury'), $line));
                }
                if ($current_ua === '*' && preg_match('/^Disallow:\s*\/\s*$/i', $line)) {
                    $blocks_all = true;
                }
                continue;
            }
        }

        foreach ($ua_seen as $ua => $count) {
            if ($count > 1) {
                /* translators: 1: user-agent token, 2: number of times it appears */
                $warnings[] = array('type' => 'warning', 'msg' => sprintf(__('User-agent “%1$s” is declared %2$d times — consider merging its rules into one block.', 'seo-fury'), $ua, $count));
            }
        }
        if ($blocks_all) {
            $warnings[] = array('type' => 'error', 'msg' => __('“Disallow: /” for User-agent: * blocks your ENTIRE site from search engines. Remove it unless that is intentional.', 'seo-fury'));
        }
        if (!$has_sitemap) {
            $warnings[] = array('type' => 'info', 'msg' => __('No Sitemap directive found — adding one helps search engines discover your content.', 'seo-fury'));
        }

        return $warnings;
    }

    /**
     * AJAX: return the composed robots.txt preview + lint warnings.
     */
    public function ajax_preview_robots() {
        check_ajax_referer('seo_fury_robots_preview', 'nonce');
        if (!current_user_can('manage_options')) {
            wp_send_json_error(array('message' => __('Insufficient permissions', 'seo-fury')));
        }
        $content = $this->compose_robots_txt();
        wp_send_json_success(array(
            'content'  => $content,
            'warnings' => $this->lint_robots($content),
        ));
    }
}
