// components/SlideRenderer.jsx
//
// Renders a single slide from a parsed slide YAML object. Supports cover layout,
// content layout, demo layout. Uses Hori-Modernist palette (cream / pounamu /
// kowhai). Exposes slide metadata to MorphyFloat for the drawer.
//
// Defensive: reads window.SlideLoader only for metadata fallback. Main data
// comes from props. Component renders even when SlideLoader absent.
//
// Wire-in: window.SlideRenderer = SlideRenderer
// Mounted in pitchdeck.html as <SlideRenderer slide={currentSlide} />

var _RS = React;
var _useMemoS = _RS.useMemo;

// Simple markdown parser for body content
function parseSimpleMarkdown(md) {
  if (!md) return '';
  var html = md;
  // Headers (must process h3 before h2 before h1)
  html = html.replace(/^### (.+)$/gm, '<h3>$1</h3>');
  html = html.replace(/^## (.+)$/gm, '<h2>$1</h2>');
  html = html.replace(/^# (.+)$/gm, '<h1>$1</h1>');
  // Bold
  html = html.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
  // Italic
  html = html.replace(/\*(.+?)\*/g, '<em>$1</em>');
  // Horizontal rule
  html = html.replace(/^---$/gm, '<hr/>');
  // Lists: collect consecutive - items into <ul>
  var lines = html.split('\n');
  var result = [];
  var inList = false;
  for (var i = 0; i < lines.length; i++) {
    var line = lines[i];
    var liMatch = line.match(/^- (.+)$/);
    if (liMatch) {
      if (!inList) {
        inList = true;
        result.push('<ul>');
      }
      result.push('<li>' + liMatch[1] + '</li>');
    } else {
      if (inList) {
        inList = false;
        result.push('</ul>');
      }
      result.push(line);
    }
  }
  if (inList) result.push('</ul>');
  html = result.join('\n');
  // Paragraphs: wrap bare text blocks
  html = html.split('\n\n').map(function(block) {
    var trimmed = block.trim();
    if (!trimmed) return '';
    if (trimmed.charAt(0) === '<') return trimmed;
    return '<p>' + trimmed + '</p>';
  }).join('\n');
  return html;
}

function SlideRenderer({ slide, audienceMode }) {
  if (!slide) {
    return (
      <div className="slide slide-loading">
        <p>Loading slide...</p>
      </div>
    );
  }

  // Parse body markdown into HTML
  var bodyHtml = _useMemoS(function() {
    if (!slide.body_markdown) return '';
    return parseSimpleMarkdown(slide.body_markdown);
  }, [slide.body_markdown]);

  var layout = (slide.design && slide.design.layout) || 'content';
  var accentColor = (slide.design && slide.design.accent) || 'pounamu';
  var highlightColor = (slide.design && slide.design.highlight) || 'kowhai';

  // Speaker notes: only visible with ?sovereign=1
  var showSpeakerNotes = false;
  try {
    var params = new URLSearchParams(window.location.search);
    showSpeakerNotes = params.get('sovereign') === '1' && slide.speaker_notes;
  } catch (e) {
    // URL parsing not supported
  }

  // Knowledge stack pills
  var knowledgeStack = slide.knowledge_stack || [];

  return (
    <div
      className={'slide slide-' + layout}
      data-audience={audienceMode}
      data-accent={accentColor}
      data-highlight={highlightColor}
    >
      <header className="slide-header">
        <h1 className="slide-title">{slide.title}</h1>
        {slide.subtitle && <h2 className="slide-subtitle">{slide.subtitle}</h2>}
        {slide.tagline && <p className="slide-tagline">{slide.tagline}</p>}
      </header>

      {knowledgeStack.length > 0 && (
        <div className="slide-knowledge-pills">
          {knowledgeStack.map(function(area, idx) {
            // Bug fix 2026-05-09: knowledge_stack entries are objects
            // { fact_id, claim, source, confidence }, not strings. Render
            // the claim text and tag with confidence; keep fact_id as
            // hover title for traceability.
            var label = (area && typeof area === 'object')
              ? (area.claim || area.fact_id || JSON.stringify(area))
              : String(area);
            var titleAttr = (area && typeof area === 'object')
              ? (area.fact_id + ' (' + (area.confidence || 'UNKNOWN') + ') ' + (area.source || ''))
              : '';
            var conf = (area && area.confidence) ? area.confidence : null;
            return (
              <span
                key={idx}
                className={'slide-knowledge-pill' + (conf ? ' conf-' + conf : '')}
                title={titleAttr}
              >{label}</span>
            );
          })}
        </div>
      )}

      <main
        className="slide-body"
        dangerouslySetInnerHTML={{ __html: bodyHtml }}
      />

      {showSpeakerNotes && (
        <details className="morphy-speaker-notes">
          <summary>Speaker notes</summary>
          <div className="morphy-speaker-notes-content">
            {slide.speaker_notes}
          </div>
        </details>
      )}

      <footer className="slide-footer">
        <span className="slide-number">
          {slide.slide_number != null ? 'Slide ' + slide.slide_number : ''}
        </span>
        <span className="slide-mode">Mode: {audienceMode || 'all'}</span>
        {slide.try_with_morphy_seed && (
          <a
            className="slide-try-link"
            href={'/dungeon-master?seed=' + encodeURIComponent(slide.try_with_morphy_seed)}
          >
            Try this with Morphy
          </a>
        )}
      </footer>
    </div>
  );
}

window.SlideRenderer = SlideRenderer;
