// Hymnal tab — projection view (mirrors the Slides layout): a black projection
// stage on the left showing the extracted hymn lyrics verse-by-verse, and a
// searchable list of the hymn database on the right. Read-only database
// (window.HYMNAL_DB, extracted from the PowerPoint hymn files).
function HymnalTab({ active, canPlan=false, edits={}, setEdits }){
  const db = window.HYMNAL_DB || { hymns: [] };
  const hymns = db.hymns || [];

  // Scenic backgrounds — one assigned per hymn (stable per hymn, varies song to song).
  const BGS = ['bg01','bg02','bg03','bg04','bg05','bg06','bg07','bg08','bg09','bg10','bg11','bg12','bg13','bg14','bg15','bg16','bg17','bg18','bg19','bg20','bg21','bg22','bg23','bg24','bg25','bg26','bg27','bg28','bg29','bg30','bg31','bg32','bg33','bg34','bg35','bg36','bg37','bg38','bg39','bg40','bg41','bg42','bg43','bg44','bg45','bg46','bg47','bg48','bg49','bg50']
    .map(n => 'app/bg/'+n+'.jpg');

  const [sel, setSel] = React.useState(0);   // index into hymns
  const [vi, setVi]   = React.useState(0);   // position within the play sequence
  const [q, setQ]     = React.useState('');

  // "Planned" setlist — hymns chosen for a specific service, kept as an ORDERED
  // list of hymn numbers so the worship team can arrange the sequence. It never
  // alters the read-only hymnal database; add / remove / reorder only edit this list.
  const [plannedList, setPlannedList] = React.useState(()=>{
    try{ const a = JSON.parse(localStorage.getItem('cwa-hymnal-planned')||'[]'); return Array.isArray(a)?a:[]; }catch(e){ return []; }
  });
  const plannedSet = React.useMemo(()=> new Set(plannedList), [plannedList]);
  const [plannedViewRaw, setPlannedView] = React.useState(false);
  const plannedView = canPlan && plannedViewRaw; // Planned is an admin-only tool
  React.useEffect(()=>{ localStorage.setItem('cwa-hymnal-planned', JSON.stringify(plannedList)); }, [plannedList]);
  const togglePlan = (h)=> setPlannedList(prev=> prev.includes(h.number) ? prev.filter(n=>n!==h.number) : [...prev, h.number]);
  const movePlan = (num, dir)=> setPlannedList(prev=>{ const a=[...prev]; const i=a.indexOf(num); const j=i+dir; if(i<0||j<0||j>=a.length) return prev; [a[i],a[j]]=[a[j],a[i]]; return a; });
  const clearPlan = ()=>{ if(window.confirm('Clear all planned hymns? This only empties the plan — your hymnal is untouched.')) setPlannedList([]); };
  // fontScale is a COMFORT multiplier on top of the auto-fit: 1 = fill the
  // stage edge-to-edge, lower = leave a margin. The auto-fit itself sizes the
  // lyrics to whatever screen runs the app (phone → tablet → desktop → 4K TV),
  // so this only nudges how big they sit within that space.
  const [fontScale, setFontScale] = React.useState(()=>{ let v=parseFloat(localStorage.getItem('cwa-hymnal-fs')||'0.92'); if(!(v>0)) v=0.92; return Math.min(1,Math.max(0.55,v)); });
  const [repeatChorus, setRepeatChorus] = React.useState(()=> localStorage.getItem('cwa-hymnal-repeat')!=='0');
  const [showWords, setShowWords] = React.useState(false);   // full-lyrics reading view
  const [editing, setEditing] = React.useState(false);      // edit-words mode
  const [draft, setDraft] = React.useState([]);             // working copy while editing
  const bump = (d)=> setFontScale(s=>{ const v=Math.min(1,Math.max(0.55,+(s+d).toFixed(2))); localStorage.setItem('cwa-hymnal-fs', v); return v; });
  React.useEffect(()=>{ localStorage.setItem('cwa-hymnal-repeat', repeatChorus?'1':'0'); }, [repeatChorus]);

  const baseHymn = hymns[sel] || null;
  // Merge any saved edits (config.hymnalEdits, keyed by hymn number) over the
  // read-only database, so edited words project and read everywhere.
  const hymn = React.useMemo(()=>{
    if(!baseHymn) return null;
    const e = edits && edits[baseHymn.number];
    return (e && Array.isArray(e.verses)) ? { ...baseHymn, verses: e.verses } : baseHymn;
  }, [baseHymn, edits]);
  const isEdited = !!(baseHymn && edits && edits[baseHymn.number]);
  // pick a background by hymn number so each hymn keeps its own scene
  const bgUrl = hymn ? BGS[((hymn.number || sel) % BGS.length + BGS.length) % BGS.length] : null;

  // Build the order the hymn is actually SUNG. Every hymn opens with a TITLE page
  // (number · title · author), then the verses. When a hymn has exactly one chorus,
  // project it again after every verse (Title → Verse 1 → Chorus → Verse 2 → Chorus …).
  // If the chorus is already repeated, or there are several choruses, keep the source order.
  const isChorus = (v)=> !!v && (v.type==='chorus' || /chorus|refrain/i.test(v.label||''));
  const verses = React.useMemo(()=>{
    if(!hymn) return [];
    const titlePage = { _title:true, label:'', lines:[] };
    const items = hymn.verses || [];
    let body = items;
    if(repeatChorus){
      const choruses   = items.filter(isChorus);
      const versesOnly = items.filter(v=>!isChorus(v));
      if(choruses.length === 1 && versesOnly.length >= 1){
        const c = choruses[0];
        body = [];
        versesOnly.forEach(v=>{ body.push(v); body.push(c); });
      }
    }
    return [titlePage, ...body];
  }, [hymn, repeatChorus]);

  const count = verses.length;
  const verse = verses[Math.min(vi, Math.max(0,count-1))] || null;

  // keep latest count for the keyboard handler without re-binding constantly
  const countRef = React.useRef(count);
  countRef.current = count;

  // clamp position if the sequence length changes (e.g. toggling chorus repeat)
  React.useEffect(()=>{ setVi(v=> Math.min(v, Math.max(0,count-1))); }, [count]);
  // always start at the TITLE slide (index 0) whenever the shown hymn changes —
  // keyed on the hymn number so re-selecting or editing the same hymn also
  // snaps back to the Title, not wherever we last were.
  React.useEffect(()=>{ setVi(0); setEditing(false); }, [sel, hymn && hymn.number]);

  // Auto-fit: scale the verse to fit the stage's SAFE area — i.e. the band
  // between the title row (top) and the nav controls (bottom) — so the lyrics
  // never overlap or get clipped by the chrome, on any screen size.
  const stageRef = React.useRef(null);
  const innerRef = React.useRef(null);
  const safeRef  = React.useRef(null);
  const measureRef = React.useRef(null);
  React.useEffect(()=>()=>{ if(measureRef.current){ measureRef.current.remove(); measureRef.current=null; } }, []);
  const [isStageFs, setIsStageFs] = React.useState(false);
  React.useLayoutEffect(()=>{
    const esc = (s)=> String(s==null?'':s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
    const verseHTML = (v)=>{
      if(v && v._title){
        return '<div class="proj-title">'
          + (hymn && hymn.number!=null ? '<div class="proj-tkicker">Hymn '+esc(hymn.number)+'</div>' : '')
          + '<div class="proj-ttitle">'+esc(hymn?hymn.title:'')+'</div>'
          + (hymn && hymn.author ? '<div class="proj-tauthor">'+esc(hymn.author)+'</div>' : '')
          + '</div>';
      }
      const lines = ((v&&v.lines)||[]).map(ln=> '<div class="pline">'+(ln?esc(ln):'\u00a0')+'</div>').join('');
      return '<div class="proj-label">'+esc(v&&v.label)+'</div><div class="proj-lines">'+lines+'</div>';
    };
    const fit = ()=>{
      const safe = safeRef.current, inner = innerRef.current;
      if(!safe || !inner) return;
      inner.style.transform = 'scale(1)';
      const availH = safe.clientHeight, availW = safe.clientWidth;
      if(availH<=0 || availW<=0) return;
      // Measure EVERY slide of this hymn in a hidden clone so all the verses
      // share ONE size — the text stays uniform as you move through the hymn.
      // (Each hymn still gets its own size; the title slide fits on its own.)
      let m = measureRef.current;
      if(!m || m.parentNode!==safe){ if(m) m.remove(); m=document.createElement('div'); m.className='proj-inner'; m.style.cssText='position:absolute;left:-99999px;top:0;visibility:hidden;pointer-events:none;transform:none'; safe.appendChild(m); measureRef.current=m; }
      let fillVerses = Infinity, fillTitle = null;
      for(const v of verses){
        m.innerHTML = verseHTML(v);
        const nH = m.scrollHeight, nW = m.scrollWidth;
        if(nH<=0 || nW<=0) continue;
        const f = Math.min(availH/nH, availW/nW);
        if(v && v._title) fillTitle = f; else fillVerses = Math.min(fillVerses, f);
      }
      let fill;
      if(verse && verse._title) fill = (fillTitle!=null ? fillTitle : (isFinite(fillVerses)?fillVerses:1));
      else fill = isFinite(fillVerses) ? fillVerses : (fillTitle!=null?fillTitle:1);
      if(!(fill>0)){ const nH=inner.scrollHeight,nW=inner.scrollWidth; fill=(nH>0&&nW>0)?Math.min(availH/nH,availW/nW):1; }
      const hardMax = isStageFs ? 7 : 6;                 // sanity cap for 1–2 word slides
      let s = Math.min(fill * fontScale, fill * 0.98, hardMax);
      s = Math.max(0.06, s);
      inner.style.transform = 'scale('+s+')';
    };
    fit();
    requestAnimationFrame(fit);
    // re-fit after the serif web-font loads (changes text height) and on resize
    const t1 = setTimeout(fit, 120);
    const t2 = setTimeout(fit, 600);
    if(document.fonts && document.fonts.ready) document.fonts.ready.then(fit).catch(()=>{});
    window.addEventListener('resize', fit);
    let ro = null;
    if(window.ResizeObserver && safeRef.current){ ro = new ResizeObserver(fit); ro.observe(safeRef.current); }
    return ()=>{ clearTimeout(t1); clearTimeout(t2); window.removeEventListener('resize', fit); if(ro) ro.disconnect(); };
  }, [sel, vi, fontScale, active, count, repeatChorus, isStageFs, verses]);

  // Auto-hide the on-screen chrome (title + buttons + nav) so the lyrics own the
  // screen. Any tap, pointer move, or navigation reveals it again for a few seconds.
  const [chrome, setChrome] = React.useState(true);
  const hideTimer = React.useRef(null);
  const revealChrome = React.useCallback(()=>{
    setChrome(true);
    clearTimeout(hideTimer.current);
    hideTimer.current = setTimeout(()=> setChrome(false), 3500);
  }, []);
  React.useEffect(()=>{ if(active) revealChrome(); else { clearTimeout(hideTimer.current); setChrome(true); } }, [active, sel, vi, revealChrome]);
  React.useEffect(()=>()=> clearTimeout(hideTimer.current), []);

  // Project the stage by itself, full screen (hides list + header).
  function toggleStageFs(){
    const el = stageRef.current;
    if(!el) return;
    const cur = document.fullscreenElement || document.webkitFullscreenElement;
    if(cur){ (document.exitFullscreen || document.webkitExitFullscreen || function(){}).call(document); }
    else { (el.requestFullscreen || el.webkitRequestFullscreen || function(){}).call(el); }
  }
  React.useEffect(()=>{
    const on = ()=> setIsStageFs(!!(document.fullscreenElement || document.webkitFullscreenElement));
    document.addEventListener('fullscreenchange', on);
    document.addEventListener('webkitfullscreenchange', on);
    return ()=>{ document.removeEventListener('fullscreenchange', on); document.removeEventListener('webkitfullscreenchange', on); };
  }, []);

  const filtered = React.useMemo(()=>{
    const s = q.trim().toLowerCase();
    const match = (h)=> !s || (h.title||'').toLowerCase().includes(s) || String(h.number)===s || String(h.number).startsWith(s);
    if(plannedView){
      // keep the planned ORDER so the team sees their service sequence
      return plannedList
        .map(num=>{ const i = hymns.findIndex(h=>h.number===num); return i>=0 ? { h:hymns[i], i } : null; })
        .filter(it=> it && match(it.h));
    }
    return hymns.map((h,i)=>({ h, i })).filter(({h})=> match(h));
  }, [q, hymns, plannedView, plannedList]);

  function pick(i){ setSel(i); setVi(0); }
  const go = (n)=> setVi(Math.min(Math.max(n,0), Math.max(0,count-1)));
  // From the full-lyrics view, tap a verse to project it on the stage.
  const jumpToVerse = (v)=>{ const i = verses.indexOf(v); setVi(i>=0?i:0); setShowWords(false); revealChrome(); };
  // ----- Edit the words of the selected hymn (admin) -----
  const startEdit = ()=>{ setDraft((hymn.verses||[]).map(v=>({ label:v.label||'', text:(v.lines||[]).join('\n') }))); setEditing(true); };
  const cancelEdit = ()=> setEditing(false);
  const saveEdit = ()=>{
    if(!hymn || !setEdits) return;
    const v = draft
      .map(d=>({ type:/chorus|refrain/i.test(d.label)?'chorus':'verse', label:(d.label||'').trim(), lines:(d.text||'').replace(/\r/g,'').split('\n') }))
      .filter(x=> x.label || x.lines.some(l=>l.trim()));
    setEdits(prev=>({ ...(prev||{}), [hymn.number]: { verses:v } }));
    setEditing(false);
    setVi(0);   // return to the Title slide after editing the words
  };
  const resetEdit = ()=>{ if(!hymn || !setEdits) return; setEdits(prev=>{ const n={ ...(prev||{}) }; delete n[hymn.number]; return n; }); setEditing(false); };
  // Renumber only verse labels (Verse 1, 2, 3…) by their order; leave choruses,
  // refrains and any custom labels exactly as the user named them.
  const renumber = (arr)=>{ let n=0; return arr.map(d=>{ const lab=d.label||''; if(/chorus|refrain/i.test(lab)) return d; if(/^\s*verse\b/i.test(lab)){ n++; return { ...d, label:'Verse '+n }; } return d; }); };
  const dUpd  = (i,patch)=> setDraft(d=> d.map((x,k)=> k===i?{ ...x, ...patch }:x));
  const dAdd  = ()=> setDraft(d=> renumber([...d, { label:'Verse 0', text:'' }]));
  const dDel  = (i)=> setDraft(d=> renumber(d.filter((_,k)=> k!==i)));
  const dMove = (i,dir)=> setDraft(d=>{ const a=[...d]; const j=i+dir; if(j<0||j>=a.length) return d; [a[i],a[j]]=[a[j],a[i]]; return renumber(a); });

  // PowerPoint-style keyboard navigation (only while this tab is open)
  React.useEffect(()=>{
    if(!active) return;
    const onKey = (e)=>{
      if(/input|textarea|select/i.test(e.target.tagName) || e.target.isContentEditable) return;
      const c = countRef.current;
      const nav = ()=> revealChrome();
      if(e.key==='ArrowRight'||e.key==='PageDown'||e.key==='ArrowDown'||e.key===' '||e.key==='Enter'){ e.preventDefault(); setVi(p=>Math.min(c-1,p+1)); nav(); }
      else if(e.key==='ArrowLeft'||e.key==='PageUp'||e.key==='ArrowUp'){ e.preventDefault(); setVi(p=>Math.max(0,p-1)); nav(); }
      else if(e.key==='Home'){ e.preventDefault(); setVi(0); nav(); }
      else if(e.key==='End'){ e.preventDefault(); setVi(c-1); nav(); }
    };
    window.addEventListener('keydown', onKey);
    return ()=> window.removeEventListener('keydown', onKey);
  }, [active]);

  return (
    <div className="hymnal-proj">
      <div className={'proj-stage'+(chrome?'':' chrome-hidden')} ref={stageRef}
        onPointerMove={revealChrome} onTouchStart={revealChrome} onClick={revealChrome}>
        {bgUrl && <div className="proj-bg" style={{backgroundImage:'url("'+bgUrl+'")'}}></div>}
        <div className="proj-scrim"></div>
        {hymn && <div className="proj-top proj-chrome">{hymn.number} &middot; {hymn.title}{hymn.author?'  —  '+hymn.author:''}</div>}

        {verse ? (
          <div className="proj-safe" ref={safeRef}>
            <div className="proj-inner" ref={innerRef}>
              {verse._title ? (
                <div className="proj-title">
                  {hymn && hymn.number!=null && <div className="proj-tkicker">Hymn {hymn.number}</div>}
                  <div className="proj-ttitle">{hymn ? hymn.title : ''}</div>
                  {hymn && hymn.author && <div className="proj-tauthor">{hymn.author}</div>}
                </div>
              ) : (
                <React.Fragment>
                  <div className="proj-label">{verse.label}</div>
                  <div className="proj-lines">
                    {verse.lines.map((ln,i)=>(<div className="pline" key={i}>{ln || '\u00a0'}</div>))}
                  </div>
                </React.Fragment>
              )}
            </div>
          </div>
        ) : (
          <div className="proj-empty">Select a hymn from the list to project its words.</div>
        )}

        {/* Full-lyrics reading view — all verses of the selected hymn, scrollable.
            Tap any verse to project it. */}
        {showWords && hymn && (
          <div className="proj-words" onClick={(e)=>e.stopPropagation()}>
            <div className="pw-head">
              <span className="pw-title">{hymn.number} &middot; {hymn.title}{isEdited && <em className="pw-edited"> &middot; edited</em>}</span>
              <span className="pw-hint">Tap a verse to project it</span>
              {canPlan && setEdits && <button className="pw-edit-btn" onClick={startEdit} title="Edit the words of this hymn"><Icon name="edit" size={14}/> Edit</button>}
              <button className="pw-x" onClick={()=>setShowWords(false)} title="Close" aria-label="Close words view">{'\u00d7'}</button>
            </div>
            <div className="pw-inner">
              {(hymn.verses||[]).map((v,i)=>(
                <div className="pw-verse" key={i} onClick={()=>jumpToVerse(v)}>
                  {v.label && <div className="pw-label">{v.label}</div>}
                  {(v.lines||[]).map((ln,j)=>(<div className="pw-line" key={j}>{ln || '\u00a0'}</div>))}
                </div>
              ))}
            </div>
          </div>
        )}

        {/* Tap zones (touch devices): left half = previous, right half = next.
            Sit above the lyrics (z-2) but below the chrome buttons (z-3) so the
            on-screen controls still work. Hidden on hover/mouse desktops. */}
        {count>1 && (
          <React.Fragment>
            <button className="proj-tap proj-tap-prev" aria-label="Previous verse"
              onClick={(e)=>{ e.stopPropagation(); setVi(p=>Math.max(0,p-1)); revealChrome(); }}></button>
            <button className="proj-tap proj-tap-next" aria-label="Next verse"
              onClick={(e)=>{ e.stopPropagation(); setVi(p=>Math.min(countRef.current-1,p+1)); revealChrome(); }}></button>
          </React.Fragment>
        )}

        <div className="proj-font proj-chrome">
          <button className={'proj-toggle'+(showWords?' on':'')} onClick={()=>setShowWords(x=>!x)} title="Show the full words of this hymn"><Icon name="list" size={15}/> Words</button>
          <button className={'proj-toggle'+(repeatChorus?' on':'')} onClick={()=>setRepeatChorus(x=>!x)} title="Repeat the chorus after every verse">{'\u21bb'} Chorus</button>
          <button onClick={()=>bump(-0.07)} title="Smaller text" aria-label="Smaller text">A&#8722;</button>
          <button onClick={()=>bump(0.07)} title="Larger text" aria-label="Larger text">A+</button>
          <button className="proj-fs" onClick={toggleStageFs} title={isStageFs?'Exit full screen (Esc)':'Project full screen'} aria-label="Full screen"><Icon name="expand" size={17}/></button>
        </div>

        {count>0 && (
          <div className="proj-ctrls proj-chrome">
            <button onClick={()=>go(vi-1)} disabled={vi===0} title="Previous verse">&lsaquo;</button>
            <span className="proj-count">{vi+1} / {count}</span>
            <button onClick={()=>go(vi+1)} disabled={vi>=count-1} title="Next verse">&rsaquo;</button>
          </div>
        )}
      </div>

      <aside className="hymnal-rail">
        <h3>
          Hymnal <span className="hymnal-count">{plannedView ? plannedList.length : hymns.length}</span>
          {canPlan && (
            <button className={'plan-btn'+(plannedView?' on':'')} onClick={()=>setPlannedView(v=>!v)}
              title={plannedView ? 'Show all hymns' : 'Show only planned hymns'}>
              <Icon name={plannedView?'bookmarkFill':'bookmark'} size={14}/>
              {plannedView ? 'All' : 'Planned'}
              {plannedList.length>0 && <span className="plan-ct">{plannedList.length}</span>}
            </button>
          )}
        </h3>
        <div className="hymnal-search">
          <Icon name="search" size={16}/>
          <input value={q} onChange={e=>setQ(e.target.value)} placeholder="Search by title or number…" />
          {q && <button className="hs-x" onClick={()=>setQ('')} title="Clear">{'\u00d7'}</button>}
        </div>
        {plannedView && (
          <div className="plan-bar">
            <span>{plannedList.length} planned{plannedList.length>1 ? ' · reorder with ↑↓' : ' for this service'}</span>
            {plannedList.length>0 && <button onClick={clearPlan} title="Remove every hymn from the plan"><Icon name="trash" size={14}/> Clear all</button>}
          </div>
        )}
        <div className="hymnal-list">
          {filtered.length===0 && <div className="hymnal-none">{plannedView ? (q ? 'No planned hymns match “'+q+'”.' : 'No hymns planned yet. Tap the bookmark on any hymn to add it here.') : 'No hymns match “'+q+'”.'}</div>}
          {filtered.map(({h,i},idx)=>{
            const isPlanned = plannedSet.has(h.number);
            const canReorder = plannedView && !q.trim();
            return (
            <div key={i} className={'hymn-row'+(i===sel?' playing':'')} onClick={()=>pick(i)}>
              <span className="ix">{plannedView ? idx+1 : h.number}</span>
              <span className="nm">{h.title}</span>
              <span className="vc">{h.verses.length}</span>
              {canReorder && (
                <span className="plan-move" onClick={e=>e.stopPropagation()}>
                  <button disabled={idx===0} title="Move up" onClick={(e)=>{ e.stopPropagation(); movePlan(h.number,-1); }}><Icon name="chevUp" size={15}/></button>
                  <button disabled={idx===filtered.length-1} title="Move down" onClick={(e)=>{ e.stopPropagation(); movePlan(h.number,1); }}><Icon name="chevDown" size={15}/></button>
                </span>
              )}
              {canPlan && (
                <button className={'plan-tog'+(isPlanned?' on':'')} title={isPlanned?'Remove from planned':'Add to planned'}
                  onClick={(e)=>{ e.stopPropagation(); togglePlan(h); }}>
                  <Icon name={isPlanned?'bookmarkFill':'bookmark'} size={15}/>
                </button>
              )}
            </div>
          );})}
        </div>
      </aside>

      {editing && hymn && (
        <div className="hymned-scrim" onClick={(e)=>{ if(e.currentTarget===e.target) cancelEdit(); }}>
          <div className="hymned">
            <div className="hymned-head">
              <h3>Edit words &mdash; {hymn.number} &middot; {hymn.title}</h3>
              <button className="hymned-x" onClick={cancelEdit} aria-label="Close editor">{'\u00d7'}</button>
            </div>
            <div className="hymned-body">
              {draft.map((d,i)=>(
                <div className="hymned-verse" key={i}>
                  <div className="hymned-row">
                    <input className="hymned-label" value={d.label} onChange={(e)=>dUpd(i,{label:e.target.value})} placeholder="Label (e.g. Verse 1, Chorus)" />
                    <span className="hymned-move">
                      <button onClick={()=>dMove(i,-1)} disabled={i===0} title="Move up"><Icon name="chevUp" size={16}/></button>
                      <button onClick={()=>dMove(i,1)} disabled={i===draft.length-1} title="Move down"><Icon name="chevDown" size={16}/></button>
                      <button onClick={()=>dDel(i)} title="Delete verse"><Icon name="trash" size={16}/></button>
                    </span>
                  </div>
                  <textarea className="hymned-text" value={d.text} onChange={(e)=>dUpd(i,{text:e.target.value})} placeholder="One line per row…" />
                </div>
              ))}
              <button className="hymned-add" onClick={dAdd}><Icon name="plus" size={15}/> Add verse</button>
            </div>
            <div className="hymned-foot">
              {isEdited && <button className="hymned-reset" onClick={resetEdit}>Reset to original</button>}
              <span className="pw-spring"></span>
              <button className="hymned-cancel" onClick={cancelEdit}>Cancel</button>
              <button className="hymned-save" onClick={saveEdit}>Save changes</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
window.HymnalTab = HymnalTab;
