/* WPSiteBeam Scanner — Testimonials Tab
   Native on-site testimonials/reviews pulled from the site's own pages. Google /
   3rd-party review WIDGETS are NOT extracted (their content is injected by the
   vendor's JS, not part of the site) — when detected they're surfaced as an
   honest "not extracted" note (Radical Transparency).
   v1.0.0 — 2026-06-23. CSS var() tokens only; WCAG 2.1 AA; analytics
   (testimonials.viewed on mount, .exported on export). */
(function () {
  'use strict';
  const Icon = window.Icon;
  const { useState, useEffect, useMemo } = React;

  function track(eventType, detail) {
    try {
      const token = window.WPSB && window.WPSB.getToken && window.WPSB.getToken();
      if (!token) return;
      const base = (window.WPSBD && window.WPSBD.apiBase) || 'https://api.wpsitebeam.io';
      fetch(base + '/events/track', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + token },
        body: JSON.stringify({ event_type: eventType, detail: detail || {} }),
      }).catch(function () {});
    } catch (_) { /* swallow */ }
  }

  function buildCsv(entries) {
    const rows = [['quote', 'author', 'author_url', 'role', 'rating', 'date', 'source_url']];
    entries.forEach(function (e) {
      rows.push([
        e.quote || '', e.author || '', e.author_url || '', e.role || '',
        (e.rating != null ? String(e.rating) : ''), e.date || '', e.source_url || '',
      ]);
    });
    return rows.map(function (r) {
      return r.map(function (c) { return '"' + String(c).replace(/"/g, '""') + '"'; }).join(',');
    }).join('\r\n');
  }

  function Stars({ rating }) {
    const n = Math.max(0, Math.min(5, Math.round(Number(rating) || 0)));
    if (!n) return null;
    return (
      <span aria-label={n + ' out of 5'} title={n + ' / 5'} style={{ color: 'var(--warn)', fontSize: '.8rem', letterSpacing: 1 }}>
        {'★★★★★'.slice(0, n)}<span style={{ color: 'var(--dim)' }}>{'☆☆☆☆☆'.slice(0, 5 - n)}</span>
      </span>
    );
  }

  function ScannerTestimonialsTab({ data }) {
    const t = data && data.testimonials;
    const entries = (t && Array.isArray(t.entries)) ? t.entries : [];
    const thirdParty = (t && Array.isArray(t.third_party)) ? t.third_party : [];
    const site = (data && data.site) || (data && data.domain) || 'this site';
    const tpVendors = useMemo(function () {
      const s = []; const seen = {};
      thirdParty.forEach(function (x) { const p = x && x.platform; if (p && !seen[p]) { seen[p] = 1; s.push(p); } });
      return s;
    }, [thirdParty]);

    useEffect(function () {
      track('testimonials.viewed', { surface: 'scan-report', tab: 'testimonials', count: entries.length, third_party: thirdParty.length });
    }, []);

    /* Third-party-only state (native count 0, widgets present) — honest, no fabrication. */
    if (!entries.length) {
      return (
        <div style={{ padding: '36px 24px', maxWidth: 640, margin: '0 auto', textAlign: 'center' }}>
          <div style={{ fontSize: '2rem', marginBottom: 12, opacity: .4 }}>💬</div>
          <div style={{ fontWeight: 700, color: 'var(--text)', marginBottom: 8, fontSize: '.9rem' }}>No native testimonials extracted</div>
          <div style={{ fontSize: '.8rem', color: 'var(--dim)', lineHeight: 1.6 }}>
            {tpVendors.length
              ? ('This site shows reviews through a third-party widget (' + tpVendors.join(', ') + '). That content is injected by the vendor and is not part of the site’s own pages, so it can’t be extracted. Adding native, on-site testimonials would let them be indexed and reused.')
              : ('No on-site testimonials or reviews were found in the site’s own pages.')}
          </div>
        </div>
      );
    }

    return (
      <div style={{ padding: '4px 2px' }}>
        {/* Header — count + honest note + export */}
        <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap', marginBottom: 12 }}>
          <div style={{ minWidth: 0 }}>
            <div style={{ fontSize: '1rem', fontWeight: 700, color: 'var(--text)' }}>Testimonials</div>
            <div style={{ fontSize: '.74rem', color: 'var(--dim)', lineHeight: 1.5, marginTop: 4, maxWidth: 600 }}>
              {(t && t.note) || ('Native testimonials authored in ' + site + '’s own pages.')}
            </div>
            <div style={{ fontSize: '.68rem', color: 'var(--dim)', fontFamily: 'var(--font-mono)', marginTop: 4 }}>
              {entries.length} native testimonial{entries.length !== 1 ? 's' : ''}
            </div>
          </div>
          <div style={{ display: 'flex', gap: 6 }}>
            <button className="btn btn-ghost btn-sm"
              onClick={function () { window.wpsbDownload(site + '-testimonials.csv', buildCsv(entries), 'text/csv'); track('testimonials.exported', { format: 'csv', count: entries.length }); }}>
              {Icon ? <Icon name="download" size={12} /> : null} CSV
            </button>
            <button className="btn btn-ghost btn-sm"
              onClick={function () { window.wpsbDownload(site + '-testimonials.json', JSON.stringify(entries, null, 2), 'application/json'); track('testimonials.exported', { format: 'json', count: entries.length }); }}>
              {Icon ? <Icon name="download" size={12} /> : null} JSON
            </button>
          </div>
        </div>

        {/* Third-party widgets detected — listed, never extracted */}
        {tpVendors.length ? (
          <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start', padding: '9px 13px', marginBottom: 14, background: 'var(--orange-dim)', border: '1px solid var(--orange-dim)', borderRadius: 8, fontSize: '.76rem', color: 'var(--dim)', lineHeight: 1.6 }}>
            <span style={{ fontSize: '1rem', flexShrink: 0, marginTop: 1 }}>ⓘ</span>
            <span>
              <strong style={{ color: 'var(--text)', fontWeight: 600 }}>Also embedded via {tpVendors.join(', ')}.</strong>
              {' '}Those reviews are injected by a third-party widget and aren’t part of the site’s own pages, so they’re not extracted here.
            </span>
          </div>
        ) : null}

        {/* Testimonial cards */}
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: 12 }}>
          {entries.map(function (e) {
            return (
              <article key={e.id} className="card" style={{ height: '100%' }}>
                <div className="card-body" style={{ display: 'flex', flexDirection: 'column', gap: 8, height: '100%' }}>
                  {e.rating != null ? <Stars rating={e.rating} /> : null}
                  <blockquote style={{ margin: 0, fontSize: '.82rem', color: 'var(--text)', lineHeight: 1.55, flex: 1 }}>
                    {'“' + (e.quote || '') + '”'}
                  </blockquote>
                  <div style={{ borderTop: '1px solid var(--border)', paddingTop: 8, marginTop: 2 }}>
                    <div style={{ fontSize: '.76rem', fontWeight: 600, color: 'var(--text)' }}>
                      {e.author_url ? (
                        <a href={e.author_url} target="_blank" rel="noopener noreferrer nofollow"
                          style={{ color: 'var(--text)', textDecoration: 'underline', textDecorationColor: 'var(--border)', textUnderlineOffset: 2 }}
                          title={'Author’s site as listed on the page (kept as-found — may be outdated or broken): ' + e.author_url}>
                          {e.author || 'Anonymous'}
                        </a>
                      ) : (e.author || 'Anonymous')}
                    </div>
                    {e.role ? <div style={{ fontSize: '.7rem', color: 'var(--dim)' }}>{e.role}</div> : null}
                    <div style={{ display: 'flex', gap: 8, alignItems: 'center', marginTop: 4, flexWrap: 'wrap' }}>
                      {e.date ? <span style={{ fontSize: '.66rem', color: 'var(--dim)', fontFamily: 'var(--font-mono)' }}>{e.date}</span> : null}
                      {e.source_url ? (
                        <a href={e.source_url} target="_blank" rel="noopener noreferrer"
                          style={{ fontSize: '.66rem', color: 'var(--beam)', textDecoration: 'none' }}
                          title={e.source_url}>source ↗</a>
                      ) : null}
                    </div>
                  </div>
                </div>
              </article>
            );
          })}
        </div>
      </div>
    );
  }

  window.ScannerTestimonialsTab = ScannerTestimonialsTab;
})();
