<?php
/**
 * robots.txt editor — replaces WP's virtual robots.txt with our content
 * when the user enabled it.
 *
 * @package Brainwerk SEO Suite
 */

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

class Seoforge_Robots {

    /**
     * Known AI / LLM crawler user-agent tokens (Generative Engine Optimization).
     * token => human label. Used for the robots.txt allow/block UI.
     */
    public static function ai_bots() {
        return array(
            'GPTBot'              => 'OpenAI GPTBot (training)',
            'OAI-SearchBot'       => 'OpenAI SearchBot',
            'ChatGPT-User'        => 'ChatGPT (user browsing)',
            'ClaudeBot'           => 'Anthropic ClaudeBot (training)',
            'Claude-User'         => 'Claude (user browsing)',
            'Claude-SearchBot'    => 'Claude SearchBot',
            'anthropic-ai'        => 'Anthropic (legacy)',
            'PerplexityBot'       => 'PerplexityBot',
            'Perplexity-User'     => 'Perplexity (user browsing)',
            'Google-Extended'     => 'Google-Extended (Gemini training)',
            'Applebot-Extended'   => 'Applebot-Extended (Apple AI)',
            'Bytespider'          => 'Bytespider (ByteDance)',
            'CCBot'               => 'CCBot (Common Crawl)',
            'Amazonbot'           => 'Amazonbot',
            'Meta-ExternalAgent'  => 'Meta-ExternalAgent',
            'cohere-ai'           => 'cohere-ai',
            'Diffbot'             => 'Diffbot',
            'ImagesiftBot'        => 'ImagesiftBot',
            'YouBot'              => 'YouBot (You.com)',
        );
    }

    public static function register( Seoforge_Loader $loader ) {
        $loader->add_filter( 'robots_txt', __CLASS__, 'filter_robots', 20, 2 );
    }

    /**
     * Build the Disallow block for the AI crawlers the user opted to block.
     * Returns '' when none selected.
     */
    public static function ai_block_rules() {
        $blocked = (array) Seoforge_Settings::get( 'geo_blocked_ai_bots', array() );
        if ( empty( $blocked ) ) {
            return '';
        }
        $known = self::ai_bots();
        $lines = "\n# AI / LLM crawlers blocked via Brainwerk SEO Suite (GEO)\n";
        $any   = false;
        foreach ( $blocked as $token ) {
            if ( ! isset( $known[ $token ] ) ) {
                continue;
            }
            $lines .= 'User-agent: ' . $token . "\nDisallow: /\n";
            $any    = true;
        }
        return $any ? $lines : '';
    }

    public static function filter_robots( $output, $public ) {
        if ( ! $public ) {
            return $output;
        }
        $stand_down = Seoforge_Compat::should_stand_down();
        // Append our sitemap line, but only if no competitor is managing robots.
        if ( ! $stand_down && Seoforge_Settings::get( 'sitemap_enabled', true ) ) {
            $output .= "\nSitemap: " . home_url( '/seoforge-sitemap.xml' ) . "\n";
        }
        if ( Seoforge_Settings::get( 'robots_custom_enabled', false ) ) {
            $custom = (string) Seoforge_Settings::get( 'robots_custom_content', '' );
            if ( '' !== trim( $custom ) ) {
                $output = $custom;
                if ( false === strpos( $output, 'Sitemap:' ) && Seoforge_Settings::get( 'sitemap_enabled', true ) ) {
                    $output .= "\nSitemap: " . home_url( '/seoforge-sitemap.xml' ) . "\n";
                }
            }
        }
        // Append AI-crawler block rules (works for both default and custom robots).
        $output .= self::ai_block_rules();
        // Advertise the llms.txt manifest when enabled (a GEO convention).
        // Not gated on stand-down: llms.txt is unique to this plugin.
        if ( Seoforge_Settings::get( 'geo_llms_enabled', false ) ) {
            $output .= "\n# LLM-Content: " . home_url( '/llms.txt' ) . "\n";
        }
        return $output;
    }
}
