// Shared gamified level shell — top entries bar, progress pill, back button, CTA

function PrimaryBtn({ children, onClick, color = '#140602', bg = '#FFC800', icon = true }) {
  const [p, setP] = React.useState(false);
  return (
    <button onClick={onClick}
      onTouchStart={() => setP(true)} onTouchEnd={() => setP(false)}
      onMouseDown={() => setP(true)} onMouseUp={() => setP(false)} onMouseLeave={() => setP(false)}
      style={{
        width: '100%', border: 'none', background: bg, color,
        padding: '18px 22px',
        fontFamily: 'Anton, Impact, sans-serif', fontSize: 22, letterSpacing: 2,
        borderRadius: 14, textTransform: 'uppercase', cursor: 'pointer',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        boxShadow: p ? `0 2px 0 ${color}` : `0 5px 0 ${color}, 0 10px 18px rgba(0,0,0,0.2)`,
        transform: p ? 'translateY(3px)' : 'translateY(0)',
        transition: 'all 80ms ease',
      }}>
      <span>{children}</span>
      {icon && (
        <svg width="22" height="22" viewBox="0 0 24 24">
          <path d="M8 12 h9 m-4 -4 l4 4 -4 4" stroke={color} strokeWidth="2.4" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
      )}
    </button>
  );
}

window.PrimaryBtn = PrimaryBtn;

function EntriesBar({ total, burst }) {
  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 8,
      padding: '5px 10px 5px 5px',
      background: 'rgba(20,6,2,0.85)',
      border: '1.5px solid rgba(247,147,26,0.5)',
      borderRadius: 100,
      position: 'relative',
    }}>
      <div style={{
        width: 26, height: 26, borderRadius: '50%', background: '#F7931A',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontFamily: 'Archivo Black', fontSize: 13, color: '#fff',
      }}>₿</div>
      <div style={{
        fontFamily: 'JetBrains Mono, monospace', fontSize: 10, letterSpacing: 1.4,
        color: 'rgba(255,232,166,0.7)',
      }}>ENTRIES</div>
      <div style={{
        fontFamily: 'Anton, sans-serif', fontSize: 18, letterSpacing: 1,
        color: '#FFC800', lineHeight: 1,
      }}>+{total}</div>
      {burst && (
        <div key={burst.k} style={{
          position: 'absolute', top: -28, right: 4,
          fontFamily: 'Anton, sans-serif', fontSize: 22, color: '#FFC800',
          textShadow: '0 2px 0 #140602',
          animation: 'entryBurst 1200ms ease-out forwards',
          pointerEvents: 'none',
        }}>+{burst.amount}</div>
      )}
    </div>
  );
}

function LevelShell({
  levelNum, totalLevels = 10, mood, textColor = '#140602',
  title, titleAccent, subtitle, children,
  onNext, onBack, ctaLabel = 'Continue', ctaBg = '#FFC800', ctaColor = '#140602',
  entries, burst,
  bingoPose = 'peek', bingoPos = 'br',
  decor,
}) {
  return (
    <div style={{
      position: 'absolute', inset: 0,
      background: mood,
      display: 'flex', flexDirection: 'column',
      overflow: 'hidden',
      color: textColor,
    }}>
      {decor}
      {/* top bar */}
      <div style={{
        position: 'relative', zIndex: 3,
        padding: '54px 16px 0 16px',
        display: 'flex', alignItems: 'center', gap: 10,
      }}>
        <button onClick={onBack} style={{
          width: 38, height: 38, borderRadius: '50%',
          border: `1.5px solid ${textColor === '#fff' ? 'rgba(255,255,255,0.4)' : 'rgba(20,6,2,0.4)'}`,
          background: 'transparent', cursor: 'pointer', flexShrink: 0,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <svg width="12" height="12" viewBox="0 0 14 14">
            <path d="M9 2 L3 7 L9 12" stroke={textColor} strokeWidth="2.2" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </button>
        <div style={{ flex: 1 }}/>
        <EntriesBar total={entries} burst={burst}/>
      </div>

      {/* progress + level tag */}
      <div style={{
        position: 'relative', zIndex: 3, padding: '16px 20px 0 20px',
      }}>
        <div style={{
          display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          fontFamily: 'JetBrains Mono, monospace', fontSize: 10.5, letterSpacing: 1.8,
          color: textColor, fontWeight: 600, marginBottom: 8,
        }}>
          <span>LEVEL {String(levelNum).padStart(2,'0')} / {String(totalLevels).padStart(2,'0')}</span>
          <span style={{ opacity: 0.55 }}>+{{1:1,2:1,3:2,4:3,5:3,6:2,7:1,8:1,9:1,10:2}[levelNum] || 1} ENTRIES</span>
        </div>
        <div style={{
          height: 8, background: textColor === '#fff' ? 'rgba(255,255,255,0.14)' : 'rgba(20,6,2,0.1)',
          borderRadius: 100, overflow: 'hidden', position: 'relative',
        }}>
          <div style={{
            width: `${(levelNum / totalLevels) * 100}%`, height: '100%', borderRadius: 100,
            background: 'linear-gradient(90deg, #FFC800 0%, #F7931A 100%)',
            transition: 'width 500ms cubic-bezier(.2,.8,.2,1)',
            boxShadow: '0 0 12px rgba(255,200,0,0.5)',
          }}/>
        </div>
      </div>

      {/* heading */}
      <div style={{ position: 'relative', zIndex: 3, padding: '18px 20px 6px 20px' }}>
        <h1 style={{
          margin: 0, fontFamily: 'Anton, Impact, sans-serif',
          fontSize: 38, lineHeight: 0.95, letterSpacing: -0.6,
          textTransform: 'uppercase',
        }}>
          {title}{titleAccent && <> <span style={{ color: titleAccent.color }}>{titleAccent.text}</span></>}
        </h1>
        {subtitle && <div style={{
          marginTop: 8, fontFamily: 'Inter, sans-serif', fontSize: 13.5,
          opacity: 0.75, lineHeight: 1.4,
        }}>{subtitle}</div>}
      </div>

      {/* scrollable body */}
      <div style={{
        position: 'relative', zIndex: 3, flex: 1, overflow: 'auto',
        padding: '14px 20px 12px 20px',
      }}>
        {children}
      </div>

      {/* CTA */}
      <div style={{ position: 'relative', zIndex: 3, padding: '8px 20px 28px 20px' }}>
        <PrimaryBtn onClick={onNext} bg={ctaBg} color={ctaColor}>{ctaLabel}</PrimaryBtn>
      </div>

      {/* Bingo */}
      {bingoPose && (
        <div style={{
          position: 'absolute', zIndex: 2,
          ...(bingoPos === 'br' ? { right: -14, bottom: 86 } : bingoPos === 'tr' ? { right: -10, top: 92 } : { left: -14, bottom: 86 }),
          transform: bingoPos === 'bl' ? 'rotate(-8deg)' : 'rotate(8deg)',
          opacity: 0.9,
        }}>
          <Bingo pose={bingoPose} size={82}/>
        </div>
      )}
    </div>
  );
}

// Chip used across chip-select levels
function Chip({ label, hint, selected, onClick, accent = '#FFC800', darkText = true }) {
  const [pressed, setPressed] = React.useState(false);
  return (
    <button onClick={onClick}
      onTouchStart={() => setPressed(true)} onTouchEnd={() => setPressed(false)}
      onMouseDown={() => setPressed(true)} onMouseUp={() => setPressed(false)} onMouseLeave={() => setPressed(false)}
      style={{
        padding: '11px 14px',
        background: selected ? accent : 'rgba(255,255,255,0.88)',
        color: '#140602',
        border: `2px solid ${selected ? '#140602' : 'rgba(20,6,2,0.12)'}`,
        borderRadius: 100, fontFamily: 'Inter, sans-serif', fontSize: 13.5, fontWeight: 600,
        cursor: 'pointer', display: 'inline-flex', alignItems: 'center', gap: 7,
        boxShadow: selected
          ? (pressed ? '0 1px 0 #140602' : '0 3px 0 #140602')
          : (pressed ? 'none' : '0 2px 0 rgba(20,6,2,0.08)'),
        transform: pressed ? 'translateY(2px) scale(0.97)' : `translateY(0) scale(${selected ? 1.03 : 1})`,
        transition: 'transform 120ms cubic-bezier(.3,1.6,.5,1), background 160ms, border-color 160ms',
      }}>
      {hint && <span style={{ fontSize: 15, filter: selected ? 'none' : 'grayscale(0.35)' }}>{hint}</span>}
      <span>{label}</span>
      {selected && (
        <span style={{
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          width: 16, height: 16, borderRadius: '50%', background: '#140602', marginLeft: 2,
        }}>
          <svg width="9" height="9" viewBox="0 0 10 10">
            <path d="M2 5 L4 7 L8 3" stroke={accent} strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </span>
      )}
    </button>
  );
}

function ChipGroup({ options, selected, setSelected, accent }) {
  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 7 }}>
      {options.map(o => {
        const id = typeof o === 'string' ? o : o.id;
        const label = typeof o === 'string' ? o : o.label;
        const hint = typeof o === 'string' ? null : o.hint;
        return (
          <Chip key={id} label={label} hint={hint}
            selected={selected.includes(id)}
            accent={accent}
            onClick={() => setSelected(selected.includes(id) ? selected.filter(x=>x!==id) : [...selected, id])}/>
        );
      })}
    </div>
  );
}

function SectionLabel({ children, color = 'rgba(20,6,2,0.55)' }) {
  return <div style={{
    fontFamily: 'JetBrains Mono, monospace', fontSize: 10, letterSpacing: 1.8,
    color, fontWeight: 600, margin: '6px 0 8px 0', textTransform: 'uppercase',
  }}>{children}</div>;
}

function TextField({ label, value, onChange, placeholder, type = 'text', dark }) {
  const [focus, setFocus] = React.useState(false);
  return (
    <label style={{ display: 'flex', flexDirection: 'column', gap: 5 }}>
      <span style={{
        fontFamily: 'JetBrains Mono, monospace', fontSize: 10, letterSpacing: 1.6,
        color: dark ? 'rgba(255,255,255,0.6)' : 'rgba(20,6,2,0.6)', fontWeight: 600,
      }}>{label}</span>
      <input type={type} value={value || ''} placeholder={placeholder}
        onChange={e => onChange(e.target.value)}
        onFocus={() => setFocus(true)} onBlur={() => setFocus(false)}
        style={{
          padding: '13px 15px',
          border: `2px solid ${focus ? '#006FD6' : (dark ? 'rgba(255,255,255,0.15)' : 'rgba(20,6,2,0.12)')}`,
          background: focus ? (dark ? 'rgba(255,255,255,0.08)' : '#fff') : (dark ? 'rgba(255,255,255,0.04)' : 'rgba(255,255,255,0.7)'),
          color: dark ? '#fff' : '#140602',
          borderRadius: 12, fontFamily: 'Inter', fontSize: 15, outline: 'none',
          transition: 'all 140ms ease',
          boxShadow: focus ? '0 0 0 4px rgba(0,111,214,0.18)' : 'none',
        }}/>
    </label>
  );
}

function PillChoice({ options, value, setValue, accent = '#FFC800' }) {
  return (
    <div style={{ display: 'flex', gap: 6 }}>
      {options.map(o => (
        <button key={o} onClick={() => setValue(o)} style={{
          flex: 1, padding: '11px 6px',
          background: value === o ? accent : 'rgba(255,255,255,0.8)',
          color: '#140602',
          border: `2px solid ${value === o ? '#140602' : 'rgba(20,6,2,0.12)'}`,
          borderRadius: 12, fontFamily: 'Inter', fontSize: 13.5, fontWeight: 600,
          cursor: 'pointer',
          boxShadow: value === o ? '0 3px 0 #140602' : 'none',
          transform: value === o ? 'translateY(0)' : 'translateY(0)',
          transition: 'all 120ms',
        }}>{o}</button>
      ))}
    </div>
  );
}

window.EntriesBar = EntriesBar;
window.LevelShell = LevelShell;
window.Chip = Chip;
window.ChipGroup = ChipGroup;
window.SectionLabel = SectionLabel;
window.TextField = TextField;
window.PillChoice = PillChoice;
