<?php
/**
 * Plugin Name: Fe Adulta — Feedback Beta
 * Description: Barra sutil de aviso "Beta" en todo el sitio + mini formulario (👍/👎 +
 *              comentario opcional) que se abre a demanda, para que el público ayude a
 *              encontrar errores. Guarda cada voto como "Beta Feedback" (CPT propio),
 *              legible en wp-admin en una sola lista. No usa el sistema de comentarios.
 * Version: 1.1
 *
 * Ver issue rafa/feadulta#78.
 */

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

const FEA_FB_CPT      = 'fea_feedback';
const FEA_FB_RATE_MAX = 12;   // máximo de envíos por IP por hora
const FEA_FB_COMMENT_MAX = 2000;

/* ── 1) CPT donde se guardan los votos (solo backend) ─────────────────────── */
add_action('init', function () {
    register_post_type(FEA_FB_CPT, [
        'labels' => [
            'name'          => 'Beta Feedback',
            'singular_name' => 'Feedback',
            'menu_name'     => 'Beta Feedback',
        ],
        'public'              => false,
        'show_ui'             => true,
        'show_in_menu'        => true,
        'menu_icon'           => 'dashicons-feedback',
        'menu_position'       => 26,
        'capability_type'     => 'post',
        'capabilities'        => ['create_posts' => 'do_not_allow'], // solo se crean por API
        'map_meta_cap'        => true,
        'supports'            => ['title', 'editor'],
        'exclude_from_search' => true,
    ]);
});

/* ── 2a) Endpoint de consulta de idioma Polylang (para publicabot / integración externa) ── */
add_action('rest_api_init', function () {
    register_rest_route('fea/v1', '/lang/(?P<id>\d+)', [
        'methods'             => 'GET',
        'permission_callback' => '__return_true',
        'callback'            => function (WP_REST_Request $req) {
            $id   = (int) $req->get_param('id');
            $post = get_post($id);
            if (!$post || $post->post_type !== 'post') {
                return new WP_REST_Response(['error' => 'post not found'], 404);
            }
            $langs = wp_get_object_terms($id, 'language', ['fields' => 'slugs']);
            $lang  = (!is_wp_error($langs) && !empty($langs)) ? $langs[0] : null;
            return new WP_REST_Response(['id' => $id, 'lang' => $lang], 200);
        },
    ]);
});

/* ── 2) Endpoint REST para recibir el voto ────────────────────────────────── */
add_action('rest_api_init', function () {
    register_rest_route('fea/v1', '/feedback', [
        'methods'             => 'POST',
        'permission_callback' => '__return_true', // público (Beta); protegido con honeypot + rate-limit
        'callback'            => 'fea_feedback_submit',
    ]);
});

function fea_feedback_submit(WP_REST_Request $req) {
    // Honeypot: si el campo oculto viene relleno, es un bot.
    if (trim((string) $req->get_param('website')) !== '') {
        return new WP_REST_Response(['ok' => true], 200); // fingir éxito
    }

    $vote = $req->get_param('vote') === 'up' ? 'up' : ($req->get_param('vote') === 'down' ? 'down' : '');
    if ($vote === '') {
        return new WP_REST_Response(['ok' => false, 'error' => 'voto inválido'], 400);
    }

    // Rate-limit por IP.
    $ip  = fea_feedback_client_ip();
    $key = 'fea_fb_rl_' . md5($ip);
    $n   = (int) get_transient($key);
    if ($n >= FEA_FB_RATE_MAX) {
        return new WP_REST_Response(['ok' => false, 'error' => 'demasiados envíos'], 429);
    }
    set_transient($key, $n + 1, HOUR_IN_SECONDS);

    $comment = trim((string) $req->get_param('comment'));
    $comment = mb_substr(wp_strip_all_tags($comment), 0, FEA_FB_COMMENT_MAX);
    $url     = esc_url_raw((string) $req->get_param('url'));
    $src_id  = (int) $req->get_param('post_id');
    $lang    = preg_replace('/[^a-z]/', '', (string) $req->get_param('lang'));
    $title   = (string) $req->get_param('title');

    $emoji = $vote === 'up' ? '👍' : '👎';
    $post_id = wp_insert_post([
        'post_type'    => FEA_FB_CPT,
        'post_status'  => 'private',
        'post_title'   => sprintf('%s %s', $emoji, $title ?: $url),
        'post_content' => $comment,
    ], true);

    if (is_wp_error($post_id)) {
        return new WP_REST_Response(['ok' => false, 'error' => 'no se pudo guardar'], 500);
    }

    update_post_meta($post_id, '_fea_fb_vote', $vote);
    update_post_meta($post_id, '_fea_fb_url', $url);
    update_post_meta($post_id, '_fea_fb_source_id', $src_id);
    update_post_meta($post_id, '_fea_fb_lang', $lang);
    update_post_meta($post_id, '_fea_fb_ua', mb_substr((string) ($_SERVER['HTTP_USER_AGENT'] ?? ''), 0, 255));
    update_post_meta($post_id, '_fea_fb_ip', md5($ip)); // hash, no IP en claro

    return new WP_REST_Response(['ok' => true], 200);
}

function fea_feedback_client_ip(): string {
    foreach (['HTTP_CF_CONNECTING_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR'] as $k) {
        if (!empty($_SERVER[$k])) return trim(explode(',', $_SERVER[$k])[0]);
    }
    return '0.0.0.0';
}

/* ── 3) Columnas en el listado del wp-admin ───────────────────────────────── */
add_filter('manage_' . FEA_FB_CPT . '_posts_columns', function ($cols) {
    return [
        'cb'        => $cols['cb'] ?? '',
        'fb_vote'   => 'Voto',
        'fb_url'    => 'Página',
        'fb_lang'   => 'Idioma',
        'fb_comment'=> 'Comentario',
        'date'      => 'Fecha',
    ];
});
add_action('manage_' . FEA_FB_CPT . '_posts_custom_column', function ($col, $post_id) {
    if ($col === 'fb_vote') {
        echo get_post_meta($post_id, '_fea_fb_vote', true) === 'up' ? '👍' : '👎';
    } elseif ($col === 'fb_url') {
        $u = get_post_meta($post_id, '_fea_fb_url', true);
        if ($u) echo '<a href="' . esc_url($u) . '" target="_blank" rel="noopener">' . esc_html(wp_parse_url($u, PHP_URL_PATH) ?: $u) . '</a>';
    } elseif ($col === 'fb_lang') {
        echo esc_html(strtoupper(get_post_meta($post_id, '_fea_fb_lang', true) ?: '—'));
    } elseif ($col === 'fb_comment') {
        echo esc_html(wp_trim_words(get_post_field('post_content', $post_id), 24));
    }
}, 10, 2);

/* ── 4) Barra Beta sutil (persistente) + tarjeta de feedback (a demanda) ──── */
/** Etiquetas del widget Beta por idioma (Polylang). */
function fea_beta_labels(): array {
    $all = [
        'es' => ['region'=>'Aviso Beta','intro'=>'Estamos en','help'=>'¿Nos ayudas a mejorar FeAdulta?',
            'opinion'=>'Dar mi opinión','collab'=>'Colaborar','dismiss'=>'Cerrar aviso','fbregion'=>'Feedback de la página',
            'close'=>'Cerrar','q'=>'¿Se ve bien esta página?','up'=>'Sí, se ve bien','down'=>'No, hay algo mal',
            'ph'=>'¿Algo falla o se ve mal? Cuéntanoslo (opcional)','send'=>'Enviar','thanks'=>'¡Gracias por ayudar! 🙏'],
        'en' => ['region'=>'Beta notice','intro'=>'We are in','help'=>'Will you help us improve FeAdulta?',
            'opinion'=>'Give feedback','collab'=>'Collaborate','dismiss'=>'Close notice','fbregion'=>'Page feedback',
            'close'=>'Close','q'=>'Does this page look right?','up'=>'Yes, looks good','down'=>'No, something is wrong',
            'ph'=>'Something broken or off? Tell us (optional)','send'=>'Send','thanks'=>'Thanks for helping! 🙏'],
        'fr' => ['region'=>'Avis Bêta','intro'=>'Nous sommes en','help'=>'Voulez-vous nous aider à améliorer FeAdulta ?',
            'opinion'=>'Donner mon avis','collab'=>'Collaborer','dismiss'=>'Fermer l’avis','fbregion'=>'Retour sur la page',
            'close'=>'Fermer','q'=>'Cette page s’affiche-t-elle bien ?','up'=>'Oui, c’est bien','down'=>'Non, il y a un problème',
            'ph'=>'Un souci ou un affichage incorrect ? Dites-le-nous (facultatif)','send'=>'Envoyer','thanks'=>'Merci de votre aide ! 🙏'],
        'it' => ['region'=>'Avviso Beta','intro'=>'Siamo in','help'=>'Ci aiuti a migliorare FeAdulta?',
            'opinion'=>'Dai la tua opinione','collab'=>'Collabora','dismiss'=>'Chiudi avviso','fbregion'=>'Feedback della pagina',
            'close'=>'Chiudi','q'=>'Questa pagina si vede bene?','up'=>'Sì, si vede bene','down'=>'No, c’è qualcosa che non va',
            'ph'=>'Qualcosa non va o si vede male? Faccelo sapere (facoltativo)','send'=>'Invia','thanks'=>'Grazie per l’aiuto! 🙏'],
        'pt' => ['region'=>'Aviso Beta','intro'=>'Estamos em','help'=>'Ajuda-nos a melhorar a FeAdulta?',
            'opinion'=>'Dar a minha opinião','collab'=>'Colaborar','dismiss'=>'Fechar aviso','fbregion'=>'Feedback da página',
            'close'=>'Fechar','q'=>'Esta página vê-se bem?','up'=>'Sim, vê-se bem','down'=>'Não, há algo errado',
            'ph'=>'Algo falha ou vê-se mal? Conta-nos (opcional)','send'=>'Enviar','thanks'=>'Obrigado por ajudar! 🙏'],
    ];
    $lang = function_exists('pll_current_language') ? (string) pll_current_language() : 'es';
    return $all[$lang] ?? $all['es'];
}

add_action('wp_footer', function () {
    if (is_admin()) return;
    $rest = esc_url_raw(rest_url('fea/v1/feedback'));
    $t = fea_beta_labels();
    ?>
    <style>
    /* Barra sutil de aviso Beta, abajo, full-width */
    #fea-beta-bar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 99997;
        background: #faf6f2; border-top: 1px solid #e6ddd5; color: #4a3b34;
        font-family: inherit; font-size: .86rem; line-height: 1.3;
        padding: 8px 44px 8px 16px; text-align: center; }
    #fea-beta-bar strong { color: #8b1a2e; }
    #fea-beta-bar .fea-beta-open { margin-left: 10px; cursor: pointer; border: 1px solid #8b1a2e;
        background: #8b1a2e; color: #fff; border-radius: 6px; padding: 4px 12px; font-size: .82rem; font-weight: 600; }
    #fea-beta-bar .fea-beta-open:hover { background: #761526; }
    #fea-beta-bar .fea-beta-collab { margin-left: 8px; cursor: pointer; display: inline-block;
        border: 1px solid #1b7a34; background: #1b7a34; color: #fff; border-radius: 6px;
        padding: 4px 12px; font-size: .82rem; font-weight: 600; text-decoration: none; }
    #fea-beta-bar .fea-beta-collab:hover { background: #15642a; }
    #fea-beta-bar .fea-beta-dismiss { position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
        border: 0; background: none; font-size: 1.15rem; cursor: pointer; color: #8a7a72; padding: 2px 6px; line-height: 1; }
    #fea-beta-bar.hidden { display: none; }

    /* Tarjeta de feedback: oculta hasta que el usuario la abre desde la barra */
    #fea-fb { position: fixed; right: 16px; bottom: 56px; z-index: 99998; font-family: inherit; max-width: 300px; }
    #fea-fb[hidden] { display: none; }
    #fea-fb .fea-fb-card { background:#fff; border:1px solid #e2e2e2; border-radius:12px;
        box-shadow:0 8px 28px rgba(0,0,0,.16); padding:12px 14px; font-size:.9rem; color:#222; position:relative; }
    #fea-fb .fea-fb-q { margin:0 0 8px; line-height:1.3; padding-right:16px; }
    #fea-fb .fea-fb-btns { display:flex; gap:8px; }
    #fea-fb button.fea-fb-vote { cursor:pointer; border:1px solid #ccc; background:#fafafa; border-radius:8px;
        padding:6px 12px; font-size:1.05rem; line-height:1; }
    #fea-fb button.fea-fb-vote:hover { background:#f0f0f0; }
    #fea-fb button.fea-fb-vote.sel { border-color:#8b1a2e; background:#f7e9ec; }
    #fea-fb textarea { width:100%; margin:9px 0 8px; border:1px solid #ccc; border-radius:8px; padding:7px;
        font:inherit; font-size:.85rem; resize:vertical; min-height:58px; box-sizing:border-box; }
    #fea-fb .fea-fb-send { background:#8b1a2e; color:#fff; border:1px solid #8b1a2e; border-radius:8px;
        padding:6px 12px; font-size:.85rem; width:100%; cursor:pointer; }
    #fea-fb .fea-fb-hp { position:absolute; left:-9999px; }
    #fea-fb .fea-fb-close { position:absolute; top:4px; right:8px; border:0; background:none; font-size:1rem; cursor:pointer; padding:2px 4px; line-height:1; }
    @media (max-width:600px){ #fea-fb{ right:10px; left:10px; max-width:none; } #fea-beta-bar{ font-size:.8rem; } }
    </style>

    <div id="fea-beta-bar" class="hidden" role="region" aria-label="<?php echo esc_attr($t['region']); ?>">
      🌱 <?php echo esc_html($t['intro']); ?> <strong>Beta</strong>. <?php echo esc_html($t['help']); ?>
      <button type="button" class="fea-beta-open"><?php echo esc_html($t['opinion']); ?></button>
      <a class="fea-beta-collab" href="https://edicionesfeadulta.com/colabora/" target="_blank" rel="noopener"><?php echo esc_html($t['collab']); ?></a>
      <button type="button" class="fea-beta-dismiss" aria-label="<?php echo esc_attr($t['dismiss']); ?>">×</button>
    </div>

    <div id="fea-fb" hidden role="complementary" aria-label="<?php echo esc_attr($t['fbregion']); ?>">
      <div class="fea-fb-card">
        <button type="button" class="fea-fb-close" aria-label="<?php echo esc_attr($t['close']); ?>">×</button>
        <p class="fea-fb-q"><?php echo esc_html($t['q']); ?></p>
        <div class="fea-fb-btns">
          <button type="button" class="fea-fb-vote" data-vote="up" aria-label="<?php echo esc_attr($t['up']); ?>">👍</button>
          <button type="button" class="fea-fb-vote" data-vote="down" aria-label="<?php echo esc_attr($t['down']); ?>">👎</button>
        </div>
        <div class="fea-fb-more" hidden>
          <input type="text" class="fea-fb-hp" tabindex="-1" autocomplete="off" aria-hidden="true" placeholder="No rellenar">
          <textarea placeholder="<?php echo esc_attr($t['ph']); ?>"></textarea>
          <button type="button" class="fea-fb-send"><?php echo esc_html($t['send']); ?></button>
        </div>
        <div class="fea-fb-thanks" hidden><?php echo esc_html($t['thanks']); ?></div>
      </div>
    </div>

    <script>
    (function(){
      var bar = document.getElementById('fea-beta-bar');
      var box = document.getElementById('fea-fb');
      if(!bar || !box) return;
      var REST = <?php echo json_encode($rest); ?>;
      var pid  = <?php echo (int) (is_singular() ? get_queried_object_id() : 0); ?>;
      var lang = <?php echo json_encode(function_exists('pll_current_language') ? (string) pll_current_language() : ''); ?>;
      var chosen = null;
      var moreEl = box.querySelector('.fea-fb-more');
      var votes  = box.querySelectorAll('.fea-fb-vote');
      var thanks = box.querySelector('.fea-fb-thanks');

      // Mostrar la barra salvo que el usuario la haya descartado antes.
      try { if (!localStorage.getItem('fea_beta_bar_off')) bar.classList.remove('hidden'); }
      catch(e){ bar.classList.remove('hidden'); }

      function openCard(){ box.hidden = false; }
      function closeCard(){ box.hidden = true; }

      bar.querySelector('.fea-beta-open').addEventListener('click', openCard);
      bar.querySelector('.fea-beta-dismiss').addEventListener('click', function(){
        bar.classList.add('hidden');
        try { localStorage.setItem('fea_beta_bar_off','1'); } catch(e){}
      });
      box.querySelector('.fea-fb-close').addEventListener('click', closeCard);

      votes.forEach(function(b){ b.addEventListener('click', function(){
        chosen = b.getAttribute('data-vote');
        votes.forEach(function(x){ x.classList.toggle('sel', x===b); });
        moreEl.hidden = false;
      });});

      box.querySelector('.fea-fb-send').addEventListener('click', function(){
        if(!chosen) return;
        var hp = box.querySelector('.fea-fb-hp').value;
        var comment = box.querySelector('textarea').value;
        fetch(REST, { method:'POST', headers:{'Content-Type':'application/json'},
          body: JSON.stringify({ vote:chosen, comment:comment, url:location.href, post_id:pid,
            lang:lang, title:document.title, website:hp }) }).catch(function(){});
        box.querySelector('.fea-fb-btns').hidden = true;
        box.querySelector('.fea-fb-q').hidden = true;
        moreEl.hidden = true; thanks.hidden = false;
        setTimeout(closeCard, 2200);
      });
    })();
    </script>
    <?php
}, 40);
