/* Webinaire — mode « Bible » : navigation, recherche, hébreu ‖ Louis Segond,
   clic sur un mot hébreu → fenêtre Strong's en français (Ancien Testament).
   Données chargées à la demande (volumineuses). Partage le scope global. */

const BIBLE_BOOKS = [
  ['Gen','Genèse'],['Exod','Exode'],['Lev','Lévitique'],['Num','Nombres'],['Deut','Deutéronome'],
  ['Josh','Josué'],['Judg','Juges'],['Ruth','Ruth'],['1Sam','1 Samuel'],['2Sam','2 Samuel'],
  ['1Kgs','1 Rois'],['2Kgs','2 Rois'],['1Chr','1 Chroniques'],['2Chr','2 Chroniques'],['Ezra','Esdras'],
  ['Neh','Néhémie'],['Esth','Esther'],['Job','Job'],['Ps','Psaumes'],['Prov','Proverbes'],
  ['Eccl','Ecclésiaste'],['Song','Cantique des cantiques'],['Isa','Ésaïe'],['Jer','Jérémie'],['Lam','Lamentations'],
  ['Ezek','Ézéchiel'],['Dan','Daniel'],['Hos','Osée'],['Joel','Joël'],['Amos','Amos'],
  ['Obad','Abdias'],['Jonah','Jonas'],['Mic','Michée'],['Nah','Nahum'],['Hab','Habacuc'],
  ['Zeph','Sophonie'],['Hag','Aggée'],['Zech','Zacharie'],['Mal','Malachie'],
  ['Matt','Matthieu'],['Mark','Marc'],['Luke','Luc'],['John','Jean'],['Acts','Actes'],
  ['Rom','Romains'],['1Cor','1 Corinthiens'],['2Cor','2 Corinthiens'],['Gal','Galates'],['Eph','Éphésiens'],
  ['Phil','Philippiens'],['Col','Colossiens'],['1Thess','1 Thessaloniciens'],['2Thess','2 Thessaloniciens'],
  ['1Tim','1 Timothée'],['2Tim','2 Timothée'],['Titus','Tite'],['Phlm','Philémon'],['Heb','Hébreux'],
  ['Jas','Jacques'],['1Pet','1 Pierre'],['2Pet','2 Pierre'],['1John','1 Jean'],['2John','2 Jean'],
  ['3John','3 Jean'],['Jude','Jude'],['Rev','Apocalypse'],
];
const BOOK_FR = Object.fromEntries(BIBLE_BOOKS.map(b => [b[0], b[1]]));
const OT_SET = new Set(BIBLE_BOOKS.slice(0, 39).map(b => b[0]));

// Index { osis: { chapters: n, verses: { chap: nbVersets } } } construit depuis BIBLE_FR
let BIBLE_INDEX = null;
function buildBibleIndex() {
  if (BIBLE_INDEX || !window.BIBLE_FR) return BIBLE_INDEX;
  const idx = {};
  for (const ref in window.BIBLE_FR) {
    const m = ref.match(/^(.+)\.(\d+)\.(\d+)$/);
    if (!m) continue;
    const [, bk, ch, vs] = m;
    const c = +ch, v = +vs;
    if (!idx[bk]) idx[bk] = { chapters: 0, verses: {} };
    if (c > idx[bk].chapters) idx[bk].chapters = c;
    if (v > (idx[bk].verses[c] || 0)) idx[bk].verses[c] = v;
  }
  BIBLE_INDEX = idx;
  return idx;
}

// Chargement à la demande des données (gros fichiers)
let _bibleLoading = null;
function loadBibleData() {
  if (window.BIBLE_FR && window.BIBLE_HEB_OT) { buildBibleIndex(); return Promise.resolve(); }
  if (_bibleLoading) return _bibleLoading;
  const files = [
    'assets/bible-fr.js',
    'assets/bible-heb-ot.js',
    'assets/strongs-hebrew-fr.js',
    'assets/bible-nt-gr.js',
    'assets/strongs-greek-fr.js',
    'assets/bible-heb-nt.js',
  ];
  _bibleLoading = Promise.all(files.map(src => new Promise((res, rej) => {
    const s = document.createElement('script');
    s.src = src; s.onload = res; s.onerror = () => { console.warn('Optionnel non chargé: ' + src); res(); };
    document.head.appendChild(s);
  }))).then(() => { buildBibleIndex(); });
  return _bibleLoading;
}

// Recherche « Jean 3 16 », « Gen 1:1 », « psaumes 23 », « Ésaïe 53 »
function parseBibleSearch(q) {
  if (!q) return null;
  const norm = (s) => s.toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g, '').replace(/[^a-z0-9]/g, '');
  const m = q.trim().match(/^(\d?\s*[^\d]+?)\s*(\d+)?\s*[:.\s]?\s*(\d+)?$/i);
  if (!m) return null;
  const bookQ = norm(m[1]);
  if (!bookQ) return null;
  let found = null;
  for (const [osis, fr] of BIBLE_BOOKS) {
    const a = norm(fr), b = norm(osis);
    if (a === bookQ || b === bookQ || a.startsWith(bookQ) || bookQ.startsWith(a) || a.indexOf(bookQ) === 0) { found = osis; break; }
  }
  if (!found) for (const [osis, fr] of BIBLE_BOOKS) { if (norm(fr).indexOf(bookQ) >= 0) { found = osis; break; } }
  if (!found) return null;
  return { osis: found, chapter: m[2] ? +m[2] : 1, verse: m[3] ? +m[3] : null };
}

// Entrée Strong's hébreu (H-codes) ou grec (G-codes)
function bibleStrongEntry(code) {
  if (typeof getStrongEntry === 'function') return getStrongEntry(code);
  const key = String(code || '').toUpperCase();
  if (key.startsWith('H')) return (window.STRONGS_HEBREW_FR && window.STRONGS_HEBREW_FR[key]) || null;
  if (key.startsWith('G')) return (window.STRONGS_GREEK_FR && window.STRONGS_GREEK_FR[key]) || null;
  return null;
}

function isNTBook(book) { return !OT_SET.has(book); }

// ============ Affichage du chapitre ============
function BibleBoard({ book, chapter, active, onSelectVerse, strong, onStrong }) {
  const setStrong = onStrong || (() => {});
  const idx = BIBLE_INDEX || {};
  const nbV = (idx[book] && idx[book].verses[chapter]) || 0;
  const isOT = OT_SET.has(book);
  const [fontSize, setFontSize] = React.useState(19);
  const hebSize = Math.round(fontSize * 1.55);
  const adjSize = (d) => setFontSize(s => Math.max(11, Math.min(36, s + d)));

  const rows = [];
  for (let v = 1; v <= nbV; v++) {
    const ref = book + '.' + chapter + '.' + v;
    rows.push({
      v, ref,
      fr: (window.BIBLE_FR || {})[ref] || '',
      heb: isOT ? ((window.BIBLE_HEB_OT || {})[ref] || null) : null,
      hebNt: !isOT ? ((window.BIBLE_HEB_NT || {})[ref] || null) : null,
      gr: !isOT ? ((window.BIBLE_NT_GR || {})[ref] || null) : null,
    });
  }

  const hasSecondCol = (row) => row.heb || row.hebNt;

  // Clic sur le mot français à l'index wi (sur frLen mots) :
  // mappe proportionnellement vers le mot grec le plus proche → Strong's direct
  const ntWordClick = (row, wi, frLen, e) => {
    e.stopPropagation();
    onSelectVerse(row.v);
    if (!row.gr || !row.gr.length) return;
    const ratio = frLen <= 1 ? 0 : wi / (frLen - 1);
    const grIdx = Math.round(ratio * (row.gr.length - 1));
    const [word, code] = row.gr[grIdx] || [];
    if (code) setStrong({ code, word });
  };

  return (
    <div style={{ position: 'absolute', inset: 0, padding: '40px 56px 24px', color: '#003333',
      display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
      {/* En-tête du chapitre */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
        borderBottom: '1px solid rgba(0,51,51,0.2)', paddingBottom: 12, marginBottom: 8 }}>
        <div style={{ fontFamily: '"Lobster", serif', fontSize: 30, color: '#003333' }}>
          {BOOK_FR[book] || book} {chapter}
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <div style={{ fontSize: 12, letterSpacing: '0.25em', color: '#9c948a', textTransform: 'uppercase' }}>
            {isOT ? 'AT · Hébreu · LSG' : 'NT · Grec · LSG'}
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 4, background: 'rgba(0,51,51,0.07)',
            borderRadius: 8, padding: '3px 8px' }}>
            <button onClick={() => adjSize(-2)}
              style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 16,
                color: '#003333', lineHeight: 1, padding: '0 3px', fontWeight: 600 }}>−</button>
            <span style={{ fontSize: 11, color: '#9c948a', minWidth: 28, textAlign: 'center' }}>{fontSize}px</span>
            <button onClick={() => adjSize(2)}
              style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 16,
                color: '#003333', lineHeight: 1, padding: '0 3px', fontWeight: 600 }}>+</button>
          </div>
        </div>
      </div>

      {/* Versets */}
      <div style={{ flex: 1, overflowY: 'auto', overflowX: 'hidden', paddingRight: 6 }}>
        {nbV === 0 && <div style={{ color: '#9c948a', padding: 20 }}>Chapitre indisponible.</div>}
        {rows.map((row) => {
          const second = hasSecondCol(row);
          const frWords = row.fr.split(' ');
          return (
            <div key={row.v}
              style={{ display: 'grid', gridTemplateColumns: second ? '1fr 1fr' : '1fr',
                gap: 36, padding: '14px 0', borderBottom: '1px solid rgba(0,51,51,0.08)',
                position: 'relative',
                opacity: active === row.v ? 1 : 0.5, transition: 'opacity 200ms' }}>
              {/* numéro de verset */}
              <div onClick={() => onSelectVerse(row.v)}
                style={{ position: 'absolute', left: second ? '50%' : -2, top: 16,
                  transform: second ? 'translateX(-50%)' : 'none',
                  width: 30, height: 30, borderRadius: '50%', cursor: 'pointer',
                  background: active === row.v ? '#fbb03b' : '#fff',
                  border: '1px solid rgba(0,51,51,0.25)', color: active === row.v ? '#fff' : '#003333',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  fontFamily: '"Lobster", serif', fontSize: 14, zIndex: 2 }}>{row.v}</div>

              {/* ——— Colonne gauche : Français ——— */}
              <div style={{ fontSize, lineHeight: 1.6, color: '#003333',
                paddingRight: second ? 26 : 44, paddingLeft: second ? 0 : 44, alignSelf: 'center' }}>
                {/* OT : clic verset entier */}
                {isOT && (
                  <span onClick={() => onSelectVerse(row.v)} style={{ cursor: 'pointer' }}>
                    {row.fr}
                  </span>
                )}
                {/* NT : chaque mot → Strong's du mot grec correspondant (mapping positionnel) */}
                {!isOT && frWords.map((mot, wi) => (
                  <span key={wi}
                    onClick={(e) => ntWordClick(row, wi, frWords.length, e)}
                    style={{ cursor: row.gr ? 'pointer' : 'default', borderRadius: 3, padding: '0 2px' }}
                    onMouseEnter={(e) => { if (row.gr) e.currentTarget.style.background = 'rgba(251,176,59,0.25)'; }}
                    onMouseLeave={(e) => { e.currentTarget.style.background = 'transparent'; }}>
                    {mot}{' '}
                  </span>
                ))}
              </div>

              {/* ——— Colonne droite : Hébreu OT (clic mot → Strong's H) ——— */}
              {row.heb && (
                <div dir="rtl" style={{ fontFamily: '"Times New Roman", "Times", "Frank Ruhl Libre", "Noto Serif Hebrew", serif',
                  fontSize: hebSize, lineHeight: 1.7, color: '#003333', textAlign: 'right', paddingRight: 26 }}>
                  {row.heb.map((pair, i) => {
                    const word = pair[0], code = pair[1];
                    return (
                      <span key={i}
                        onClick={(e) => { e.stopPropagation(); onSelectVerse(row.v); if (code) setStrong({ code, word }); }}
                        style={{ cursor: code ? 'pointer' : 'default', padding: '0 2px', borderRadius: 4,
                          opacity: code ? 1 : 0.45 }}
                        onMouseEnter={(e) => { if (code) e.currentTarget.style.background = 'rgba(251,176,59,0.25)'; }}
                        onMouseLeave={(e) => { e.currentTarget.style.background = 'transparent'; }}>
                        {word}{' '}
                      </span>
                    );
                  })}
                  <span style={{ opacity: 0.5, fontSize: hebSize * 0.85 }}>׃</span>
                </div>
              )}

              {/* ——— Colonne droite : Hébreu NT (traduction Delitzsch, RTL) ——— */}
              {row.hebNt && (
                <div dir="rtl" onClick={() => onSelectVerse(row.v)}
                  style={{ fontFamily: '"Times New Roman", "Times", "Frank Ruhl Libre", "Noto Serif Hebrew", serif',
                    fontSize: hebSize, lineHeight: 1.75, color: '#003333', textAlign: 'right',
                    paddingRight: 26, alignSelf: 'center', cursor: 'pointer' }}>
                  {row.hebNt}
                  <span style={{ opacity: 0.4, fontSize: hebSize * 0.85 }}> ׃</span>
                </div>
              )}
            </div>
          );
        })}
      </div>

      {strong && <StrongPopup code={strong.code} word={strong.word} onClose={() => setStrong(null)} />}
    </div>
  );
}

// Fenêtre Strong's — hébreu (H-codes) ou grec (G-codes)
function StrongPopup({ code, word, onClose }) {
  const e = bibleStrongEntry(code);
  const isGreek = String(code || '').toUpperCase().startsWith('G');
  const wordFont = isGreek
    ? '"Times New Roman", "Times", "GFS Didot", "Noto Serif", serif'
    : '"Times New Roman", "Times", "Frank Ruhl Libre", "Noto Serif Hebrew", serif';
  const rootFont = isGreek ? wordFont
    : '"Times New Roman", "Times", "Frank Ruhl Libre", "Noto Serif Hebrew", serif';
  return (
    <div style={{ position: 'absolute', left: 40, right: 56, bottom: 18, zIndex: 50,
      background: '#003333', color: '#fff', borderRadius: 14, padding: '16px 20px',
      boxShadow: '0 18px 50px rgba(0,0,0,0.4)', border: '1px solid rgba(251,176,59,0.4)' }}>
      <button onClick={onClose} style={{ position: 'absolute', top: 10, right: 12, background: 'transparent',
        border: 0, color: 'rgba(255,255,255,0.6)', fontSize: 18, cursor: 'pointer' }}>✕</button>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 14, flexWrap: 'wrap', marginBottom: 6 }}>
        <span dir={isGreek ? 'ltr' : 'rtl'} style={{ fontFamily: wordFont, fontSize: 32 }}>{word}</span>
        <span style={{ background: 'rgba(251,176,59,0.18)', color: '#fbb03b', padding: '2px 10px',
          borderRadius: 6, fontSize: 14, letterSpacing: '0.08em' }}>{code}</span>
        {e && e.h && (
          <span style={{ display: 'inline-flex', alignItems: 'baseline', gap: 6 }}>
            <span style={{ fontSize: 10, color: 'rgba(255,255,255,0.5)', textTransform: 'uppercase', letterSpacing: '0.15em' }}>racine</span>
            <span dir={isGreek ? 'ltr' : 'rtl'} style={{ fontFamily: rootFont, fontSize: 26, color: '#fbb03b' }}>{e.h}</span>
          </span>
        )}
        {e && e.m && <span style={{ fontStyle: 'italic', color: 'rgba(255,255,255,0.85)' }}>{e.m}</span>}
        {e && e.p && <span style={{ fontSize: 13, color: 'rgba(255,255,255,0.55)' }}>/{e.p}/</span>}
        {e && e.t && <span style={{ fontSize: 11, color: '#fbb03b', textTransform: 'uppercase',
          letterSpacing: '0.1em', marginLeft: 'auto' }}>{e.t}</span>}
      </div>
      {e ? (
        <>
          {e.def && <div style={{ fontSize: 15, lineHeight: 1.5, whiteSpace: 'pre-wrap',
            maxHeight: 150, overflowY: 'auto' }}>{e.def}</div>}
          {e.lsg && <div style={{ fontSize: 12.5, color: 'rgba(255,255,255,0.7)', marginTop: 8 }}>
            <strong style={{ color: '#fbb03b' }}>LSG : </strong><em>{e.lsg}</em></div>}
          {e.o && <div style={{ fontSize: 11, color: 'rgba(255,255,255,0.4)', marginTop: 4 }}>
            Origine : {e.o}</div>}
        </>
      ) : <div style={{ color: 'rgba(255,255,255,0.6)' }}>Définition Strong's indisponible pour {code}.</div>}
    </div>
  );
}

// ============ Navigation (panneau réglages) ============
function BibleNav({ book, setBook, chapter, setChapter, ready, onGo }) {
  const [q, setQ] = React.useState('');
  const idx = BIBLE_INDEX || {};
  const nbCh = (idx[book] && idx[book].chapters) || 1;
  const doSearch = () => {
    const r = parseBibleSearch(q);
    if (!r) { alert('Référence non reconnue. Essaie « Jean 3:16 » ou « Genèse 1 ».'); return; }
    onGo(r.osis, r.chapter, r.verse);
  };
  return (
    <div className="sp-section">
      <div className="sp-sec-title">Bible</div>
      {!ready && <div className="sp-help">Chargement de la Bible… (un instant au premier usage)</div>}
      <div className="sp-row col">
        <span className="sp-lbl">Rechercher un passage</span>
        <div style={{ display: 'flex', gap: 8 }}>
          <input className="sp-input" value={q} onChange={e => setQ(e.target.value)}
            onKeyDown={e => { if (e.key === 'Enter') doSearch(); }} placeholder="ex. Jean 3:16" />
          <button className="sp-btn" onClick={doSearch}>Aller</button>
        </div>
      </div>
      <div className="sp-row col">
        <span className="sp-lbl">Livre</span>
        <select className="sp-select" value={book} onChange={e => setBook(e.target.value)}>
          <optgroup label="Ancien Testament">
            {BIBLE_BOOKS.slice(0, 39).map(b => <option key={b[0]} value={b[0]}>{b[1]}</option>)}
          </optgroup>
          <optgroup label="Nouveau Testament">
            {BIBLE_BOOKS.slice(39).map(b => <option key={b[0]} value={b[0]}>{b[1]}</option>)}
          </optgroup>
        </select>
      </div>
      <div className="sp-row">
        <span className="sp-lbl">Chapitre</span>
        <select className="sp-select" style={{ width: 100 }} value={chapter}
          onChange={e => setChapter(+e.target.value)}>
          {Array.from({ length: nbCh }).map((_, i) => <option key={i + 1} value={i + 1}>{i + 1}</option>)}
        </select>
      </div>
      <div className="sp-help">
        Clique un <strong>mot hébreu</strong> (AT) ou <strong>mot grec</strong> (NT) pour voir son <strong>Strong's en français</strong>.
        Flèches ← / → pour changer de verset.
      </div>
    </div>
  );
}

Object.assign(window, { BIBLE_BOOKS, BOOK_FR, OT_SET, isNTBook, loadBibleData, buildBibleIndex,
  parseBibleSearch, bibleStrongEntry, BibleBoard, StrongPopup, BibleNav });
