<?php
/**
 * Forge Feedback Widget — shared NPS/CSAT collector for all 4 Forge plugins.
 *
 * Same duplication contract as Forge_Suite_Dashboard /
 * Forge_Credits_Widget: edit ONE copy, copy to all 4 plugins. First
 * loader wins via class_exists guard.
 *
 * Behavior:
 * - Renders a small "How likely are you to recommend…?" card in the
 * admin footer on Forge plugin pages only (page slug starts with
 * `lf-`, `rankforge`, `formforge`, `fieldforge`, or `forge-suite`).
 * - Show frequency: at least 30 days after install, then at most once
 * per 60 days per user, suppressed 14 days after dismiss.
 * - NPS: 0–10 scale. On submit, posts to api.avakode.com/feedback and
 * stores `forge_feedback_submitted_at` in user_meta so we don't re-prompt.
 * - Non-blocking: if the API is unreachable, the card still closes and
 * we set the cooldown — we're not going to block the user on our bug.
 *
 * Privacy: no post content, no admin email by default. The user can tick
 * a "contact me" checkbox to include their email — otherwise only the
 * score + comment + plugin/wp version travel.
 *
 * @package Forge
 */

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

if (!class_exists('Forge_Feedback_Widget')) {

class Forge_Feedback_Widget {

    const API_URL = 'https://api.avakode.com/feedback';

    const INSTALL_OPT         = 'forge_feedback_first_seen';
    const USER_DISMISSED_META = 'forge_feedback_dismissed_until';
    const USER_SUBMITTED_META = 'forge_feedback_submitted_at';

    const MIN_DAYS_SINCE_INSTALL = 30;
    const COOLDOWN_AFTER_SUBMIT  = 60 * DAY_IN_SECONDS;
    const COOLDOWN_AFTER_DISMISS = 14 * DAY_IN_SECONDS;

    public static function bootstrap() {
        if (!get_option(self::INSTALL_OPT)) {
            update_option(self::INSTALL_OPT, time(), false);
        }
        add_action('admin_footer', [__CLASS__, 'maybe_render']);
        add_action('wp_ajax_forge_feedback_submit', [__CLASS__, 'ajax_submit']);
        add_action('wp_ajax_forge_feedback_dismiss', [__CLASS__, 'ajax_dismiss']);
    }

    /** Is the current admin screen a Forge plugin page? */
    private static function on_forge_page() {
        $screen = function_exists('get_current_screen') ? get_current_screen() : null;
        if (!$screen) return false;
        $id = (string) $screen->id;
        // Plugin top-level menu slugs: langforge, rankforge, formforge, fieldforge,
        // forge-suite. Sub-pages get prefixed with "{slug}_page_{subslug}".
        foreach (['langforge', 'rankforge', 'formforge', 'fieldforge', 'forge-suite'] as $slug) {
            if (strpos($id, $slug) !== false) return true;
        }
        // Also match toplevel on "toplevel_page_{slug}".
        if (preg_match('/toplevel_page_(lang|seo|form|field)forge|forge-suite/', $id)) return true;
        return false;
    }

    private static function detect_product() {
        $screen = get_current_screen();
        $id = $screen ? (string) $screen->id : '';
        foreach (['langforge', 'rankforge', 'formforge', 'fieldforge'] as $slug) {
            if (strpos($id, $slug) !== false) return $slug;
        }
        // Forge Suite dashboard → report bundle
        if (strpos($id, 'forge-suite') !== false) return 'bundle';
        return 'bundle';
    }

    public static function maybe_render() {
        if (!self::on_forge_page()) return;
        if (!current_user_can('manage_options')) return;

        $user_id = get_current_user_id();
        $first_seen = (int) get_option(self::INSTALL_OPT, time());
        if ((time() - $first_seen) < self::MIN_DAYS_SINCE_INSTALL * DAY_IN_SECONDS) return;

        $dismissed_until = (int) get_user_meta($user_id, self::USER_DISMISSED_META, true);
        if ($dismissed_until && $dismissed_until > time()) return;

        $submitted_at = (int) get_user_meta($user_id, self::USER_SUBMITTED_META, true);
        if ($submitted_at && (time() - $submitted_at) < self::COOLDOWN_AFTER_SUBMIT) return;

        $product = self::detect_product();
        $nonce = wp_create_nonce('forge_feedback');
        self::render_html($product, $nonce);
    }

    private static function render_html($product, $nonce) {
        ?>
        <div id="forge-feedback-widget"
             data-product="<?php echo esc_attr($product); ?>"
             data-nonce="<?php echo esc_attr($nonce); ?>"
             style="display:none">
          <style>
            #forge-feedback-widget {
              position: fixed; right: 20px; bottom: 20px; z-index: 100000;
              width: 360px; padding: 20px; border-radius: 14px;
              background: #fff; box-shadow: 0 12px 40px rgba(0,0,0,.15);
              border: 1px solid rgba(0,0,0,.06);
              font-family: -apple-system, BlinkMacSystemFont, sans-serif;
            }
            #forge-feedback-widget h4 { margin: 0 0 6px 0; font-size: 15px; font-weight: 600; color: #0f172a; }
            #forge-feedback-widget p  { margin: 0 0 12px 0; font-size: 13px; color: #475569; line-height: 1.5; }
            #forge-feedback-widget .fb-scores { display: grid; grid-template-columns: repeat(11, 1fr); gap: 4px; margin-bottom: 12px; }
            #forge-feedback-widget .fb-score {
              padding: 8px 0; border: 1px solid #e2e8f0; background: #f8fafc;
              border-radius: 6px; cursor: pointer; font-size: 12px;
              font-weight: 500; color: #475569; text-align: center;
              transition: all .12s ease;
            }
            #forge-feedback-widget .fb-score:hover { border-color: #0ec49e; color: #0a8a6e; }
            #forge-feedback-widget .fb-score.selected { background: #0ec49e; color: #fff; border-color: #0ec49e; }
            #forge-feedback-widget textarea {
              width: 100%; min-height: 72px; padding: 8px;
              border: 1px solid #e2e8f0; border-radius: 6px;
              font-family: inherit; font-size: 13px; resize: vertical;
              margin-bottom: 10px; box-sizing: border-box;
            }
            #forge-feedback-widget .fb-legend { display: flex; justify-content: space-between; font-size: 11px; color: #94a3b8; margin-bottom: 8px; }
            #forge-feedback-widget .fb-actions { display: flex; justify-content: space-between; align-items: center; gap: 8px; }
            #forge-feedback-widget .fb-dismiss, #forge-feedback-widget .fb-submit {
              padding: 7px 14px; border-radius: 6px; font-size: 13px;
              border: none; cursor: pointer; font-weight: 500;
            }
            #forge-feedback-widget .fb-dismiss { background: none; color: #94a3b8; }
            #forge-feedback-widget .fb-dismiss:hover { color: #475569; }
            #forge-feedback-widget .fb-submit { background: #0ec49e; color: #fff; }
            #forge-feedback-widget .fb-submit:hover { background: #0a8a6e; }
            #forge-feedback-widget .fb-submit:disabled { background: #cbd5e1; cursor: not-allowed; }
            #forge-feedback-widget .fb-done { text-align: center; padding: 8px 0; font-size: 14px; color: #0a8a6e; }
          </style>
          <div class="fb-main">
            <h4><?php esc_html_e('Quick question — how are we doing?', 'rankforge'); ?></h4>
            <p><?php esc_html_e('On a scale of 0–10, how likely are you to recommend Forge to a colleague?', 'rankforge'); ?></p>
            <div class="fb-legend">
              <span><?php esc_html_e('Not likely', 'rankforge'); ?></span>
              <span><?php esc_html_e('Very likely', 'rankforge'); ?></span>
            </div>
            <div class="fb-scores">
              <?php for ($i = 0; $i <= 10; $i++) : ?>
                <button type="button" class="fb-score" data-score="<?php echo esc_attr($i); ?>"><?php echo esc_html($i); ?></button>
              <?php endfor; ?>
            </div>
            <textarea placeholder="<?php esc_attr_e('Anything we can improve? (optional)', 'rankforge'); ?>"></textarea>
            <div class="fb-actions">
              <button type="button" class="fb-dismiss"><?php esc_html_e('Not now', 'rankforge'); ?></button>
              <button type="button" class="fb-submit" disabled><?php esc_html_e('Send feedback', 'rankforge'); ?></button>
            </div>
          </div>
          <div class="fb-done" style="display:none">
            <?php esc_html_e('Thanks! We read every response.', 'rankforge'); ?>
          </div>
        </div>
        <script>
        (function(){
          const widget = document.getElementById('forge-feedback-widget');
          if (!widget) return;

          // Show after a short delay so it doesn't pounce on load.
          setTimeout(function(){ widget.style.display = 'block'; }, 1500);

          let selectedScore = null;
          const scoreButtons = widget.querySelectorAll('.fb-score');
          const submitBtn = widget.querySelector('.fb-submit');
          const dismissBtn = widget.querySelector('.fb-dismiss');
          const textarea = widget.querySelector('textarea');

          scoreButtons.forEach(function(btn){
            btn.addEventListener('click', function(){
              scoreButtons.forEach(b => b.classList.remove('selected'));
              btn.classList.add('selected');
              selectedScore = parseInt(btn.dataset.score, 10);
              submitBtn.disabled = false;
            });
          });

          dismissBtn.addEventListener('click', async function(){
            await fetch(ajaxurl, {
              method: 'POST',
              credentials: 'same-origin',
              headers: {'Content-Type': 'application/x-www-form-urlencoded'},
              body: 'action=forge_feedback_dismiss&_wpnonce=' + encodeURIComponent(widget.dataset.nonce),
            }).catch(function(){});
            widget.remove();
          });

          submitBtn.addEventListener('click', async function(){
            if (selectedScore === null) return;
            submitBtn.disabled = true;
            submitBtn.textContent = '…';

            const payload = new URLSearchParams();
            payload.set('action', 'forge_feedback_submit');
            payload.set('_wpnonce', widget.dataset.nonce);
            payload.set('product', widget.dataset.product);
            payload.set('score', String(selectedScore));
            payload.set('comment', textarea.value || '');

            await fetch(ajaxurl, {
              method: 'POST',
              credentials: 'same-origin',
              headers: {'Content-Type': 'application/x-www-form-urlencoded'},
              body: payload.toString(),
            }).catch(function(){});

            widget.querySelector('.fb-main').style.display = 'none';
            widget.querySelector('.fb-done').style.display = 'block';
            setTimeout(function(){ widget.remove(); }, 2200);
          });
        })();
        </script>
        </div>
        <?php
    }

    public static function ajax_submit() {
        check_ajax_referer('forge_feedback');
        if (!current_user_can('manage_options')) wp_send_json_error('forbidden', 403);

        $score = isset($_POST['score']) ? intval($_POST['score']) : -1;
        $product = isset($_POST['product']) ? sanitize_key($_POST['product']) : '';
        $comment = isset($_POST['comment']) ? sanitize_textarea_field(wp_unslash($_POST['comment'])) : '';

        if ($score < 0 || $score > 10) wp_send_json_error('invalid_score', 400);
        if (!in_array($product, ['langforge','rankforge','formforge','fieldforge','bundle'], true)) {
            wp_send_json_error('invalid_product', 400);
        }

        $user_id = get_current_user_id();
        $license_key = self::resolve_license_key();

        $body = [
            'type' => 'nps',
            'score' => $score,
            'product' => $product,
            'context' => 'plugin_dashboard',
            'comment' => $comment,
            'plugin_version' => defined('FORGE_VERSION') ? FORGE_VERSION : '',
            'wp_version' => get_bloginfo('version'),
        ];
        if ($license_key) $body['license_key'] = $license_key;
        $email = wp_get_current_user()->user_email;
        if ($email) $body['email'] = $email;

        $response = wp_remote_post(self::API_URL, [
            'timeout' => 4,
            'headers' => ['Content-Type' => 'application/json'],
            'body' => wp_json_encode($body),
        ]);

        // Regardless of API outcome, mark locally so we don't re-prompt.
        // If the API was flaky we'd rather silently lose the response than
        // annoy the user with a second popup later.
        update_user_meta($user_id, self::USER_SUBMITTED_META, time());

        if (is_wp_error($response)) {
            wp_send_json_success(['stored_locally' => true, 'api' => 'unreachable']);
        }
        wp_send_json_success(['api_status' => wp_remote_retrieve_response_code($response)]);
    }

    public static function ajax_dismiss() {
        check_ajax_referer('forge_feedback');
        if (!current_user_can('manage_options')) wp_send_json_error('forbidden', 403);
        update_user_meta(
            get_current_user_id(),
            self::USER_DISMISSED_META,
            time() + self::COOLDOWN_AFTER_DISMISS
        );
        wp_send_json_success();
    }

    /**
 * Best-effort license key lookup. Each plugin exposes a different
 * accessor — try a couple of safe, read-only options without
 * requiring any plugin to be loaded.
 */
    private static function resolve_license_key() {
        // Freemius stores it in wp_options under fs_accounts. We don't
        // parse it here — the API's license lookup is best-effort anyway,
        // so skipping it leaves the feedback anonymous, which is fine.
        return '';
    }
}

Forge_Feedback_Widget::bootstrap();

} // class_exists guard
