/* ============================================================
   AlphabetGrid — the full Cyrillic alphabet as a 3-column grid.
   Tap a tile to hear the letter's SOUND; tap its check to mark it
   learned. A progress bar tracks mastery and persists locally.
   ============================================================ */
(function () {
  const { useState, useRef, useEffect } = React;
  const A = window.APP;
  const KEY = 'ru_alpha_learned_v1';

  function AlphabetGrid({ nav }) {
    const letters = A.findLesson('alphabet').lesson.letters;
    const [learned, setLearned] = useState(() => {
      try { return JSON.parse(localStorage.getItem(KEY)) || {}; } catch (e) { return {}; }
    });
    const [active, setActive] = useState(null);
    const [tip, setTip] = useState(null);
    const [userId, setUserId] = useState(null);     // null = anonymous
    const [hint, setHint] = useState(false);        // non-blocking "sign in to save" hint
    const tRef = useRef(null);
    useEffect(() => () => clearTimeout(tRef.current), []);

    // 2026-06-05 7:25PM — when signed in, learned set is sourced from user_progress.
    // Falls back to localStorage for anonymous users. PENDING USER TESTING
    useEffect(() => {
      let live = true;
      (async () => {
        if (!window.sb) return;
        const { data } = await window.sb.auth.getUser();
        const id = data && data.user ? data.user.id : null;
        if (!live) return;
        setUserId(id);
        if (id) {
          const { data: rows, error } = await window.sb.from('user_progress')
            .select('item_key').eq('user_id', id).eq('item_type', 'letter').eq('status', 'learned');
          if (error) { console.error('[auth:alphabet] read', error.message); return; }
          if (!live) return;
          const map = {}; (rows || []).forEach(r => { map[r.item_key] = 1; });
          setLearned(map);
        }
      })();
      return () => { live = false; };
    }, []);

    const total = letters.length;
    const count = letters.filter(l => learned[l.ru]).length;

    const play = (l) => {
      setActive(l.ru); setTip(null);
      window.speakRU(l.say || l.low);
      clearTimeout(tRef.current);
      tRef.current = setTimeout(() => setActive(null), 850);
    };
    const toggle = (l, e) => {
      e.stopPropagation();
      const wasOn = !!learned[l.ru];
      setLearned(prev => {
        const n = { ...prev };
        if (n[l.ru]) delete n[l.ru]; else n[l.ru] = 1;
        try { localStorage.setItem(KEY, JSON.stringify(n)); } catch (er) {}
        return n;
      });
      if (userId && window.sb) {
        // persist to DB (upsert on add, delete on remove)
        if (wasOn) {
          window.sb.from('user_progress').delete().eq('user_id', userId).eq('item_type', 'letter').eq('item_key', l.ru)
            .then(({ error }) => { if (error) console.error('[auth:alphabet] delete', error.message); });
        } else {
          window.sb.from('user_progress').upsert(
            { user_id: userId, item_type: 'letter', item_key: l.ru, status: 'learned', completed_at: new Date().toISOString() },
            { onConflict: 'user_id,item_type,item_key' }
          ).then(({ error }) => { if (error) console.error('[auth:alphabet] upsert', error.message); });
        }
      } else if (!wasOn) {
        setHint(true); // anonymous user just earned progress — nudge to sign in (non-blocking)
      }
    };

    return (
      <div style={{ height:'100%', display:'flex', flexDirection:'column', background:'var(--bg)', position:'relative' }}>
        {/* header */}
        <div style={{ padding:'50px 18px 0', display:'flex', alignItems:'center', justifyContent:'space-between', gap:12 }}>
          <div style={{ display:'flex', alignItems:'center', gap:9 }}>
            <Emblem letter="А" color="oklch(0.78 0.13 72)" size={28} radius={9} />
            <span style={{ fontFamily:'"Hanken Grotesk",system-ui', fontWeight:700, fontSize:13.5,
              color:'oklch(0.62 0.13 65)' }}>Foundations</span>
          </div>
          <IconBtn kind="close" onClick={nav.back} />
        </div>
        <div style={{ padding:'10px 22px 12px' }}>
          <div style={{ fontFamily:'"Bricolage Grotesque",system-ui', fontWeight:800, fontSize:27,
            color:'var(--ink)', letterSpacing:'-0.02em' }}>The Alphabet</div>
          <div style={{ fontFamily:'"Hanken Grotesk",system-ui', fontWeight:600, fontSize:13,
            color:'var(--muted)', marginTop:2 }}>Tap to hear · check the ring to mark each learned</div>
          {/* progress */}
          <div style={{ display:'flex', alignItems:'center', gap:12, marginTop:12 }}>
            <div style={{ flex:1 }}><Bar value={count/total} color="oklch(0.72 0.14 72)" /></div>
            <span style={{ fontFamily:'"JetBrains Mono",monospace', fontWeight:700, fontSize:12.5,
              color:'var(--ink)', whiteSpace:'nowrap' }}>{count}<span style={{ color:'var(--muted)' }}>/{total} learned</span></span>
          </div>
        </div>

        {/* anonymous "sign in to save" hint — non-blocking, dismissible */}
        {hint && !userId && (
          <div style={{ margin:'2px 18px 8px', display:'flex', alignItems:'center', gap:10,
            background:'var(--primary-wash)', border:'1px solid var(--line)', borderRadius:14, padding:'10px 12px' }}>
            <span style={{ flex:1, fontFamily:'"Hanken Grotesk",system-ui', fontWeight:700, fontSize:12.5, color:'var(--primary-deep)' }}>
              Sign in to save your progress
            </span>
            <button onClick={() => nav.go('auth')} style={{ appearance:'none', border:'none', cursor:'pointer',
              background:'var(--primary)', color:'#fff', borderRadius:999, padding:'6px 12px',
              fontFamily:'"Hanken Grotesk",system-ui', fontWeight:800, fontSize:12 }}>Sign in</button>
            <button onClick={() => setHint(false)} aria-label="Dismiss" style={{ appearance:'none', border:'none', cursor:'pointer',
              background:'transparent', color:'var(--muted)', padding:'4px', display:'flex' }}>
              <svg width="16" height="16" viewBox="0 0 24 24"><path d="M6 6l12 12M18 6L6 18" stroke="currentColor" strokeWidth="2.2" fill="none" strokeLinecap="round"/></svg>
            </button>
          </div>
        )}

        {/* grid */}
        <div style={{ flex:1, minHeight:0, overflowY:'auto', padding:`2px 18px ${count >= total ? 92 : 48}px` }}>
          <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:8 }}>
            {letters.map((l, idx) => {
              const isOn = !!learned[l.ru];
              const isActive = active === l.ru;
              const noSound = l.lat === '—';
              const rightCol = idx % 2 === 1;
              const infoIcon = l.info ? (
                <span onClick={(e) => { e.stopPropagation(); setTip(tip === l.ru ? null : l.ru); }}
                  role="button" aria-label={`About ${l.ru}`}
                  style={{ width:15, height:15, borderRadius:999, flexShrink:0,
                    display:'inline-flex', alignItems:'center', justifyContent:'center',
                    border:`1.2px solid ${tip === l.ru ? 'var(--primary)' : 'var(--muted)'}`,
                    color: tip === l.ru ? 'var(--primary)' : 'var(--muted)',
                    fontFamily:'Georgia, serif', fontStyle:'italic', fontSize:10, fontWeight:700,
                    lineHeight:1, cursor:'pointer' }}>i</span>
              ) : null;
              return (
                <button key={l.ru} onClick={() => play(l)}
                  style={{ appearance:'none', cursor:'pointer', textAlign:'left', position:'relative',
                    background:'var(--surface)', borderRadius:15, padding:'10px 11px', minHeight:54,
                    border:`1.5px solid ${isActive ? 'var(--primary)' : (isOn ? 'oklch(0.80 0.11 150)' : 'var(--line)')}`,
                    boxShadow: isActive ? '0 8px 20px -10px var(--primary)' : '0 1px 0 var(--line)',
                    transition:'border-color .15s, box-shadow .15s, transform .1s',
                    transform: isActive ? 'translateY(-1px)' : 'none',
                    display:'flex', alignItems:'stretch', gap:11 }}>
                  {/* Cyrillic pair */}
                  <div style={{ display:'flex', alignItems:'baseline', gap:3, minWidth:40, alignSelf:'center' }}>
                    <span style={{ fontFamily:'"Golos Text",system-ui', fontWeight:600, fontSize:26,
                      color:'var(--ink)', lineHeight:1 }}>{l.ru}</span>
                    <span style={{ fontFamily:'"Golos Text",system-ui', fontWeight:500, fontSize:15,
                      color:'var(--muted)', lineHeight:1 }}>{l.low}</span>
                  </div>
                  <div style={{ width:1, alignSelf:'stretch', background:'var(--line)' }} />
                  {/* English letter + spoken name (signs show their name only) */}
                  <div style={{ display:'flex', flexDirection:'column', gap:2, minWidth:0, flex:1, alignSelf:'center' }}>
                    {noSound ? (
                      <span style={{ display:'flex', alignItems:'center', gap:6 }}>
                        <span style={{ fontFamily:'"Hanken Grotesk",system-ui', fontWeight:800, fontSize:15,
                          color:'var(--ink)', lineHeight:1.15 }}>{l.name}</span>
                        {infoIcon}
                      </span>
                    ) : (
                      <React.Fragment>
                        <span style={{ fontFamily:'"Hanken Grotesk",system-ui', fontWeight:800, fontSize:17,
                          color:'var(--ink)', lineHeight:1.05 }}>{l.lat}</span>
                        <span style={{ display:'flex', alignItems:'center', gap:5,
                          fontFamily:'"JetBrains Mono",monospace', fontSize:11, fontWeight:600,
                          color: isActive ? 'var(--primary-deep)' : 'oklch(0.55 0.1 65)', lineHeight:1.15 }}>
                          “{l.name}”
                          {infoIcon}
                        </span>
                      </React.Fragment>
                    )}
                  </div>
                  {/* controls: learned check (top) + speaker (bottom) */}
                  <div style={{ display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'space-between' }}>
                    <span onClick={(e) => toggle(l, e)} role="checkbox" aria-checked={isOn}
                      style={{ width:20, height:20, borderRadius:999, flexShrink:0,
                        display:'flex', alignItems:'center', justifyContent:'center',
                        background: isOn ? 'oklch(0.60 0.13 150)' : 'transparent',
                        border: isOn ? 'none' : '1.5px solid var(--line)', transition:'background .15s' }}>
                      {isOn && <svg width="12" height="12" viewBox="0 0 24 24"><path d="M5 13l4 4 10-11" stroke="#fff" strokeWidth="3" fill="none" strokeLinecap="round" strokeLinejoin="round"/></svg>}
                    </span>
                    <Speaker size={15} color={isActive ? 'var(--primary)' : 'var(--muted)'} playing={isActive} />
                  </div>
                  {/* info tooltip */}
                  {tip === l.ru && l.info && (
                    <div onClick={(e) => e.stopPropagation()}
                      style={{ position:'absolute', zIndex:20, width:200,
                        ...(noSound ? { bottom:'calc(100% - 6px)' } : { top:'calc(100% - 6px)' }),
                        ...(rightCol ? { right:12 } : { left:12 }),
                        background:'var(--ink)', color:'#fff', borderRadius:11, padding:'10px 12px',
                        fontFamily:'"Hanken Grotesk",system-ui', fontSize:11.5, fontWeight:600, lineHeight:1.42,
                        boxShadow:'0 14px 30px -8px rgba(40,20,10,0.55)' }}>
                      <span style={{ position:'absolute', width:10, height:10, background:'var(--ink)',
                        transform:'rotate(45deg)', borderRadius:2,
                        ...(noSound ? { bottom:-5 } : { top:-5 }),
                        ...(rightCol ? { right:20 } : { left:20 }) }} />
                      {l.info}
                    </div>
                  )}
                </button>
              );
            })}
          </div>
        </div>

        {/* footer — appears only once every letter is learned */}
        {count >= total && (
          <div style={{ position:'absolute', left:0, right:0, bottom:0, zIndex:5,
            padding:'12px 20px calc(20px + env(safe-area-inset-bottom))', borderTop:'1px solid var(--line)',
            background:'var(--bg)', animation:'footerRise .3s cubic-bezier(.2,.9,.3,1)' }}>
            <Btn full onClick={() => nav.go('complete', { lessonId:'alphabet', accuracy:100, learned:total })}>
              Mark lesson as complete
            </Btn>
          </div>
        )}
      </div>
    );
  }

  window.AlphabetGrid = AlphabetGrid;
})();
