<?php

/**
 * Shop2LLM — AI Discovery for WooCommerce
 *
 * Make your WooCommerce store discoverable by AI assistants.
 * Free version supports ChatGPT, Google, Perplexity with product schema,
 * AI-friendly catalog, and crawler tracking.
 * Upgrade to Pro for 7 AI platforms, always-on AI connection, analytics
 * dashboard, search query insights, and conversion funnel.
 *
 * ---
 * Plugin Name: Shop2LLM
 * Description: Make your WooCommerce products discoverable by ChatGPT and AI assistants. Includes product schema, AI-friendly catalog, and crawler tracking.
 * Version:     1.0.3
 * Author:      FinCore
 * Author URI:  https://aiproductscout.shop/
 * License:     GPL-2.0+
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain: shop2llm
 * Domain Path: /languages
 * Requires PHP: 8.1
 * Requires at least: 6.0
 * Requires Plugins: woocommerce
 * WC requires at least: 8.0
 * WC tested up to: 10.8
 * ---
 */

declare(strict_types=1);

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

define('SHOP_TO_LLM_VERSION', '1.0.3');
define('SHOP_TO_LLM_DIR', plugin_dir_path(__FILE__));
define('SHOP_TO_LLM_URL', plugin_dir_url(__FILE__));

// ─── Lifecycle ─────────────────────────────────────────────────────────

register_activation_hook(__FILE__, 'shop_to_llm_activate');
register_deactivation_hook(__FILE__, 'shop_to_llm_deactivate');

// HPOS compatibility (required for WooCommerce Marketplace)
add_action('before_woocommerce_init', function() {
    if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) {
        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('custom_order_tables', __FILE__, true);
    }
});

function shop_to_llm_activate(): void
{
    if (!class_exists('WooCommerce')) {
        deactivate_plugins(plugin_basename(__FILE__));
        wp_die(
            wp_kses(
                sprintf(
                    /* translators: %s: URL to plugins page */
                    __('Shop2LLM requires WooCommerce to be installed and active. <a href="%s">Go back</a>', 'shop2llm'),
                    esc_url(admin_url('plugins.php'))
                ),
                ['a' => ['href' => []]]
            )
        );
    }

    add_option('shop_to_llm_enabled', 'yes');
    add_option('shop_to_llm_api_key', wp_generate_password(32, false));
    add_option('shop_to_llm_catalog_search', 'yes');
    add_option('shop_to_llm_analytics', 'no');
    flush_rewrite_rules();

    if (get_option('shop_to_llm_analytics', 'no') === 'yes') {
        wp_remote_post('https://api.aiproductscout.shop/fincore/v1/free/register', [
            'timeout' => 5,
            'blocking' => false,
            'headers' => ['Content-Type' => 'application/json'],
            'body' => json_encode([
                'site_url' => get_site_url(),
                'platform' => 'woocommerce',
                'plugin_version' => SHOP_TO_LLM_VERSION,
                'php_version' => PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION,
                'wc_version' => class_exists('WooCommerce') ? WC()->version : '',
                'wp_version' => get_bloginfo('version'),
                'site_name' => get_bloginfo('name'),
            ]),
        ]);
    }
}

function shop_to_llm_deactivate(): void
{
    flush_rewrite_rules();
}

// ─── REST API Routes ───────────────────────────────────────────────────

add_action('rest_api_init', 'shop_to_llm_register_routes');
add_action('parse_request', 'shop_to_llm_detect_ai_crawler', 1);

function shop_to_llm_register_routes(): void
{
    if (get_option('shop_to_llm_enabled', 'yes') !== 'yes') {
        return;
    }

    register_rest_route('shop2llm/v1', '/mcp', [
        'methods' => ['POST', 'GET'],
        'callback' => 'shop_to_llm_handle_mcp',
        'permission_callback' => 'shop_to_llm_check_auth',
    ]);

    register_rest_route('shop2llm/v1', '/.well-known/mcp', [
        'methods' => ['GET'],
        'callback' => 'shop_to_llm_mcp_discovery',
        'permission_callback' => '__return_true',
    ]);
}

// ─── Admin Page ────────────────────────────────────────────────────────

add_action('admin_menu', 'shop_to_llm_add_admin_page');
add_action('admin_enqueue_scripts', 'shop_to_llm_enqueue_admin_assets');
add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'shop_to_llm_add_action_links');
add_action('wp_head', 'shop_to_llm_inject_product_schema');
add_action('init', 'shop_to_llm_generate_llms_txt');
add_filter('query_vars', 'shop_to_llm_llms_txt_query_var');
add_action('template_redirect', 'shop_to_llm_render_llms_txt');
add_filter('robots_txt', 'shop_to_llm_robots_txt');

function shop_to_llm_add_admin_page(): void
{
    add_menu_page(
        'Shop2LLM',
        'Shop2LLM',
        'manage_options',
        'shop2llm',
        'shop_to_llm_render_settings',
        'data:image/svg+xml;base64,' . base64_encode('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M5.5 7C3.5 7 2 8.5 2 10s1.5 3 3.5 3c1.2 0 2-.5 3-1.5L10 10l1.5 1.5c1 1 1.8 1.5 3 1.5 2 0 3.5-1.5 3.5-3S16.5 7 14.5 7c-1.2 0-2 .5-3 1.5L10 10 8.5 8.5C7.5 7.5 6.7 7 5.5 7z"/></svg>'),
        56
    );
}

function shop_to_llm_enqueue_admin_assets(string $hook): void
{
    if ($hook !== 'toplevel_page_shop2llm') {
        return;
    }
    wp_enqueue_style(
        'shop2llm-admin',
        SHOP_TO_LLM_URL . 'assets/css/admin.css',
        [],
        SHOP_TO_LLM_VERSION
    );
    wp_enqueue_script(
        'shop2llm-admin',
        SHOP_TO_LLM_URL . 'assets/js/admin.js',
        [],
        SHOP_TO_LLM_VERSION,
        true
    );
}

function shop_to_llm_add_action_links(array $links): array
{
    $pro_link = '<a href="https://aiproductscout.shop/" target="_blank" style="color:#6366f1;font-weight:700;">⭐ ' . esc_html__('Upgrade to Pro', 'shop2llm') . '</a>';
    array_unshift($links, $pro_link);
    return $links;
}

function shop_to_llm_render_settings(): void
{
    if (!current_user_can('manage_options')) {
        wp_die(esc_html__('Unauthorized', 'shop2llm'));
    }

    if (isset($_POST['shop_to_llm_save'])) {
        check_admin_referer('shop_to_llm_settings');
        $enabled_post = sanitize_text_field(wp_unslash($_POST['shop_to_llm_enabled'] ?? 'yes'));
        $enabled = in_array($enabled_post, ['yes', 'no'], true) ? $enabled_post : 'yes';
        $catalog_post = sanitize_text_field(wp_unslash($_POST['shop_to_llm_catalog_search'] ?? 'yes'));
        $catalogSearch = in_array($catalog_post, ['yes', 'no'], true) ? $catalog_post : 'yes';
        $analytics_post = sanitize_text_field(wp_unslash($_POST['shop_to_llm_analytics'] ?? 'no'));
        $analytics = in_array($analytics_post, ['yes', 'no'], true) ? $analytics_post : 'no';
        $wasAnalyticsEnabled = get_option('shop_to_llm_analytics', 'no');
        update_option('shop_to_llm_enabled', $enabled);
        update_option('shop_to_llm_catalog_search', $catalogSearch);
        update_option('shop_to_llm_analytics', $analytics);
        if ($wasAnalyticsEnabled !== 'yes' && $analytics === 'yes') {
            wp_remote_post('https://api.aiproductscout.shop/fincore/v1/free/register', [
                'timeout' => 5,
                'blocking' => false,
                'headers' => ['Content-Type' => 'application/json'],
                'body' => json_encode([
                    'site_url' => get_site_url(),
                    'platform' => 'woocommerce',
                    'plugin_version' => SHOP_TO_LLM_VERSION,
                    'php_version' => PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION,
                    'wc_version' => class_exists('WooCommerce') ? WC()->version : '',
                    'wp_version' => get_bloginfo('version'),
                    'site_name' => get_bloginfo('name'),
                ]),
            ]);
        }
        echo '<div class="notice notice-success"><p>' . esc_html__('Settings saved.', 'shop2llm') . '</p></div>';
    }

    $enabled = get_option('shop_to_llm_enabled', 'yes');
    $apiKey = get_option('shop_to_llm_api_key', '');
    $catalogSearch = get_option('shop_to_llm_catalog_search', 'yes');
    $analytics = get_option('shop_to_llm_analytics', 'no');
    $storeName = get_bloginfo('name');
    $todayCount = shop_to_llm_get_today_api_count();
    $mcpEndpoint = rest_url('shop2llm/v1/mcp');

    ?>

    <div class="stl-wrap">
        <div class="stl-header">
            <div class="stl-logo">
                <span>∞</span>
            </div>
            <div>
                <h1>Shop2LLM</h1>
                <p style="font-size:13px;color:#64748b;margin:4px 0 0;line-height:1.4"><?php echo esc_html__('Get your products discovered by ChatGPT and AI-powered search engines.', 'shop2llm'); ?></p>
            </div>
        </div>

        <!-- Usage Card -->
        <?php
        $crawlerVisits = shop_to_llm_get_recent_crawlers();
        $crawlerCount = count($crawlerVisits);
        $uniqueCrawlers = array_unique(array_column($crawlerVisits, 'crawler'));
        ?>
        <div class="stl-card">
            <h2><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M12 20V10"/><path d="M18 20V4"/><path d="M6 20v-6"/></svg><?php echo esc_html__('Daily AI Visibility', 'shop2llm'); ?></h2>
            <div class="stl-row">
                <div class="stl-label"><?php echo esc_html__('API Calls Today', 'shop2llm'); ?></div>
                <div class="stl-value">
                    <strong style="font-size:20px;color:#166534">
                        <?php echo esc_html($todayCount); ?>
                    </strong>
                </div>
            </div>
            <div style="display:flex;gap:16px;flex-wrap:wrap;margin-top:12px">
                <div style="display:flex;align-items:center;gap:6px">
                    <span class="stl-badge stl-badge-ok" style="font-size:10px">✓</span>
                    <span style="font-size:11px;color:#475569"><?php echo esc_html__('AI-Ready Product Pages', 'shop2llm'); ?></span>
                </div>
                <div style="display:flex;align-items:center;gap:6px">
                    <span class="stl-badge stl-badge-ok" style="font-size:10px">✓</span>
                    <span style="font-size:11px;color:#475569"><?php echo esc_html__('AI Store Directory', 'shop2llm'); ?></span>
                </div>
                <div style="display:flex;align-items:center;gap:6px">
                    <span class="stl-badge stl-badge-ok" style="font-size:10px">✓</span>
                    <span style="font-size:11px;color:#475569"><?php echo esc_html__('12 AI Search Engines', 'shop2llm'); ?></span>
                </div>
                <div style="display:flex;align-items:center;gap:6px">
                    <span class="stl-badge <?php echo esc_attr($crawlerCount > 0 ? 'stl-badge-ok' : 'stl-badge-pro'); ?>" style="font-size:10px"><?php echo esc_html($crawlerCount); ?></span>
                    <span style="font-size:11px;color:#475569"><?php echo esc_html__('AI Bots Visited Today', 'shop2llm'); ?></span>
                </div>
            </div>
            <div style="margin-top:12px;padding:12px 14px;background:#f0f9ff;border:1px solid #bae6fd;border-radius:8px;font-size:12px;line-height:1.7;color:#0c4a6e">
                <strong style="display:block;margin-bottom:4px;color:#0369a1"><?php echo esc_html__('What does this mean for your store?', 'shop2llm'); ?></strong>
                <?php echo esc_html__('Each API call = your store was connected to an AI.', 'shop2llm'); ?><br>
                <?php echo esc_html__('Each crawler visit = an AI search engine indexed your products — making them discoverable by consumers.', 'shop2llm'); ?><br>
                <?php if ($todayCount > 0) : ?>
                    <?php echo esc_html__('Your store is active and visible to AI today.', 'shop2llm'); ?>
                <?php else : ?>
                    <?php echo esc_html__('Your store is ready — AI activity will appear here as it happens.', 'shop2llm'); ?>
                <?php endif; ?>
            </div>
        </div>

        <!-- Recent AI Searches -->
        <?php
        $recentSearches = shop_to_llm_get_recent_searches();
        $searchCount = count($recentSearches);
        ?>
        <div class="stl-card">
            <h2><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg><?php echo esc_html__('AI Search Activity', 'shop2llm'); ?></h2>
            <?php if ($searchCount === 0) : ?>
                <p style="color:#94a3b8;font-size:13px;margin:0;line-height:1.6">
                    <?php echo esc_html__('No AI searches today yet. When a consumer asks an AI (like ChatGPT) about your products, the search terms and matched products will appear here — so you can see what consumers are asking AI about your store.', 'shop2llm'); ?>
                </p>
            <?php else : ?>
                <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px">
                    <p style="color:#64748b;font-size:12px;margin:0"><?php /* translators: %d: number of searches */ echo sprintf(esc_html__('What consumers asked AI about your store today (%d searches):', 'shop2llm'), absint($searchCount)); ?></p>
                    <select id="stl-sort" style="font-size:12px;padding:3px 8px;border:1px solid #e2e8f0;border-radius:4px;background:#fff;color:#64748b">
                        <option value="time-desc"><?php echo esc_html__('Latest first', 'shop2llm'); ?></option>
                        <option value="time-asc"><?php echo esc_html__('Oldest first', 'shop2llm'); ?></option>
                        <option value="results-desc"><?php echo esc_html__('Most results', 'shop2llm'); ?></option>
                        <option value="results-asc"><?php echo esc_html__('Fewest results', 'shop2llm'); ?></option>
                    </select>
                </div>
                <table id="stl-search-table" style="width:100%;border-collapse:collapse;font-size:13px">
                    <thead>
                        <tr style="border-bottom:2px solid #e2e8f0">
                            <th style="text-align:left;padding:6px 8px;color:#64748b;font-weight:600"><?php echo esc_html__('Search Term', 'shop2llm'); ?></th>
                            <th style="text-align:left;padding:6px 8px;color:#64748b;font-weight:600"><?php echo esc_html__('Products Found', 'shop2llm'); ?></th>
                            <th style="text-align:center;padding:6px 8px;color:#64748b;font-weight:600"><?php echo esc_html__('Results', 'shop2llm'); ?></th>
                            <th style="text-align:right;padding:6px 8px;color:#64748b;font-weight:600"><?php echo esc_html__('Time', 'shop2llm'); ?></th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach (array_slice($recentSearches, 0, 15) as $i => $s) : ?>
                        <tr data-idx="<?php echo esc_attr($i); ?>" data-results="<?php echo esc_attr((int)$s['results']); ?>" data-time="<?php echo esc_attr($s['time']); ?>" style="border-bottom:1px solid #f1f5f9">
                            <td style="padding:6px 8px;color:#1e1e1e;font-weight:500"><?php echo esc_html($s['query']); ?></td>
                            <td style="padding:6px 8px;color:#475569;font-size:12px">
                                <?php
                                $prods = $s['products'] ?? [];
                                if (!empty($prods)) {
                                    echo esc_html(implode(', ', $prods));
                                } else {
                                    echo '<span style="color:#94a3b8">—</span>';
                                }
                                ?>
                            </td>
                            <td style="padding:6px 8px;text-align:center">
                                <?php if ($s['results'] > 0) : ?>
                                    <span style="color:#166534;font-weight:600"><?php /* translators: %d: number of found results */ echo sprintf(esc_html__('%d found', 'shop2llm'), (int)$s['results']); ?></span>
                                <?php else : ?>
                                    <span style="color:#991b1b;font-weight:600"><?php echo esc_html__('No match', 'shop2llm'); ?></span>
                                <?php endif; ?>
                            </td>
                            <td style="padding:6px 8px;text-align:right;color:#94a3b8"><?php echo esc_html($s['time']); ?></td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
                <?php if ($searchCount > 15) : ?>
                <p style="color:#94a3b8;font-size:12px;margin:8px 0 0"><?php /* translators: %d: number of searches */ echo sprintf(esc_html__('Showing latest 15 of %d searches. Upgrade to Pro for full search analytics.', 'shop2llm'), absint($searchCount)); ?></p>
                <?php endif; ?>
            <?php endif; ?>
            <?php if ($crawlerCount > 0) : ?>
            <div style="margin-top:16px;padding-top:14px;border-top:2px solid #e2e8f0">
                <p style="color:#64748b;font-size:12px;margin:0 0 8px"><?php /* translators: %1$d: number of visits, %2$d: number of platforms */ echo sprintf(esc_html__('AI crawler visits today (%1$d visits from %2$d platforms):', 'shop2llm'), absint($crawlerCount), absint(count($uniqueCrawlers))); ?></p>
                <table style="width:100%;border-collapse:collapse;font-size:13px">
                    <thead>
                        <tr style="border-bottom:2px solid #e2e8f0">
                            <th style="text-align:left;padding:6px 8px;color:#64748b;font-weight:600"><?php echo esc_html__('AI Platform', 'shop2llm'); ?></th>
                            <th style="text-align:right;padding:6px 8px;color:#64748b;font-weight:600"><?php echo esc_html__('Time', 'shop2llm'); ?></th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach (array_slice($crawlerVisits, 0, 10) as $v) : ?>
                        <tr style="border-bottom:1px solid #f1f5f9">
                            <td style="padding:6px 8px;color:#1e1e1e;font-weight:500"><?php echo esc_html($v['crawler']); ?></td>
                            <td style="padding:6px 8px;text-align:right;color:#94a3b8"><?php echo esc_html($v['time']); ?></td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
                <?php if ($crawlerCount > 10) : ?>
                <p style="color:#94a3b8;font-size:12px;margin:6px 0 0"><?php /* translators: %d: number of crawler visits */ echo sprintf(esc_html__('Showing latest 10 of %d visits.', 'shop2llm'), absint($crawlerCount)); ?></p>
                <?php endif; ?>
            </div>
            <?php endif; ?>
        </div>

        <!-- Status Card -->
        <div class="stl-card">
            <h2><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg><?php echo esc_html__('Connection Status', 'shop2llm'); ?></h2>
            <div class="stl-row">
                <div class="stl-label"><?php echo esc_html__('Store', 'shop2llm'); ?></div>
                <div class="stl-value"><?php echo esc_html($storeName); ?></div>
            </div>
            <div class="stl-row">
                <div class="stl-label"><?php echo esc_html__('Connection', 'shop2llm'); ?></div>
                <div class="stl-value">
                    <?php if ($enabled === 'yes') : ?>
                        <span class="stl-badge stl-badge-ok">
                            <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"><path d="M20 6 9 17l-5-5"/></svg>
                            <?php echo esc_html__('Connected', 'shop2llm'); ?>
                        </span>
                        <span style="color:#94a3b8;font-size:12px;margin-left:6px"><?php echo esc_html__('Self-hosted, zero latency', 'shop2llm'); ?></span>
                    <?php else : ?>
                        <span class="stl-badge stl-badge-off"><?php echo esc_html__('Disabled', 'shop2llm'); ?></span>
                    <?php endif; ?>
                </div>
            </div>
            <div class="stl-row">
                <div class="stl-label"><?php echo esc_html__('Tools Available', 'shop2llm'); ?></div>
                <div class="stl-value"><?php echo esc_html(shop_to_llm_tool_count()); ?></div>
            </div>
        </div>

        <!-- AI Connection Card -->
        <?php
        $configJson = json_encode([
            'mcpServers' => [
                'shop2llm' => [
                    'transport' => 'streamable-http',
                    'url' => $mcpEndpoint,
                    'headers' => ['Authorization' => 'Bearer ' . $apiKey],
                ],
            ],
        ], JSON_PRETTY_PRINT);
        ?>
        <div class="stl-card" id="stl-connection">
            <h2><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg><?php echo esc_html__('Test It Yourself', 'shop2llm'); ?></h2>
            <p style="color:#64748b;font-size:12px;margin:0 0 12px;line-height:1.5"><?php echo esc_html__('Paste this config into your ChatGPT to verify your store is AI-ready. This connects your ChatGPT to your store — a quick way to confirm everything works.', 'shop2llm'); ?></p>
            <div style="background:#fef3c7;border:1px solid #fcd34d;border-radius:6px;padding:10px 14px;margin-bottom:16px;font-size:12px;color:#92400e;line-height:1.5">
                <?php echo esc_html__('💡 Consumers can\'t search your store yet. This config only connects your own ChatGPT. For consumers to discover your products through ChatGPT, Claude, Gemini and more, you need the always-on cloud connection — available in Pro.', 'shop2llm'); ?>
            </div>
            <div style="position:relative;margin-bottom:14px">
                <pre id="stl-config" style="margin:0;padding:12px 14px;background:#1e1e1e;color:#e2e8f0;border-radius:6px;font-size:11px;line-height:1.6;overflow-x:auto;white-space:pre-wrap;word-break:break-all"><?php echo esc_html($configJson); ?></pre>
                <button type="button" class="stl-copy-btn" onclick="stlCopy('stl-config',this)" style="position:absolute;top:8px;right:8px"><?php echo esc_html__('Copy Config', 'shop2llm'); ?></button>
            </div>
            <p style="color:#64748b;font-size:12px;margin:0 0 12px;line-height:1.5"><?php echo esc_html__('Then: ChatGPT Desktop → Settings → Developer → Connect App → paste and save.', 'shop2llm'); ?></p>
            <div class="stl-row">
                <div class="stl-label"><?php echo esc_html__('API Key', 'shop2llm'); ?></div>
                <div class="stl-value" style="display:flex;align-items:center;gap:8px">
                    <code id="stl-apikey" class="stl-mono" style="max-width:280px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"><?php echo esc_html($apiKey); ?></code>
                    <button type="button" class="stl-copy-btn" onclick="stlCopy('stl-apikey',this)"><?php echo esc_html__('Copy', 'shop2llm'); ?></button>
                </div>
            </div>
            <div class="stl-row">
                <div class="stl-label"><?php echo esc_html__('AI Endpoint', 'shop2llm'); ?></div>
                <div class="stl-value" style="display:flex;align-items:center;gap:8px">
                    <code id="stl-endpoint" class="stl-mono" style="max-width:280px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"><?php echo esc_url($mcpEndpoint); ?></code>
                    <button type="button" class="stl-copy-btn" onclick="stlCopy('stl-endpoint',this)"><?php echo esc_html__('Copy', 'shop2llm'); ?></button>
                </div>
            </div>
        </div>

        <!-- Platform Card -->
        <div class="stl-card">
            <h2><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8"/><path d="M12 17v4"/></svg><?php echo esc_html__('AI Platforms', 'shop2llm'); ?></h2>
            <div class="stl-grid">
                <div class="stl-platform">
                    <svg viewBox="0 0 24 24" fill="none"><rect width="24" height="24" rx="6" fill="#10a37f"/><path d="M7 8h10M7 12h10M7 16h6" stroke="#fff" stroke-width="1.5" stroke-linecap="round"/></svg>
                    <span class="stl-pname">ChatGPT</span>
                    <span class="stl-badge stl-badge-ok" style="margin-left:auto"><?php echo esc_html__('Free', 'shop2llm'); ?></span>
                </div>
                <div class="stl-platform">
                    <svg viewBox="0 0 24 24" fill="none"><rect width="24" height="24" rx="6" fill="#d97706"/><path d="M8 7l4 5-4 5M13 7l4 5-4 5" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
                    <span class="stl-pname">Claude</span>
                    <span class="stl-badge stl-badge-pro" style="margin-left:auto"><?php echo esc_html__('Pro', 'shop2llm'); ?></span>
                </div>
                <div class="stl-platform">
                    <svg viewBox="0 0 24 24" fill="none"><rect width="24" height="24" rx="6" fill="#4285f4"/><path d="M12 7v10M7 12h10" stroke="#fff" stroke-width="2" stroke-linecap="round"/></svg>
                    <span class="stl-pname">Gemini</span>
                    <span class="stl-badge stl-badge-pro" style="margin-left:auto"><?php echo esc_html__('Pro', 'shop2llm'); ?></span>
                </div>
                <div class="stl-platform">
                    <svg viewBox="0 0 24 24" fill="none"><rect width="24" height="24" rx="6" fill="#7c3aed"/><path d="M8 12l3 3 5-6" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
                    <span class="stl-pname">Copilot</span>
                    <span class="stl-badge stl-badge-pro" style="margin-left:auto"><?php echo esc_html__('Pro', 'shop2llm'); ?></span>
                </div>
                <div class="stl-platform">
                    <svg viewBox="0 0 24 24" fill="none"><rect width="24" height="24" rx="6" fill="#1877f2"/><circle cx="12" cy="12" r="4" stroke="#fff" stroke-width="1.5"/><path d="M12 2v4M12 18v4M2 12h4M18 12h4" stroke="#fff" stroke-width="1.5" stroke-linecap="round"/></svg>
                    <span class="stl-pname">Meta AI</span>
                    <span class="stl-badge stl-badge-pro" style="margin-left:auto"><?php echo esc_html__('Pro', 'shop2llm'); ?></span>
                </div>
                <div class="stl-platform">
                    <svg viewBox="0 0 24 24" fill="none"><rect width="24" height="24" rx="6" fill="#ff9900"/><path d="M7 17l5-10 5 10M9 14h6" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
                    <span class="stl-pname">Bedrock</span>
                    <span class="stl-badge stl-badge-pro" style="margin-left:auto"><?php echo esc_html__('Pro', 'shop2llm'); ?></span>
                </div>
            </div>
        </div>

        <!-- Settings Card -->
        <div class="stl-card">
            <h2><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg><?php echo esc_html__('Settings', 'shop2llm'); ?></h2>
            <form method="post">
                <?php wp_nonce_field('shop_to_llm_settings'); ?>
                <table class="stl-form-table">
                    <tr>
                        <th><?php echo esc_html__('Enable', 'shop2llm'); ?></th>
                        <td>
                            <select name="shop_to_llm_enabled">
                                <option value="yes" <?php selected($enabled, 'yes'); ?>><?php echo esc_html__('Enabled — store is visible to AI agents', 'shop2llm'); ?></option>
                                <option value="no" <?php selected($enabled, 'no'); ?>><?php echo esc_html__('Disabled', 'shop2llm'); ?></option>
                            </select>
                        </td>
                    </tr>
                    <tr>
                        <th><?php echo esc_html__('Product Search', 'shop2llm'); ?></th>
                        <td>
                            <select name="shop_to_llm_catalog_search">
                                <option value="yes" <?php selected($catalogSearch, 'yes'); ?>><?php echo esc_html__('Enabled — AI can search your catalog', 'shop2llm'); ?></option>
                                <option value="no" <?php selected($catalogSearch, 'no'); ?>><?php echo esc_html__('Disabled', 'shop2llm'); ?></option>
                            </select>
                        </td>
                    </tr>
                    <tr>
                        <th><?php echo esc_html__('Analytics', 'shop2llm'); ?></th>
                        <td>
                            <select name="shop_to_llm_analytics">
                                <option value="no" <?php selected($analytics, 'no'); ?>><?php echo esc_html__('Disabled — no data sent', 'shop2llm'); ?></option>
                                <option value="yes" <?php selected($analytics, 'yes'); ?>><?php echo esc_html__('Enabled — share anonymized site metadata &amp; AI crawler visits for analytics', 'shop2llm'); ?></option>
                            </select>
                            <p style="color:#64748b;font-size:11px;margin:4px 0 0"><?php echo esc_html__('When enabled, basic site metadata and AI crawler visits are sent to our cloud service. No personal customer or order data is transmitted. Privacy Policy: https://aiproductscout.shop/privacy', 'shop2llm'); ?></p>
                        </td>
                    </tr>
                    <tr>
                        <th><?php echo esc_html__('Cart & Checkout', 'shop2llm'); ?></th>
                        <td>
                            <span class="stl-badge stl-badge-pro"><?php echo esc_html__('Pro', 'shop2llm'); ?></span>
                            <span style="color:#64748b;font-size:12px;margin-left:6px"><?php echo esc_html__('AI agents add to cart, checkout, and track orders', 'shop2llm'); ?></span>
                        </td>
                    </tr>
                </table>
                <?php submit_button(__('Save Settings', 'shop2llm'), 'primary', 'shop_to_llm_save'); ?>
            </form>
        </div>

        <!-- Pro CTA -->
        <div class="stl-cta">
            <div class="stl-cta-text">
                <h3><?php echo esc_html__('Upgrade to Shop2LLM Pro', 'shop2llm'); ?></h3>
                <p><?php echo esc_html__('5 AI tools, 6 platforms, unlimited calls, analytics dashboard — $9/mo', 'shop2llm'); ?></p>
            </div>
            <a href="https://api.aiproductscout.shop/fincore/v1/page/prolanding?site=<?php echo urlencode(get_site_url()); ?>" target="_blank" class="stl-cta-btn"><?php echo esc_html__('Upgrade to Pro →', 'shop2llm'); ?></a>
        </div>
    </div>

<?php }
function shop_to_llm_tool_count(): string
{
    return __('2 AI tools (search, product detail) — 5 total with Pro', 'shop2llm');
}

// ─── MCP JSON-RPC Handler ──────────────────────────────────────────────

function shop_to_llm_handle_mcp(\WP_REST_Request $request): \WP_REST_Response
{
    if (function_exists('WC') && WC()->session) {
        WC()->session->set('shop_to_llm_ai_session', true);
    }

    $key = 'shop_to_llm_count_' . gmdate('Y-m-d');
    set_transient($key, (int) get_transient($key) + 1, DAY_IN_SECONDS);

    $body = $request->get_json_params();
    if (!is_array($body)) {
        return new \WP_REST_Response([
            'jsonrpc' => '2.0', 'id' => null,
            'error' => ['code' => -32700, 'message' => 'Parse error'],
        ], 200);
    }
    $method = $body['method'] ?? '';
    $params = $body['params'] ?? [];

    $result = match ($method) {
        'tools/list' => shop_to_llm_tools_list(),
        'tools/call' => shop_to_llm_tools_call($params),
        'initialize' => [
            'protocolVersion' => '2025-11-25',
            'capabilities' => ['tools' => ['listChanged' => true]],
            'serverInfo' => ['name' => get_bloginfo('name') . ' — Shop2LLM', 'version' => SHOP_TO_LLM_VERSION],
        ],
        'prompts/list' => ['prompts' => []],
        default => null,
    };

    if ($result === null) {
        return new \WP_REST_Response([
            'jsonrpc' => '2.0', 'id' => $body['id'] ?? null,
            'error' => ['code' => -32601, 'message' => "Method not found: {$method}"],
        ], 200);
    }

    return new \WP_REST_Response([
        'jsonrpc' => '2.0', 'id' => $body['id'] ?? null, 'result' => $result,
    ], 200);
}

// ─── Tool Definitions ──────────────────────────────────────────────────

function shop_to_llm_tools_list(): array
{
    $tools = [
        [
            'name' => 'search_products',
            'description' => 'Search the ' . get_bloginfo('name') . ' product catalog. Returns matching products with prices, stock status, ratings, and purchase URLs.',
            'inputSchema' => [
                'type' => 'object',
                'properties' => [
                    'query' => ['type' => 'string', 'description' => 'Search keywords (e.g., "wireless headphones", "summer dress")'],
                    'category' => ['type' => 'string', 'description' => 'Filter by product category slug'],
                    'max_price' => ['type' => 'number', 'description' => 'Maximum price in store currency'],
                    'in_stock_only' => ['type' => 'boolean', 'default' => true, 'description' => 'Only show in-stock items'],
                    'limit' => ['type' => 'integer', 'default' => 10, 'maximum' => 50],
                ],
                'required' => ['query'],
            ],
            'idempotent' => true,
        ],
        [
            'name' => 'get_product',
            'description' => 'Get full details for a specific product including description, price, variants, and availability.',
            'inputSchema' => [
                'type' => 'object',
                'properties' => ['product_id' => ['type' => 'integer', 'description' => 'WooCommerce product ID']],
                'required' => ['product_id'],
            ],
            'idempotent' => true,
        ],
    ];

    return apply_filters('shop_to_llm_tools_list', ['tools' => $tools]);
}

function shop_to_llm_tools_call(array $params): array
{
    $name = $params['name'] ?? '';
    $args = $params['arguments'] ?? [];

    $result = match ($name) {
        'search_products' => shop_to_llm_search_products($args),
        'get_product' => shop_to_llm_get_product($args),
        default => ['error' => ['code' => 'TOOL_NOT_FOUND', 'message' => 'Tool not found: ' . $name]],
    };

    return apply_filters('shop_to_llm_tools_call', $result, $name, $args);
}

// ─── Tool Implementations ──────────────────────────────────────────────

function shop_to_llm_search_products(array $args): array
{
    $query = $args['query'] ?? '';
    $wcArgs = [
        'status' => 'publish',
        's' => $query,
        'limit' => min((int)($args['limit'] ?? 10), 50),
    ];

    if (!empty($args['category'])) {
        $wcArgs['category'] = [$args['category']];
    }
    if (!empty($args['max_price'])) {
        $wcArgs['max_price'] = (float)$args['max_price'];
    }
    if ($args['in_stock_only'] ?? true) {
        $wcArgs['stock_status'] = 'instock';
    }

    $products = wc_get_products($wcArgs);

    $results = array_map(function ($p) {
        return [
            'id' => $p->get_id(),
            'name' => $p->get_name(),
            'price' => $p->get_price(),
            'currency' => get_woocommerce_currency(),
            'in_stock' => $p->is_in_stock(),
            'rating' => (float)$p->get_average_rating(),
            'short_description' => wp_strip_all_tags($p->get_short_description()),
            'url' => $p->get_permalink(),
            'image_url' => wp_get_attachment_url($p->get_image_id()) ?: '',
        ];
    }, $products);

    if (!empty($query)) {
        $productNames = array_map(function ($p) {
            return $p->get_name();
        }, $products);
        shop_to_llm_log_search($query, count($results), $productNames);
    }

    return ['products' => $results];
}

function shop_to_llm_get_product(array $args): array
{
    $id = (int)($args['product_id'] ?? 0);
    if ($id <= 0) {
        return ['error' => ['code' => 'INVALID_ARGUMENT', 'message' => 'Valid product_id required']];
    }

    $product = wc_get_product($id);
    if (!$product || $product->get_status() !== 'publish') {
        return ['error' => ['code' => 'NOT_FOUND', 'message' => 'Product not found']];
    }

    return [
        'product' => [
            'id' => $product->get_id(),
            'name' => $product->get_name(),
            'description' => wp_strip_all_tags($product->get_description()),
            'short_description' => wp_strip_all_tags($product->get_short_description()),
            'price' => $product->get_price(),
            'regular_price' => $product->get_regular_price(),
            'sale_price' => $product->get_sale_price(),
            'currency' => get_woocommerce_currency(),
            'in_stock' => $product->is_in_stock(),
            'stock_quantity' => $product->get_stock_quantity(),
            'rating' => (float)$product->get_average_rating(),
            'review_count' => $product->get_review_count(),
            'categories' => wp_get_post_terms($id, 'product_cat', ['fields' => 'names']),
            'url' => $product->get_permalink(),
            'image_url' => wp_get_attachment_url($product->get_image_id()) ?: '',
        ],
    ];
}

function shop_to_llm_log_search(string $query, int $resultCount, array $productNames = []): void
{
    $key = 'shop_to_llm_searches_' . gmdate('Y-m-d');
    $searches = get_transient($key);
    if (!is_array($searches)) {
        $searches = [];
    }
    array_unshift($searches, [
        'query' => sanitize_text_field($query),
        'results' => $resultCount,
        'products' => array_slice(array_map('sanitize_text_field', $productNames), 0, 5),
        'time' => current_time('H:i'),
    ]);
    set_transient($key, array_slice($searches, 0, 50), DAY_IN_SECONDS);
}

function shop_to_llm_get_recent_searches(): array
{
    $key = 'shop_to_llm_searches_' . gmdate('Y-m-d');
    $searches = get_transient($key);
    return is_array($searches) ? $searches : [];
}

function shop_to_llm_log_crawler(string $crawlerType): void
{
    $key = 'shop_to_llm_crawlers_' . gmdate('Y-m-d');
    $crawlers = get_transient($key);
    if (!is_array($crawlers)) {
        $crawlers = [];
    }
    $label = [
        'oai-search' => 'ChatGPT Search', 'chatgpt-user' => 'ChatGPT User',
        'gptbot' => 'GPTBot', 'claude-bot' => 'ClaudeBot',
        'perplexity-bot' => 'Perplexity', 'google-extended' => 'Google AI',
        'bingbot' => 'Bing', 'meta-external' => 'Meta AI',
        'facebook-bot' => 'Facebook', 'amazonbot' => 'Amazon Bot',
        'bytespider' => 'ByteDance', 'applebot-extended' => 'Apple Bot',
    ];
    array_unshift($crawlers, [
        'crawler' => $label[$crawlerType] ?? $crawlerType,
        'time' => current_time('H:i'),
    ]);
    set_transient($key, array_slice($crawlers, 0, 50), DAY_IN_SECONDS);
}

function shop_to_llm_get_recent_crawlers(): array
{
    $key = 'shop_to_llm_crawlers_' . gmdate('Y-m-d');
    $crawlers = get_transient($key);
    return is_array($crawlers) ? $crawlers : [];
}

function shop_to_llm_get_today_api_count(): int
{
    $key = 'shop_to_llm_count_' . gmdate('Y-m-d');
    return (int) get_transient($key);
}

// ─── Discovery Endpoints ───────────────────────────────────────────────

function shop_to_llm_mcp_discovery(): \WP_REST_Response
{
    $cached = get_transient('shop_to_llm_mcp_discovery');
    if (is_array($cached)) {
        return new \WP_REST_Response($cached);
    }

    $data = [
        'mcp' => [
            'version' => '2025-11-25',
            'transport' => 'streamable-http',
            'endpoint' => rest_url('shop2llm/v1/mcp'),
            'capabilities' => ['tools' => ['listChanged' => true]],
        ],
        'registry' => [
            'name' => get_bloginfo('name') . ' via Shop2LLM',
            'description' => 'WooCommerce store connected to AI assistants',
        ],
        'server_info' => [
            'name' => get_bloginfo('name') . ' — Shop2LLM',
            'version' => SHOP_TO_LLM_VERSION,
        ],
    ];

    set_transient('shop_to_llm_mcp_discovery', $data, HOUR_IN_SECONDS);

    return new \WP_REST_Response($data);
}

// ─── Auth ──────────────────────────────────────────────────────────────

// Bypass WordPress REST auth for Shop2LLM routes.
// Priority 99999 ensures this runs after core auth checks.
add_filter('rest_authentication_errors', function ($result) {
    global $wp;
    $route = (isset($wp->query_vars) && is_array($wp->query_vars)) ? ($wp->query_vars['rest_route'] ?? '') : '';
    if ($route === '' && isset($_SERVER['REQUEST_URI'])) {
        $parsed = wp_parse_url(sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])), PHP_URL_PATH);
        $restPrefix = rest_get_url_prefix();
        if (is_string($parsed) && str_starts_with($parsed, '/' . $restPrefix . '/')) {
            $route = substr($parsed, strlen('/' . $restPrefix));
        }
    }
    if (str_starts_with($route, '/shop2llm/') || $route === '/shop2llm') {
        return true;
    }
    return $result;
}, 99999);

function shop_to_llm_check_auth(\WP_REST_Request $request): bool
{
    $storedKey = get_option('shop_to_llm_api_key', '');

    if ($storedKey === '') {
        return false;
    }

    $authHeader = $request->get_header('Authorization');
    if ($authHeader !== null && $authHeader !== '' && str_starts_with($authHeader, 'Bearer ')) {
        $token = substr($authHeader, 7);
        return hash_equals($storedKey, $token);
    }

    $apiKeyHeader = $request->get_header('X-Shop-To-LLm-Key');
    if ($apiKeyHeader !== null && $apiKeyHeader !== '') {
        if (hash_equals($storedKey, $apiKeyHeader)) {
            return true;
        }
        // Also accept Pro license key (used by cloud proxy)
        $proKey = get_option('shop_to_llm_pro_license_key', '');
        if ($proKey !== '' && hash_equals($proKey, $apiKeyHeader)) {
            return true;
        }
    }

    return false;
}

// ─── AI Crawler Detection ──────────────────────────────────────────────

function shop_to_llm_detect_ai_crawler(): void
{
    $ua = sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'] ?? ''));
    $crawlers = [
        'OAI-SearchBot' => 'oai-search',
        'ChatGPT-User' => 'chatgpt-user',
        'GPTBot' => 'gptbot',
        'ClaudeBot' => 'claude-bot',
        'PerplexityBot' => 'perplexity-bot',
        'Google-Extended' => 'google-extended',
        'bingbot' => 'bingbot',
        'Meta-ExternalAgent' => 'meta-external',
        'FacebookBot' => 'facebook-bot',
        'Amazonbot' => 'amazonbot',
        'Bytespider' => 'bytespider',
        'Applebot-Extended' => 'applebot-extended',
    ];
    foreach ($crawlers as $pattern => $type) {
        if (stripos($ua, $pattern) !== false) {
            shop_to_llm_report_crawler($type);
            break;
        }
    }
}

function shop_to_llm_report_crawler(string $crawlerType): void
{
    shop_to_llm_log_crawler($crawlerType);

    if (get_option('shop_to_llm_analytics', 'no') !== 'yes') {
        return;
    }

    $apiKey = get_option('shop_to_llm_api_key', '');
    $siteUrl = get_site_url();
    $requestUri = sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'] ?? ''));
    $ua = sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'] ?? ''));
    $result = wp_remote_post('https://api.aiproductscout.shop/fincore/v1/crawler/log', [
        'timeout' => 3,
        'blocking' => true,
        'headers' => ['Content-Type' => 'application/json'],
        'body' => json_encode([
            'license_key' => 'free_' . md5($siteUrl . $apiKey),
            'crawler_type' => $crawlerType,
            'page_url' => $siteUrl . $requestUri,
            'user_agent' => substr($ua, 0, 500),
            'response_code' => http_response_code() ?: 200,
        ]),
    ]);
    if (is_wp_error($result)) {
        error_log('[Shop2LLM] Crawler report failed: ' . $result->get_error_message());
    }
}

// ─── Product Schema (JSON-LD) ──────────────────────────────────────────

function shop_to_llm_inject_product_schema(): void
{
    if (!is_product()) {
        return;
    }
    // Skip if a known SEO plugin is active to avoid duplicate schema
    static $has_seo_plugin = null;
    if ($has_seo_plugin === null) {
        $active = apply_filters('active_plugins', get_option('active_plugins', []));
        $seo_slugs = ['wordpress-seo/wp-seo.php', 'seo-by-rank-math/rank-math.php', 'all-in-one-seo-pack/all_in_one_seo_pack.php', 'wp-seopress/seopress.php'];
        $has_seo_plugin = (bool) array_intersect($seo_slugs, $active);
    }
    if ($has_seo_plugin) {
        return;
    }
    global $product;
    if (!$product instanceof WC_Product) {
        return;
    }
    $schema = [
        '@context' => 'https://schema.org',
        '@type' => 'Product',
        'name' => $product->get_name(),
        'description' => wp_strip_all_tags($product->get_short_description() ?: $product->get_description()),
        'image' => wp_get_attachment_url($product->get_image_id()),
        'sku' => $product->get_sku(),
        'offers' => [
            '@type' => 'Offer',
            'url' => get_permalink($product->get_id()),
            'priceCurrency' => get_woocommerce_currency(),
            'price' => $product->get_price(),
            'availability' => $product->is_in_stock()
                ? 'https://schema.org/InStock'
                : 'https://schema.org/OutOfStock',
            'seller' => [
                '@type' => 'Organization',
                'name' => get_bloginfo('name'),
            ],
        ],
    ];
    if ($product->get_average_rating() > 0) {
        $schema['aggregateRating'] = [
            '@type' => 'AggregateRating',
            'ratingValue' => $product->get_average_rating(),
            'reviewCount' => $product->get_review_count(),
        ];
    }
    echo '<script type="application/ld+json">' . wp_json_encode($schema) . '</script>' . "\n";
}

// ─── llms.txt Generation ───────────────────────────────────────────────

function shop_to_llm_generate_llms_txt(): void
{
    add_rewrite_rule('^llms\.txt$', 'index.php?shop_to_llm_llms_txt=1', 'top');
}

function shop_to_llm_llms_txt_query_var(array $vars): array
{
    $vars[] = 'shop_to_llm_llms_txt';
    return $vars;
}

function shop_to_llm_render_llms_txt(): void
{
    if (!get_query_var('shop_to_llm_llms_txt')) {
        return;
    }
    $siteName = get_bloginfo('name');
    $siteUrl = get_site_url();
    $desc = get_bloginfo('description');
    $output = "# {$siteName}\n\n";
    $output .= "> {$desc}\n\n";
    $output .= "This store is connected to AI assistants via Shop2LLM.\n\n";
    $output .= "## Products\n\n";
    $products = wc_get_products(['limit' => 100, 'status' => 'publish', 'orderby' => 'popularity']);
    foreach ($products as $product) {
        $price = wp_strip_all_tags($product->get_price_html());
        $stock = $product->is_in_stock() ? 'In Stock' : 'Out of Stock';
        $url = get_permalink($product->get_id());
        $output .= '- [' . esc_html($product->get_name()) . '](' . esc_url($url) . '): ' . esc_html($price) . ' — ' . esc_html($stock) . "\n";
    }
    $total = wp_count_posts('product')->publish ?? 0;
    if ($total > 100) {
        $output .= "\n... and " . ($total - 100) . " more products. Full catalog at " . esc_url($siteUrl . '/shop/') . "\n";
    }
    $output .= "\n## AI Access\n\n";
    $output .= "- MCP Endpoint: " . esc_url($siteUrl . '/wp-json/shop2llm/v1/mcp') . "\n";
    $output .= "- AI Discovery: " . esc_url($siteUrl . '/wp-json/shop2llm/v1/.well-known/mcp') . "\n";
    $output .= "- Product Feed (XML): " . esc_url($siteUrl . '/product-feed.xml') . "\n";
    $output .= "- Product Feed (URL): " . esc_url($siteUrl . '/products.xml') . "\n";
    header('Content-Type: text/plain; charset=UTF-8');
    // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- plain text, all variables pre-escaped
    echo $output;
    exit;
}

// ─── robots.txt Optimization ───────────────────────────────────────────

function shop_to_llm_robots_txt(string $output): string
{
    $lines = [
        'User-agent: OAI-SearchBot', 'Allow: /', '',
        'User-agent: ChatGPT-User', 'Allow: /', '',
        'User-agent: GPTBot', 'Allow: /', '',
        'User-agent: ClaudeBot', 'Allow: /', '',
        'User-agent: PerplexityBot', 'Allow: /', '',
        'User-agent: Google-Extended', 'Allow: /', '',
        'User-agent: bingbot', 'Allow: /', '',
        'User-agent: Meta-ExternalAgent', 'Allow: /', '',
        'User-agent: FacebookBot', 'Allow: /', '',
        'User-agent: Amazonbot', 'Allow: /', '',
        'User-agent: Bytespider', 'Allow: /', '',
        'User-agent: Applebot-Extended', 'Allow: /', '',
    ];
    $custom = implode("\n", $lines) . "\n";
    return $custom . $output;
}

// ─── AI Product Feed (Bing/ChatGPT/Google/Perplexity) ───────────────────

function shop_to_llm_product_feed_xml(): void
{
    $products = wc_get_products(['limit' => 100, 'status' => 'publish', 'orderby' => 'date']);
    $storeUrl = get_site_url();
    $storeName = get_bloginfo('name');

    header('Content-Type: application/xml; charset=utf-8');
    echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
    echo '<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">' . "\n";
    echo '<channel>' . "\n";
    echo '<title>' . esc_xml($storeName) . '</title>' . "\n";
    echo '<link>' . esc_xml($storeUrl) . '</link>' . "\n";
    echo '<description>' . esc_xml(__('Shop2LLM product feed for ChatGPT, Bing Copilot, Google AI Overview, and Perplexity', 'shop2llm')) . '</description>' . "\n";

    foreach ($products as $p) {
        $pid = $p->get_id();
        $title = esc_xml(wp_strip_all_tags($p->get_name()));
        $desc = esc_xml(wp_strip_all_tags($p->get_short_description() ?: $p->get_description()));
        $link = esc_url(get_permalink($pid));
        $imgId = $p->get_image_id();
        $imgUrl = $imgId ? esc_url(wp_get_attachment_url($imgId)) : '';
        $price = $p->get_price();
        $currency = get_woocommerce_currency();
        $avail = esc_xml($p->is_in_stock() ? 'in stock' : 'out of stock');
        $sku = esc_xml($p->get_sku() ?: 'WC-' . $pid);
        $brand = esc_xml($storeName);
        $gtin = esc_xml($p->get_meta('_gtin') ?: $p->get_meta('_barcode') ?: '');

        echo '<item>' . "\n";
        echo '<g:id>' . $sku . '</g:id>' . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $sku already escaped via esc_xml()
        echo '<title>' . $title . '</title>' . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $title already escaped via esc_xml()
        echo '<description>' . ($desc ?: $title) . '</description>' . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $desc/$title already escaped via esc_xml()
        echo '<link>' . $link . '</link>' . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $link already escaped via esc_url()
        if ($imgUrl) {
            echo '<g:image_link>' . $imgUrl . '</g:image_link>' . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $imgUrl already escaped via esc_url()
        }
        if ($price) {
            echo '<g:price>' . esc_xml($price . ' ' . $currency) . '</g:price>' . "\n";
        }
        echo '<g:availability>' . $avail . '</g:availability>' . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $avail already escaped via esc_xml()
        if ($brand) {
            echo '<g:brand>' . $brand . '</g:brand>' . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $brand already escaped via esc_xml()
        }
        if ($gtin) {
            echo '<g:gtin>' . $gtin . '</g:gtin>' . "\n"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $gtin already escaped via esc_xml()
        }
        echo '<g:condition>new</g:condition>' . "\n";
        echo '</item>' . "\n";
    }

    echo '</channel>' . "\n";
    echo '</rss>' . "\n";
    exit;
}

function shop_to_llm_register_feed_rewrite(): void
{
    add_rewrite_rule('^product-feed\.xml$', 'index.php?shop_to_llm_feed=1', 'top');
    add_rewrite_rule('^products\.xml$', 'index.php?shop_to_llm_feed=1', 'top');
}
add_action('init', 'shop_to_llm_register_feed_rewrite');

add_filter('query_vars', function (array $vars): array {
    $vars[] = 'shop_to_llm_feed';
    return $vars;
});

add_action('template_redirect', function () {
    if (get_query_var('shop_to_llm_feed')) {
        shop_to_llm_product_feed_xml();
    }
});
