// Shared shell — Marriott Bonvoy aesthetic (orange + black + white)

const LUX = {
  navy: '#0A0A0A',           // black — primary text & dark-screen ground
  midnight: '#000000',
  navyLighter: '#1A1A1A',
  cream: '#FAFAFA',          // warm white
  gold: '#F68522',           // Bonvoy orange
  goldHover: '#FF9438',
  goldGlow: 'rgba(246,133,34,0.12)',
  goldTint: 'rgba(246,133,34,0.18)',
  softCream: '#8A8A8A',
  slate: '#6B6B6B',
  inputBorder: '#E5E5E5',
};
window.LUX = LUX;

// ─────────── BONV°Y wordmark (Mother Design signature) ───────────
function BonvoyMark({ color = '#0A0A0A', size = 18, style }) {
  // BONV°Y — the ° sits where the O between V and Y would be
  return (
    <span style={{
      fontFamily: 'Inter, sans-serif',
      fontWeight: 900,
      fontSize: size,
      letterSpacing: size > 20 ? -0.5 : -0.2,
      color,
      display: 'inline-flex',
      alignItems: 'center',
      lineHeight: 1,
      ...style,
    }}>
      <span>BONV</span>
      <span style={{
        display: 'inline-block',
        width: size * 0.32,
        height: size * 0.32,
        borderRadius: '50%',
        border: `${Math.max(1.4, size*0.09)}px solid ${color}`,
        margin: `0 ${size*0.04}px`,
        position: 'relative',
        top: -size * 0.28,
      }}/>
      <span>Y</span>
    </span>
  );
}
window.BonvoyMark = BonvoyMark;

// ─────────── Monochrome line icons for level headers ───────────
function LevelIcon({ name, color = LUX.gold, size = 22 }) {
  const s = size, c = color, sw = 1.4;
  const paths = {
    contact: <><circle cx="12" cy="9" r="3.5" stroke={c} strokeWidth={sw} fill="none"/><path d="M5 20 Q5 14 12 14 Q19 14 19 20" stroke={c} strokeWidth={sw} fill="none" strokeLinecap="round"/></>,
    vitals: <><path d="M3 12 H7 L9 8 L12 16 L15 10 L17 12 H21" stroke={c} strokeWidth={sw} fill="none" strokeLinecap="round" strokeLinejoin="round"/></>,
    loyalty: <><path d="M5 6 H19 V14 Q19 18 12 20 Q5 18 5 14 Z" stroke={c} strokeWidth={sw} fill="none" strokeLinejoin="round"/><path d="M9 12 L11 14 L15 10" stroke={c} strokeWidth={sw} fill="none" strokeLinecap="round" strokeLinejoin="round"/></>,
    travel: <><path d="M2 14 L7 11 L11 13 L21 7 L21 10 L13 16 L9 14 L4 17 Z" stroke={c} strokeWidth={sw} fill="none" strokeLinejoin="round"/></>,
    events: <><path d="M5 8 V18 H19 V8" stroke={c} strokeWidth={sw} fill="none" strokeLinecap="round"/><path d="M3 8 H21 L18 4 H6 Z" stroke={c} strokeWidth={sw} fill="none" strokeLinejoin="round"/><path d="M10 12 V15 M14 12 V15" stroke={c} strokeWidth={sw} fill="none" strokeLinecap="round"/></>,
    leagues: <><circle cx="12" cy="12" r="8" stroke={c} strokeWidth={sw} fill="none"/><path d="M12 4 V20 M4 12 H20 M6 6 L18 18 M18 6 L6 18" stroke={c} strokeWidth={sw*0.6} fill="none"/></>,
    dining: <><path d="M7 4 V20 M5 4 V10 Q5 12 7 12 Q9 12 9 10 V4" stroke={c} strokeWidth={sw} fill="none" strokeLinecap="round"/><path d="M16 4 Q14 6 14 10 Q14 13 16 13 V20" stroke={c} strokeWidth={sw} fill="none" strokeLinecap="round"/></>,
    trip: <><circle cx="12" cy="10" r="3" stroke={c} strokeWidth={sw} fill="none"/><path d="M12 21 Q5 14 5 10 Q5 4 12 4 Q19 4 19 10 Q19 14 12 21 Z" stroke={c} strokeWidth={sw} fill="none" strokeLinejoin="round"/></>,
    booking: <><rect x="4" y="6" width="16" height="14" rx="1.5" stroke={c} strokeWidth={sw} fill="none"/><path d="M8 4 V8 M16 4 V8 M4 11 H20" stroke={c} strokeWidth={sw} fill="none" strokeLinecap="round"/></>,
    sponsor: <><path d="M12 3 L14.5 9 L21 9 L15.8 13 L17.8 19.5 L12 16 L6.2 19.5 L8.2 13 L3 9 L9.5 9 Z" stroke={c} strokeWidth={sw} fill="none" strokeLinejoin="round"/></>,
  };
  return (
    <svg width={s} height={s} viewBox="0 0 24 24" style={{ flexShrink: 0 }}>
      {paths[name] || paths.contact}
    </svg>
  );
}
window.LevelIcon = LevelIcon;

function MonoLabel({ children, dark, style }) {
  return (
    <div style={{
      fontFamily: "'JetBrains Mono', monospace",
      fontSize: 10, letterSpacing: 1.8, fontWeight: 600,
      color: dark ? 'rgba(245,240,232,0.6)' : 'rgba(11,26,46,0.6)',
      textTransform: 'uppercase',
      ...style,
    }}>{children}</div>
  );
}

// ─────────── Coin Drop Animation ───────────
// Coins fly from a source position to the entries badge
function CoinDropFX({ active, amount, onDone }) {
  React.useEffect(() => {
    if (!active) return;
    const id = setTimeout(onDone, 1100);
    return () => clearTimeout(id);
  }, [active]);
  if (!active) return null;
  const coins = Math.min(Math.max(amount, 1), 6);
  return (
    <div style={{
      position: 'absolute', inset: 0, pointerEvents: 'none', zIndex: 250,
    }}>
      {Array.from({length: coins}).map((_, i) => {
        const delay = i * 80;
        return (
          <div key={i} style={{
            position: 'absolute',
            left: '50%',
            top: '60%',
            width: 22, height: 22, borderRadius: '50%',
            background: `radial-gradient(circle at 35% 30%, #FFB76A, ${LUX.gold} 60%, #C25A0A)`,
            border: `1.5px solid #C25A0A`,
            boxShadow: `0 0 12px ${LUX.gold}`,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            color: LUX.navy, fontFamily: "'JetBrains Mono', monospace",
            fontSize: 11, fontWeight: 800,
            animation: `coinFly 1000ms cubic-bezier(.4,0,.2,1) ${delay}ms forwards`,
            opacity: 0,
          }}>+</div>
        );
      })}
    </div>
  );
}
window.CoinDropFX = CoinDropFX;

function EntriesBadge({ total, burst, pulse }) {
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 8,
      padding: '6px 12px 6px 8px',
      background: 'rgba(10,10,10,0.06)',
      border: `1px solid ${LUX.gold}`,
      borderRadius: 100,
      position: 'relative',
      transform: pulse ? 'scale(1.08)' : 'scale(1)',
      transition: 'transform 280ms cubic-bezier(.34,1.56,.64,1)',
      boxShadow: pulse ? `0 0 24px ${LUX.gold}` : 'none',
    }}>
      <div style={{
        width: 22, height: 22, borderRadius: '50%',
        background: LUX.gold,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        <svg width="11" height="11" viewBox="0 0 12 12" fill="none">
          <path d="M6 1 L7.5 4.5 L11 5 L8.5 7.5 L9 11 L6 9.3 L3 11 L3.5 7.5 L1 5 L4.5 4.5 Z"
            fill="#0A0A0A"/>
        </svg>
      </div>
      <div style={{
        fontFamily: "'JetBrains Mono', monospace", fontSize: 9, letterSpacing: 1.4,
        color: 'rgba(10,10,10,0.6)',
      }}>ENTRIES</div>
      <div style={{
        fontFamily: "'JetBrains Mono', monospace", fontSize: 14, fontWeight: 700,
        color: LUX.gold, lineHeight: 1,
      }}>+{total}</div>
      {burst && (
        <div key={burst.k} style={{
          position: 'absolute', top: -28, right: 8,
          fontFamily: "'JetBrains Mono', monospace", fontSize: 16, fontWeight: 700,
          color: LUX.gold,
          textShadow: '0 1px 0 #fff',
          animation: 'entryBurst 1200ms ease-out forwards',
          pointerEvents: 'none',
        }}>+{burst.amount}</div>
      )}
    </div>
  );
}

function LuxShell({
  levelNum, totalLevels = 10, dark = true, reward = 1,
  title, subtitle, children, iconName,
  onNext, onBack, ctaLabel = 'Continue', canContinue = true,
  entries, burst, pulseEntries,
}) {
  const fg = dark ? LUX.cream : LUX.navy;
  const bg = dark ? LUX.navy : LUX.cream;
  // Override badge for dark mode (different bg)
  const badge = (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 8,
      padding: '6px 12px 6px 8px',
      background: dark ? 'rgba(255,255,255,0.06)' : 'rgba(10,10,10,0.04)',
      border: `1px solid ${LUX.gold}`,
      borderRadius: 100,
      position: 'relative',
      transform: pulseEntries ? 'scale(1.10)' : 'scale(1)',
      transition: 'transform 320ms cubic-bezier(.34,1.56,.64,1)',
      boxShadow: pulseEntries ? `0 0 26px ${LUX.gold}` : 'none',
    }}>
      <div style={{
        width: 22, height: 22, borderRadius: '50%',
        background: LUX.gold,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        <svg width="11" height="11" viewBox="0 0 12 12" fill="none">
          <path d="M6 1 L7.5 4.5 L11 5 L8.5 7.5 L9 11 L6 9.3 L3 11 L3.5 7.5 L1 5 L4.5 4.5 Z" fill={dark ? '#0A0A0A' : '#0A0A0A'}/>
        </svg>
      </div>
      <div style={{
        fontFamily: "'JetBrains Mono', monospace", fontSize: 9, letterSpacing: 1.4,
        color: dark ? 'rgba(255,255,255,0.65)' : 'rgba(10,10,10,0.55)',
      }}>ENTRIES</div>
      <div style={{
        fontFamily: "'JetBrains Mono', monospace", fontSize: 14, fontWeight: 700,
        color: LUX.gold, lineHeight: 1,
      }}>+{entries}</div>
      {burst && (
        <div key={burst.k} style={{
          position: 'absolute', top: -28, right: 8,
          fontFamily: "'JetBrains Mono', monospace", fontSize: 16, fontWeight: 700,
          color: LUX.gold,
          animation: 'entryBurst 1200ms ease-out forwards',
          pointerEvents: 'none',
        }}>+{burst.amount}</div>
      )}
    </div>
  );

  return (
    <div style={{
      position: 'absolute', inset: 0, background: bg,
      display: 'flex', flexDirection: 'column', overflow: 'hidden', color: fg,
    }}>
      {/* top: back + entries — top padding respects iOS notch/Dynamic Island via env(safe-area-inset-top) */}
      <div style={{
        position: 'relative', zIndex: 3,
        padding: 'max(54px, calc(14px + env(safe-area-inset-top, 0px))) 18px 0 18px',
        display: 'flex', alignItems: 'center', gap: 10,
      }}>
        <button onClick={onBack} style={{
          width: 36, height: 36, borderRadius: '50%',
          border: `1px solid ${dark ? 'rgba(245,240,232,0.3)' : 'rgba(10,10,10,0.18)'}`,
          background: 'transparent', cursor: 'pointer', flexShrink: 0,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <svg width="11" height="11" viewBox="0 0 14 14">
            <path d="M9 2 L3 7 L9 12" stroke={fg} strokeWidth="1.6" fill="none"
              strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </button>
        <div style={{ flex: 1 }}/>
        {badge}
      </div>

      {/* progress + level tag */}
      <div style={{ position: 'relative', zIndex: 3, padding: '14px 22px 0 22px' }}>
        <div style={{
          display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          fontFamily: "'JetBrains Mono', monospace", fontSize: 10, letterSpacing: 2,
          color: fg, fontWeight: 600, opacity: 0.85, marginBottom: 8,
        }}>
          <span>LEVEL {String(levelNum).padStart(2,'0')} / {String(totalLevels).padStart(2,'0')}</span>
          <span style={{ color: LUX.gold }}>+{reward} ENTR{reward === 1 ? 'Y' : 'IES'}</span>
        </div>
        <div style={{
          height: 3,
          background: dark ? 'rgba(245,240,232,0.12)' : 'rgba(10,10,10,0.1)',
          borderRadius: 100, overflow: 'hidden',
        }}>
          <div style={{
            width: `${(levelNum / totalLevels) * 100}%`, height: '100%',
            background: LUX.gold,
            transition: 'width 600ms cubic-bezier(.2,.8,.2,1)',
          }}/>
        </div>
      </div>

      {/* heading w/ icon */}
      <div style={{ position: 'relative', zIndex: 3, padding: '20px 22px 6px 22px' }}>
        {iconName && (
          <div style={{ marginBottom: 12 }}>
            <div style={{
              width: 40, height: 40, borderRadius: '50%',
              background: dark ? 'rgba(246,133,34,0.10)' : 'rgba(246,133,34,0.10)',
              border: `1px solid ${LUX.gold}`,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
            }}>
              <LevelIcon name={iconName} color={LUX.gold} size={22}/>
            </div>
          </div>
        )}
        <h1 style={{
          margin: 0,
          fontFamily: 'Inter, sans-serif',
          fontWeight: 900,
          fontSize: 32, lineHeight: 1.0, letterSpacing: -1.0,
          textTransform: 'uppercase',
        }}>{title}</h1>
        {subtitle && <div style={{
          marginTop: 10, fontFamily: 'Inter, sans-serif', fontSize: 13,
          color: dark ? 'rgba(245,240,232,0.7)' : 'rgba(10,10,10,0.65)',
          lineHeight: 1.45, fontWeight: 400,
        }}>{subtitle}</div>}
      </div>

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

      {/* CTA — bottom padding respects iOS home indicator via env(safe-area-inset-bottom) */}
      <div style={{
        position: 'relative', zIndex: 3,
        padding: '8px 22px max(28px, calc(20px + env(safe-area-inset-bottom, 0px))) 22px',
      }}>
        <button onClick={canContinue ? onNext : undefined} style={{
          width: '100%', border: 'none',
          background: canContinue ? LUX.gold : (dark ? 'rgba(196,163,90,0.25)' : 'rgba(196,163,90,0.35)'),
          color: canContinue ? '#FFFFFF' : (dark ? 'rgba(245,240,232,0.4)' : 'rgba(10,10,10,0.4)'),
          padding: '17px 20px',
          fontFamily: "'JetBrains Mono', monospace", fontSize: 13,
          fontWeight: 700, letterSpacing: 2.5,
          borderRadius: 12, textTransform: 'uppercase',
          cursor: canContinue ? 'pointer' : 'default',
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          opacity: canContinue ? 1 : 0.65,
          transition: 'all 180ms ease',
        }}>
          <span>{ctaLabel}</span>
          <span style={{ fontSize: 16, letterSpacing: 0 }}>→</span>
        </button>
      </div>
    </div>
  );
}

// ─────────── Pill (with stronger haptic pulse) ───────────
function Pill({ label, hint, selected, onClick, dark }) {
  const [pressed, setPressed] = React.useState(false);
  const [ripple, setRipple] = React.useState(0);
  const baseBg = dark ? LUX.navyLighter : '#FFFFFF';
  const selBg = dark ? LUX.goldGlow : LUX.goldTint;
  const handleClick = () => {
    setRipple(r => r + 1);
    onClick?.();
  };
  return (
    <button onClick={handleClick}
      onMouseDown={() => setPressed(true)} onMouseUp={() => setPressed(false)}
      onMouseLeave={() => setPressed(false)}
      onTouchStart={() => setPressed(true)} onTouchEnd={() => setPressed(false)}
      style={{
        padding: '11px 16px',
        background: selected ? selBg : baseBg,
        color: dark ? LUX.cream : LUX.navy,
        border: `1px solid ${selected ? LUX.gold : (dark ? 'rgba(245,240,232,0.08)' : 'rgba(10,10,10,0.08)')}`,
        borderRadius: 24,
        fontFamily: 'Inter, sans-serif', fontSize: 13.5, fontWeight: 500,
        cursor: 'pointer',
        display: 'inline-flex', alignItems: 'center', gap: 8,
        boxShadow: !dark && !selected ? '0 1px 3px rgba(10,10,10,0.06)' :
                   selected && !dark ? '0 2px 12px rgba(246,133,34,0.18)' : 'none',
        transform: pressed ? 'scale(0.93)' : (ripple ? 'scale(1)' : 'scale(1)'),
        animation: ripple ? `pillPulse 360ms cubic-bezier(.34,1.56,.64,1)` : undefined,
        transition: 'background 180ms, border-color 180ms, box-shadow 180ms, transform 100ms ease',
        position: 'relative',
      }} key={ripple}>
      {hint && <span style={{ fontSize: 14 }}>{hint}</span>}
      <span style={{ letterSpacing: 0.1 }}>{label}</span>
      {selected && (
        <span style={{
          display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
          width: 16, height: 16, borderRadius: '50%', background: LUX.gold,
          marginLeft: 2,
        }}>
          <svg width="9" height="9" viewBox="0 0 10 10">
            <path d="M2 5 L4 7 L8 3" stroke="#FFFFFF" strokeWidth="1.8"
              fill="none" strokeLinecap="round" strokeLinejoin="round"/>
          </svg>
        </span>
      )}
    </button>
  );
}

function PillGrid({ options, value, setValue, multi, dark }) {
  const isSel = (id) => multi ? (value || []).includes(id) : value === id;
  const toggle = (id) => {
    if (multi) {
      const cur = value || [];
      setValue(cur.includes(id) ? cur.filter(x => x !== id) : [...cur, id]);
    } else {
      setValue(id);
    }
  };
  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
      {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 (
          <Pill key={id} label={label} hint={hint}
            selected={isSel(id)} onClick={() => toggle(id)} dark={dark}/>
        );
      })}
    </div>
  );
}

function TextField({ label, value, onChange, placeholder, type = 'text', dark, format }) {
  const [focus, setFocus] = React.useState(false);
  const handleChange = (e) => {
    const v = format ? format(e.target.value) : e.target.value;
    onChange(v);
  };
  return (
    <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
      <MonoLabel dark={dark}>{label}</MonoLabel>
      <input type={type} value={value || ''} placeholder={placeholder}
        onChange={handleChange}
        onFocus={() => setFocus(true)} onBlur={() => setFocus(false)}
        style={{
          padding: '13px 14px',
          border: `1px solid ${focus ? LUX.gold : LUX.inputBorder}`,
          background: '#FFFFFF',
          color: LUX.navy,
          borderRadius: 12, fontFamily: 'Inter, sans-serif',
          fontSize: 15, outline: 'none',
          transition: 'all 160ms ease',
          boxShadow: focus ? `0 0 0 3px ${LUX.goldTint}` : 'none',
        }}/>
    </label>
  );
}

function RatingScale({ value, setValue, dark }) {
  return (
    <div style={{ display: 'flex', gap: 8, justifyContent: 'space-between' }}>
      {[1,2,3,4,5].map(n => {
        const sel = value === n;
        return (
          <button key={n} onClick={() => setValue(n)} style={{
            flex: 1, aspectRatio: '1 / 1', maxWidth: 56,
            background: sel ? LUX.gold : (dark ? LUX.navyLighter : '#FFFFFF'),
            color: sel ? '#FFFFFF' : (dark ? LUX.cream : LUX.navy),
            border: `1px solid ${sel ? LUX.gold : (dark ? 'rgba(245,240,232,0.12)' : 'rgba(10,10,10,0.1)')}`,
            borderRadius: '50%',
            fontFamily: "'JetBrains Mono', monospace", fontSize: 16, fontWeight: 700,
            cursor: 'pointer', transition: 'all 160ms ease',
          }}>{n}</button>
        );
      })}
    </div>
  );
}

function SectionLabel({ children, dark }) {
  return (
    <MonoLabel dark={dark} style={{ margin: '14px 0 10px 0' }}>
      {children}
    </MonoLabel>
  );
}

// Phone formatter — (XXX) XXX-XXXX
function formatPhone(v) {
  const d = (v || '').replace(/\D/g, '').slice(0, 10);
  if (d.length < 4) return d;
  if (d.length < 7) return `(${d.slice(0,3)}) ${d.slice(3)}`;
  return `(${d.slice(0,3)}) ${d.slice(3,6)}-${d.slice(6)}`;
}
window.formatPhone = formatPhone;

Object.assign(window, {
  LuxShell, Pill, PillGrid, TextField, RatingScale,
  MonoLabel, SectionLabel, EntriesBadge,
});
