<?php
/**
 * Forge Suite — contextual, dismissible "Pro spotlight" reminder.
 *
 * A single calm, helpful card that highlights ONE Pro feature on the plugin's
 * own dashboard page (never site-wide). Free users only. Dismissible per-user
 * (stays hidden for 30 days, then gently returns — not a persistent paywall).
 * The CTA is tagged data-forge-cta="go_pro" so opt-in telemetry can count it.
 *
 * WordPress.org compliance: in-page (plugin dashboard only), dismissible,
 * never blocks functionality, copy never implies the Free plugin is crippled.
 *
 * Shared across the 4 wave-1 plugins with a class_exists guard — edit one
 * copy, copy to all (forge-check-shared verifies parity).
 *
 * @package Forge
 */

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

if (!class_exists('Forge_Pro_Tip')) {

class Forge_Pro_Tip {

    const META_KEY    = 'forge_pro_tip_dismissed_until'; // per-user, per-plugin (suffix)
    const SNOOZE_DAYS = 30;

    /** plugin slug => [main dashboard page slug, License class, accent, features] */
    private static function registry(): array {
        return [
            'rankforge' => [
                'page'   => 'rankforge',
                'license'=> 'RANKFORGE_License',
                'accent' => '#FF6B35',
                'features' => [
                    ['key' => 'ai_meta',      'title' => __('AI meta titles & descriptions', 'rankforge'), 'body' => __('Generate optimized titles and meta descriptions for any post in one click.', 'rankforge')],
                    ['key' => 'site_audit',   'title' => __('Full Site Audit', 'rankforge'),               'body' => __('Crawl your whole site for SEO issues and get a prioritized fix list.', 'rankforge')],
                    ['key' => 'gsc',          'title' => __('Search Console rankings', 'rankforge'),        'body' => __('Track real keyword positions and clicks right inside the dashboard.', 'rankforge')],
                    ['key' => 'optimizer',    'title' => __('Content Optimizer', 'rankforge'),              'body' => __('Score a draft against your target keyword and get concrete suggestions.', 'rankforge')],
                ],
            ],
            'langforge' => [
                'page'   => 'langforge-settings',
                'license'=> 'LANGFORGE_License',
                'accent' => '#0EC49E',
                'features' => [
                    ['key' => 'ai_translation', 'title' => __('AI translation', 'rankforge'),       'body' => __('Translate posts, pages and strings automatically with a single click.', 'rankforge')],
                    ['key' => 'visual_editor',  'title' => __('Visual Editor', 'rankforge'),        'body' => __('Translate content side-by-side on a live preview of your page.', 'rankforge')],
                    ['key' => 'glossary',       'title' => __('Glossary', 'rankforge'),             'body' => __('Keep brand terms consistent across every language you publish.', 'rankforge')],
                    ['key' => 'tm',             'title' => __('Translation Memory', 'rankforge'),   'body' => __('Reuse past translations to stay consistent and save on AI usage.', 'rankforge')],
                ],
            ],
            'formforge' => [
                'page'   => 'formforge',
                'license'=> 'FORMFORGE_License',
                'accent' => '#3B82F6',
                'features' => [
                    ['key' => 'ai_form',     'title' => __('AI form generation', 'rankforge'),     'body' => __('Describe the form you want and let AI build the fields for you.', 'rankforge')],
                    ['key' => 'stripe',      'title' => __('Stripe payments', 'rankforge'),        'body' => __('Collect payments and donations directly through your forms.', 'rankforge')],
                    ['key' => 'conversational','title' => __('Conversational mode', 'rankforge'),  'body' => __('Turn any form into a friendly one-question-at-a-time experience.', 'rankforge')],
                    ['key' => 'ai_analysis', 'title' => __('AI submission analysis', 'rankforge'),  'body' => __('Summarize and surface trends across your form submissions.', 'rankforge')],
                ],
            ],
            'fieldforge' => [
                'page'   => 'fieldforge',
                'license'=> 'FIELDFORGE_License',
                'accent' => '#F43F5E',
                'features' => [
                    ['key' => 'repeater',    'title' => __('Repeater & Flexible Content', 'rankforge'), 'body' => __('Build unlimited repeating rows and flexible layout blocks.', 'rankforge')],
                    ['key' => 'options',     'title' => __('Options Pages', 'rankforge'),               'body' => __('Add global fields for headers, footers and site-wide settings.', 'rankforge')],
                    ['key' => 'graphql',     'title' => __('GraphQL & REST exposure', 'rankforge'),     'body' => __('Expose your custom fields to headless and REST/GraphQL clients.', 'rankforge')],
                    ['key' => 'calculation', 'title' => __('Calculation fields', 'rankforge'),          'body' => __('Compute totals from other fields and sum values across posts.', 'rankforge')],
                ],
            ],
        ];
    }

    public static function init() {
        add_action('admin_notices',                   [__CLASS__, 'maybe_render']);
        add_action('admin_enqueue_scripts',           [__CLASS__, 'enqueue']);
        add_action('wp_ajax_forge_pro_tip_dismiss',   [__CLASS__, 'ajax_dismiss']);
    }

    /** Which plugin's dashboard are we on (if any, and only when Free)? */
    private static function current(): ?array {
        if (!is_admin() || !current_user_can('manage_options')) return null;
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- reading which admin screen is being rendered; no form data is processed and nothing is mutated.
        $page = isset($_GET['page']) ? sanitize_key(wp_unslash($_GET['page'])) : '';
        if ($page === '') return null;
        foreach (self::registry() as $slug => $cfg) {
            if ($cfg['page'] !== $page) continue;
            // Only on a Free install — never upsell a paying customer.
            if (self::license_call($cfg['license'], 'is_free') === false) return null;
            return ['slug' => $slug] + $cfg;
        }
        return null;
    }

    private static function is_dismissed(string $slug): bool {
        $until = (int) get_user_meta(get_current_user_id(), self::META_KEY . '_' . $slug, true);
        return $until > time();
    }

    /** Stable-per-day feature rotation so the spotlight varies over time. */
    private static function pick(array $features): array {
        if (empty($features)) return ['key' => 'pro', 'title' => __('Pro features', 'rankforge'), 'body' => ''];
        $day = (int) gmdate('z');
        $idx = ($day + get_current_user_id()) % count($features);
        return $features[$idx];
    }

    public static function maybe_render() {
        $cur = self::current();
        if (!$cur) return;
        if (self::is_dismissed($cur['slug'])) return;

        $feat   = self::pick($cur['features']);
        $accent = $cur['accent'];
        $url    = self::upgrade_url($cur);
        $nonce  = wp_create_nonce('forge_pro_tip_dismiss');
        ?>
        <div class="forge-pro-tip" data-plugin="<?php echo esc_attr($cur['slug']); ?>"
             style="position:relative;border:1px solid #E5E7EB;border-left:4px solid <?php echo esc_attr($accent); ?>;background:#fff;border-radius:0 10px 10px 0;padding:14px 44px 14px 18px;margin:14px 0;display:flex;gap:14px;align-items:flex-start;max-width:760px;">
            <span class="dashicons dashicons-lightbulb" style="color:<?php echo esc_attr($accent); ?>;font-size:22px;width:22px;height:22px;margin-top:1px;"></span>
            <div style="flex:1;min-width:0;">
                <div style="font-size:11px;font-weight:700;letter-spacing:.5px;text-transform:uppercase;color:<?php echo esc_attr($accent); ?>;margin-bottom:2px;"><?php esc_html_e('Pro tip', 'rankforge'); ?></div>
                <strong style="font-size:14px;color:#111827;"><?php echo esc_html($feat['title']); ?></strong>
                <p style="margin:3px 0 8px;font-size:13.5px;color:#4B5563;line-height:1.5;"><?php echo esc_html($feat['body']); ?></p>
                <a href="<?php echo esc_url($url); ?>" target="_blank" rel="noopener"
                   data-forge-cta="go_pro" data-forge-ctx="<?php echo esc_attr($cur['slug'] . ':' . $feat['key']); ?>"
                   style="display:inline-flex;align-items:center;gap:5px;font-size:13.5px;font-weight:600;color:<?php echo esc_attr($accent); ?>;text-decoration:none;">
                    <?php esc_html_e('See what’s in Pro', 'rankforge'); ?> &rarr;
                </a>
            </div>
            <button type="button" class="forge-pro-tip-dismiss" data-nonce="<?php echo esc_attr($nonce); ?>" data-plugin="<?php echo esc_attr($cur['slug']); ?>"
                    title="<?php esc_attr_e('Dismiss', 'rankforge'); ?>" aria-label="<?php esc_attr_e('Dismiss', 'rankforge'); ?>"
                    style="position:absolute;top:10px;right:10px;background:transparent;border:0;color:#9CA3AF;cursor:pointer;padding:2px;line-height:1;">
                <span class="dashicons dashicons-no-alt" style="font-size:18px;width:18px;height:18px;"></span>
            </button>
        </div>
        <?php
    }

    public static function enqueue() {
        if (!self::current()) return;
        $handle = 'forge-pro-tip';
        // Explicit version (inline-only handle, no src) — Plugin Check flags a
        // false/unset version on register even when there is no external file.
        wp_register_script($handle, false, ['jquery'], '1.0', true);
        wp_enqueue_script($handle);
        $js = <<<'JS'
(function($){
  $(document).on('click', '.forge-pro-tip-dismiss', function(){
    var $btn = $(this), $card = $btn.closest('.forge-pro-tip');
    $card.slideUp(180);
    $.post(window.ajaxurl || (window.forgeTelemetry && window.forgeTelemetry.ajaxurl), {
      action: 'forge_pro_tip_dismiss',
      plugin: $btn.data('plugin'),
      nonce: $btn.data('nonce')
    });
  });
})(jQuery);
JS;
        wp_add_inline_script($handle, 'window.ajaxurl=window.ajaxurl||' . wp_json_encode(admin_url('admin-ajax.php')) . ';', 'before');
        wp_add_inline_script($handle, $js);
    }

    public static function ajax_dismiss() {
        check_ajax_referer('forge_pro_tip_dismiss', 'nonce');
        if (!current_user_can('manage_options')) wp_send_json_error(['message' => 'Forbidden'], 403);
        $slug = isset($_POST['plugin']) ? sanitize_key(wp_unslash($_POST['plugin'])) : '';
        if (!array_key_exists($slug, self::registry())) wp_send_json_error(['message' => 'bad plugin'], 400);
        update_user_meta(get_current_user_id(), self::META_KEY . '_' . $slug, time() + self::SNOOZE_DAYS * DAY_IN_SECONDS);
        // Count the dismissal too (opt-in telemetry; no-op without consent).
        if (class_exists('Forge_Telemetry')) {
            Forge_Telemetry::track('cta.pro_tip_dismissed', ['plugin' => $slug]);
        }
        wp_send_json_success();
    }

    private static function upgrade_url(array $cur): string {
        $url = self::license_call($cur['license'], 'upgrade_url');
        if (is_string($url) && $url !== '') return $url;
        return 'https://avakode.com/pricing/';
    }

    /** Call a License method whether it's declared static or instance. */
    private static function license_call(string $class, string $method) {
        if (!class_exists($class) || !method_exists($class, $method)) return null;
        try {
            $ref = new ReflectionMethod($class, $method);
            if ($ref->isStatic()) return $class::$method();
            if (method_exists($class, 'instance')) return $class::instance()->$method();
        } catch (\Throwable $e) {}
        return null;
    }
}

Forge_Pro_Tip::init();

} // class_exists guard
