/* Onboarding, sign in, OTP, location */
function SignIn({ onDone }) {
  const { topInset, bottomInset, device } = useApp();
  const [val, setVal] = useState(''); const [pk, setPk] = useState(0); const [bad, setBad] = useState(false); const [focus, setFocus] = useState(false);
  const ok = /^[^@\s]+@[^@\s]+\.[a-z]{2,}$/i.test(val);
  const passkey = () => { setPk(1); setTimeout(() => setPk(2), 1200); setTimeout(() => onDone({ via: 'passkey' }), 1700); };
  const go = () => { if (!ok) { setBad(true); setTimeout(() => setBad(false), 500); return; } onDone({ via: 'email', to: val }); };
  const pill = (I, label, onClick, flex) => <button className="press" onClick={onClick} style={{ flex: flex || 'none', width: flex ? 'auto' : '100%', height: 52, borderRadius: 12, border: '1px solid var(--line)', background: 'var(--sur)', color: 'var(--ink)', fontSize: 14.5, fontWeight: 600, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 9 }}>{I}{label}</button>;
  return <div style={{ position: 'absolute', inset: 0, background: STAGE_BG, overflow: 'hidden' }}>
    {/* hero: aurora + kinetic genre marquee */}
    <div style={{ position: 'absolute', left: 0, right: 0, top: 0, height: '48%', overflow: 'hidden' }}>
      <div style={{ position: 'absolute', width: 340, height: 340, left: -80, top: -60, borderRadius: '50%', background: 'radial-gradient(circle, rgba(229,69,88,.75), transparent 65%)', filter: 'blur(20px)', animation: 'siBlob1 9s ease-in-out infinite' }}></div>
      <div style={{ position: 'absolute', width: 320, height: 320, right: -90, top: 20, borderRadius: '50%', background: 'radial-gradient(circle, rgba(123,92,255,.7), transparent 65%)', filter: 'blur(24px)', animation: 'siBlob2 11s ease-in-out infinite' }}></div>
      <div style={{ position: 'absolute', width: 260, height: 260, left: 60, top: 140, borderRadius: '50%', background: 'radial-gradient(circle, rgba(255,182,120,.45), transparent 65%)', filter: 'blur(26px)', animation: 'siBlob1 13s ease-in-out -4s infinite' }}></div>
      <div style={{ position: 'absolute', inset: '-20% -30%', transform: 'rotate(-12deg)', display: 'grid', alignContent: 'center', gap: 6, top: 60 }}>
        {[['Concerts', 'Bollywood Movies', 'Garba', 'Qawwali', 'Bhangra', 'Sufi Nights'], ['Startup Meetups', 'Comedy', 'Bingo Nights', 'Diwali', 'Dandiya', 'Ghazal'], ['Meetups', 'Festivals', 'Holi', 'Brunch', 'Afterparty', 'Mehfil']].map((row, r) => <div key={r} style={{ display: 'flex', whiteSpace: 'nowrap', animation: `siMarq ${26 + r * 6}s linear infinite ${r % 2 ? 'reverse' : ''}` }}>{[...row, ...row, ...row].map((w, i) => <span key={i} style={{ fontFamily: 'var(--dp-font-display)', fontWeight: 700, fontSize: 46, letterSpacing: '-.02em', padding: '0 14px', lineHeight: 1.05, color: (i + r) % 3 === 0 ? 'rgba(255,255,255,.92)' : 'transparent', WebkitTextStroke: (i + r) % 3 === 0 ? '0' : '1.2px rgba(255,255,255,.28)', fontStyle: (i + r) % 3 === 0 ? 'italic' : 'normal' }}>{w}</span>)}</div>)}
      </div>
      <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(180deg, rgba(22,10,36,.55) 0%, rgba(22,10,36,.15) 35%, rgba(22,10,36,.5) 75%, #160A24 100%)' }}></div>
      <div style={{ position: 'absolute', inset: 0, opacity: .12, backgroundImage: 'radial-gradient(rgba(255,255,255,.6) 1px, transparent 1px)', backgroundSize: '3px 3px', mixBlendMode: 'overlay' }}></div>
      <div style={{ position: 'absolute', left: 0, right: 0, top: topInset + 40, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 12 }}>
        <img src={DP.A + 'desipass-logo-white.svg'} alt="DesiPass" style={{ height: 34, animation: 'dpLogoIn .8s cubic-bezier(.2,.8,.2,1) both' }} />
        <div style={{ fontSize: 14.5, fontWeight: 500, color: 'rgba(255,255,255,.75)', animation: 'dpTag .6s ease .3s both' }}>Book tickets. Manage your events.</div>
      </div>
    </div>
    {/* sheet */}
    <div className="sheet" style={{ position: 'absolute', left: 0, right: 0, bottom: 0, borderRadius: '30px 30px 0 0', background: 'var(--bg)', padding: `26px 22px ${bottomInset + 16}px`, boxShadow: '0 -20px 50px rgba(0,0,0,.35)' }}>
      <div style={{ width: 40, height: 4, borderRadius: 4, background: 'var(--line)', margin: '-14px auto 18px' }}></div>
      <h1 style={{ margin: '0 0 16px', fontFamily: 'var(--dp-font-display)', fontWeight: 600, fontSize: 26, letterSpacing: '-.02em', color: 'var(--ink)' }}>Sign in <em style={{ fontStyle: 'italic', fontWeight: 500, color: 'var(--red)' }}>or join</em></h1>
      <div className={bad ? 'shake' : ''} style={{ position: 'relative', height: 58, borderRadius: 16, border: `1.5px solid ${bad ? 'var(--red)' : focus ? 'var(--ink)' : 'var(--line)'}`, background: 'var(--sur)', transition: 'border-color .2s', display: 'flex', alignItems: 'center', padding: '0 6px 0 16px' }}>
        <div style={{ flex: 1, position: 'relative', height: '100%' }}>
          <span style={{ position: 'absolute', left: 0, top: focus || val ? 9 : 19, fontSize: focus || val ? 11 : 15, color: 'var(--mut2)', fontWeight: 500, transition: 'all .2s cubic-bezier(.2,.8,.2,1)', pointerEvents: 'none' }}>Enter your email</span>
          <input value={val} onChange={e => setVal(e.target.value)} onFocus={() => setFocus(true)} onBlur={() => setFocus(false)} onKeyDown={e => e.key === 'Enter' && go()} type="email" style={{ ...inputStyle, position: 'absolute', left: 0, right: 0, bottom: 8, fontSize: 15 }} />
        </div>
        <button className="press" aria-label="Continue with email" onClick={go} style={{ width: 46, height: 46, borderRadius: 13, background: ok ? 'linear-gradient(135deg,#E54558,#3B2E4D)' : 'var(--chip)', color: ok ? '#fff' : 'var(--mut2)', display: 'grid', placeItems: 'center', transition: 'all .25s' }}><Ico.chev size={20} /></button>
      </div>
      <div style={{ fontSize: 12, color: 'var(--mut2)', margin: '8px 2px 0' }}>We'll email you a 6-digit code. No password needed.</div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, margin: '18px 0 14px' }}><span style={{ flex: 1, height: 1, background: 'var(--line)' }}></span><span style={{ fontSize: 11, letterSpacing: '.1em', color: 'var(--mut2)', fontWeight: 600 }}>OR</span><span style={{ flex: 1, height: 1, background: 'var(--line)' }}></span></div>
      <div style={{ display: 'grid', gap: 10 }}>
        <button className="press" onClick={passkey} style={{ width: '100%', height: 52, borderRadius: 12, background: 'var(--ink)', color: 'var(--bg)', fontSize: 14.5, fontWeight: 600, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 9 }}><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><circle cx="9" cy="8" r="4" /><path d="M2 21a7 7 0 0 1 11-5.7" /><circle cx="18" cy="15" r="2.5" /><path d="M18 17.5V22M18 20h2" /></svg>Continue with Passkey</button>
        <div style={{ display: 'flex', gap: 10 }}>{device !== 'android' && pill(<Brand.apple color="currentColor" />, 'Apple', () => onDone({ via: 'apple' }), 1)}{pill(<Brand.google />, 'Google', () => onDone({ via: 'google' }), 1)}</div>
      </div>
      <p style={{ margin: '18px 0 0', fontSize: 11.5, color: 'var(--mut2)', textAlign: 'center', lineHeight: 1.6 }}>By continuing you agree to DesiPass's <a style={{ color: 'var(--mut)', textDecoration: 'underline', textUnderlineOffset: 2 }}>Terms of Service</a> and <a style={{ color: 'var(--mut)', textDecoration: 'underline', textUnderlineOffset: 2 }}>Privacy Policy</a></p>
    </div>
    {pk > 0 && <div className="sheet-bg" style={{ position: 'absolute', inset: 0, background: 'rgba(14,4,32,.45)', display: 'flex', alignItems: 'flex-end', zIndex: 5 }}><div className="sheet" style={{ width: '100%', background: 'var(--sur)', borderRadius: '24px 24px 0 0', padding: `22px 24px ${bottomInset + 24}px`, textAlign: 'center' }}>
      <div style={{ fontWeight: 700, fontSize: 16 }}>Sign in with your passkey</div><div style={{ fontSize: 13, color: 'var(--mut)', marginTop: 4 }}>{DP.USER.email}</div>
      <div style={{ width: 64, height: 64, margin: '20px auto 10px', borderRadius: 18, border: `2.5px solid ${pk === 2 ? '#30d158' : '#0a84ff'}`, color: pk === 2 ? '#30d158' : '#0a84ff', display: 'grid', placeItems: 'center', transition: 'all .25s' }}>{pk === 2 ? <Ico.check size={30} stroke={2.6} /> : <Ico.user size={30} />}</div>
      <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--mut)' }}>{pk === 2 ? 'Signed in' : device === 'android' ? 'Touch the fingerprint sensor' : 'Face ID'}</div>
    </div></div>}
  </div>;
}

function OTP({ to, onDone, onBack }) {
  const { bottomInset } = useApp();
  const [code, setCode] = useState(''); const [busy, setBusy] = useState(false); const [left, setLeft] = useState(30);
  useEffect(() => { const t = setInterval(() => setLeft(l => l > 0 ? l - 1 : 0), 1000); return () => clearInterval(t); }, []);
  useEffect(() => { if (code.length === 6) { setBusy(true); setTimeout(onDone, 900); } }, [code]);
  const key = (k) => <button key={k} className="press" onClick={() => k === '⌫' ? setCode(c => c.slice(0, -1)) : k !== '' && code.length < 6 && setCode(c => c + k)} style={{ height: 56, borderRadius: 14, fontSize: 24, fontWeight: 500, color: 'var(--ink)', background: 'transparent', border: k === '' ? 0 : '1px solid var(--line)' }}>{k}</button>;
  return (
    <div className="push" style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', background: 'var(--bg)' }}>
      <TopBar onBack={onBack} />
      <div style={{ padding: '10px 24px 0', flex: 1 }}>
        <h1 style={{ color: 'var(--ink)', margin: 0, fontFamily: 'var(--dp-font-display)', fontWeight: 600, fontSize: 30, letterSpacing: '-.025em', lineHeight: 1.1 }}>Check your <em style={{ fontStyle: 'italic', fontWeight: 500, color: 'var(--red)' }}>email</em></h1>
        <p style={{ margin: '10px 0 26px', color: 'var(--mut)', fontSize: 14.5 }}>We sent a 6-digit code to <b style={{ color: 'var(--ink)' }}>{to || 'your inbox'}</b>.</p>
        <div style={{ display: 'flex', gap: 8 }}>{[0, 1, 2, 3, 4, 5].map(n => { const filled = code[n] !== undefined, active = code.length === n; return <div key={n} className={filled ? 'pop' : ''} style={{ flex: 1, height: 56, borderRadius: 12, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 22, fontWeight: 700, background: filled ? 'var(--red)' : 'var(--sur)', color: filled ? '#fff' : 'var(--ink)', border: `1.5px solid ${active ? 'var(--red)' : filled ? 'var(--red)' : 'var(--line)'}`, transition: 'all .2s' }}>{code[n] || ''}</div>; })}</div>
        <div style={{ marginTop: 18, fontSize: 13.5, color: 'var(--mut)', display: 'flex', alignItems: 'center', gap: 8, minHeight: 22 }}>{busy ? <><span style={{ width: 16, height: 16, borderRadius: '50%', border: '2px solid var(--red-soft)', borderTopColor: 'var(--red)', animation: 'dpSpin .7s linear infinite' }}></span>Verifying…</> : left > 0 ? <>Resend code in <b style={{ color: 'var(--ink)' }}>0:{String(left).padStart(2, '0')}</b></> : <button onClick={() => setLeft(30)} style={{ color: 'var(--red)', fontWeight: 700 }}>Resend code</button>}</div>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 8, padding: `12px 12px ${bottomInset + 12}px`, borderTop: '1px solid var(--line)' }}>{['1', '2', '3', '4', '5', '6', '7', '8', '9', '', '0', '⌫'].map(key)}</div>
    </div>
  );
}

function LocationAsk({ onDone, onPick }) {
  const { topInset, bottomInset, sim } = useApp(); const [denied, setDenied] = useState(false);
  return (
    <div className="fade-in" style={{ position: 'absolute', inset: 0, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: `${topInset}px 28px ${bottomInset + 24}px`, background: 'var(--bg)', textAlign: 'center' }}>
      <div style={{ position: 'relative', width: 120, height: 120, display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 28 }}>
        {[0, 1, 2].map(i => <span key={i} style={{ position: 'absolute', inset: 0, borderRadius: '50%', border: '1.5px solid var(--red)', animation: `dpPulse 2.4s ease-out ${i * .8}s infinite` }}></span>)}
        <div className="pop" style={{ width: 72, height: 72, borderRadius: '50%', background: 'linear-gradient(266deg,#3B2E4D,#E54558)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', boxShadow: '0 18px 24px rgba(111,29,27,.3)' }}><Ico.pin size={32} /></div>
      </div>
      <h1 className="rise" style={{ color: 'var(--ink)', margin: 0, fontFamily: 'var(--dp-font-display)', fontWeight: 600, fontSize: 28, letterSpacing: '-.025em', lineHeight: 1.1 }}>Find events <em style={{ fontStyle: 'italic', fontWeight: 500, color: 'var(--red)' }}>near you</em></h1>
      <p className="rise" style={{ margin: '12px 0 30px', color: 'var(--mut)', fontSize: 14.5, lineHeight: 1.5, maxWidth: 300, animationDelay: '.05s' }}>We show your city first, then the rest of your country. Your location stays on your phone.</p>
      <div className="rise" style={{ width: '100%', display: 'grid', gap: 10, animationDelay: '.1s' }}>{denied && <div className="fade-in" style={{ display: 'flex', gap: 10, alignItems: 'flex-start', textAlign: 'left', padding: '12px 14px', borderRadius: 12, background: 'var(--warn-bg)', color: 'var(--warn-fg)', fontSize: 13, lineHeight: 1.45 }}><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" style={{ flex: 'none' }}>{ST_ICONS.pin}</svg><span>Location is off for DesiPass. Choose your city, or turn location on in Settings.</span></div>}<Btn onClick={() => sim === 'locdenied' && !denied ? setDenied(true) : denied ? onPick() : onDone()}>{denied ? 'Choose a City' : 'Use My Location'}</Btn>{denied ? <Btn kind="ghost" onClick={() => setDenied(false)}>Open Settings</Btn> : <Btn kind="ghost" onClick={onPick}>Choose a City</Btn>}</div>
    </div>
  );
}

Object.assign(window, { SignIn, OTP, LocationAsk });
