// QReward Customer — Onboarding: Splash, Tour, Login, Account creation
const { useState: uS1, useEffect: uE1, useRef: uR1 } = React;

/* ============ SPLASH ============ */
const SplashScreen = ({ onDone }) => {
  uE1(() => { const t = setTimeout(onDone, 1600); return () => clearTimeout(t); }, []);
  return (
    <div className="splash">
      <div className="splash-mark" style={{ animation: 'splashPop 600ms cubic-bezier(0.2,0.7,0.3,1)' }}>
        <span className="splash-mark-r">r</span>
      </div>
      <div className="splash-name" style={{ animation: 'fadeUp 500ms ease 200ms both' }}>QReward</div>
      <style>{`
        @keyframes splashPop { from { transform: scale(0.6); opacity: 0.3; } to { transform: scale(1); opacity: 1; } }
        @keyframes fadeUp { from { transform: translateY(8px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
      `}</style>
    </div>
  );
};

/* ============ FIRST-RUN TOUR ============ */
const TourScreen = ({ onDone, lang }) => {
  const [i, setI] = uS1(0);
  const slides = [
    { art: 'wallet', hl: lang === 'jp' ? 'すべてのポイントを\nひとつに' : 'All your points,\nin one wallet', body: lang === 'jp' ? 'LifeCardとQUALIAのポイントを、QRewardでまとめて管理。' : 'QReward brings your LifeCard and QUALIA points together in one place.' },
    { art: 'trending', hl: lang === 'jp' ? '使うほど\n貯まる' : 'Earn as you\nspend', body: lang === 'jp' ? '提携カードを連携すると、毎日のお買い物がポイントに変わります。' : 'Link your partner cards and everyday spending turns into points automatically.' },
    { art: 'gift', hl: lang === 'jp' ? 'ポイントで\n特別な体験を' : 'Redeem for\nthings you love', body: lang === 'jp' ? 'マーケットプレイスで、ギフト・家電・体験などと交換できます。' : 'Spend points in the marketplace on gift cards, electronics, experiences and more.' },
  ];
  const s = slides[i];
  const last = i === slides.length - 1;
  return (
    <div className="tour">
      <button className="tour-skip" onClick={onDone}>{lang === 'jp' ? 'スキップ' : 'Skip'}</button>
      <div className="tour-illust">
        <div className="tour-illust-art" key={i} style={{ animation: 'tourArt 500ms ease' }}>
          <TourArt kind={s.art} />
        </div>
      </div>
      <div className="tour-body">
        <div className="tour-dots">
          {slides.map((_, k) => <div key={k} className={`tour-dot ${k === i ? 'active' : ''}`}></div>)}
        </div>
        <div className="tour-headline" key={'h' + i} style={{ whiteSpace: 'pre-line', animation: 'fadeIn 400ms ease 80ms both' }}>{s.hl}</div>
        <div className="tour-body-text" key={'b' + i} style={{ animation: 'fadeIn 400ms ease 140ms both' }}>{s.body}</div>
        <div style={{ marginTop: 22 }}>
          <Btn block onClick={() => last ? onDone() : setI(i + 1)}>
            {last ? (lang === 'jp' ? 'はじめる' : 'Get started') : (lang === 'jp' ? '次へ' : 'Next')}
          </Btn>
        </div>
      </div>
      <style>{`
        @keyframes tourArt { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: translateX(0); } }
        @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
      `}</style>
    </div>
  );
};

const TourArt = ({ kind }) => {
  // Stylized cohesive illustrations (line-weight consistent)
  if (kind === 'wallet') return (
    <svg viewBox="0 0 220 220" fill="none">
      <rect x="34" y="70" width="152" height="100" rx="16" fill="#dce8ff"/>
      <rect x="34" y="70" width="152" height="100" rx="16" stroke="#1f4fd1" strokeWidth="3"/>
      <rect x="50" y="52" width="120" height="74" rx="12" fill="#1b2d6f" transform="rotate(-8 110 89)"/>
      <circle cx="150" cy="120" r="16" fill="#1f4fd1"/>
      <text x="146" y="127" fontFamily="Georgia" fontStyle="italic" fontSize="22" fill="#fff">r</text>
      <circle cx="80" cy="40" r="5" fill="#f5b942"/>
      <circle cx="180" cy="56" r="4" fill="#5eea98"/>
    </svg>
  );
  if (kind === 'trending') return (
    <svg viewBox="0 0 220 220" fill="none">
      <circle cx="110" cy="110" r="78" fill="#dce8ff"/>
      <path d="M60 140 L95 105 L120 125 L165 80" stroke="#1f4fd1" strokeWidth="5" strokeLinecap="round" strokeLinejoin="round"/>
      <path d="M140 80 H165 V105" stroke="#1f4fd1" strokeWidth="5" strokeLinecap="round" strokeLinejoin="round"/>
      <circle cx="165" cy="80" r="9" fill="#f5b942"/>
      <text x="159" y="86" fontFamily="Georgia" fontStyle="italic" fontSize="13" fill="#1b2d6f">r</text>
    </svg>
  );
  return (
    <svg viewBox="0 0 220 220" fill="none">
      <rect x="56" y="92" width="108" height="84" rx="10" fill="#dce8ff"/>
      <rect x="48" y="74" width="124" height="28" rx="8" fill="#1f4fd1"/>
      <path d="M110 74 V176" stroke="#1b2d6f" strokeWidth="4"/>
      <path d="M110 74 C 96 50, 70 56, 78 74 Z" fill="#f5b942"/>
      <path d="M110 74 C 124 50, 150 56, 142 74 Z" fill="#5eea98"/>
      <circle cx="110" cy="74" r="7" fill="#1b2d6f"/>
    </svg>
  );
};

/* ============ LOGIN ============ */
const LoginScreen = ({ onLogin, onCreate, lang, hasBiometric = true }) => {
  const [email, setEmail] = uS1('giri.tanaka@gmail.com');
  const [pw, setPw] = uS1('');
  const [showPw, setShowPw] = uS1(false);
  const [remember, setRemember] = uS1(true);
  const [state, setState] = uS1('fresh'); // fresh | submitting | error | success | bioPrompt
  const [attempts, setAttempts] = uS1(0);

  const submit = () => {
    setState('submitting');
    setTimeout(() => {
      if (pw === 'wrong' || (pw.length > 0 && pw.length < 4)) {
        const a = attempts + 1; setAttempts(a);
        setState('error');
      } else {
        setState('success');
        setTimeout(onLogin, 500);
      }
    }, 900);
  };

  const locked = attempts >= 5;

  return (
    <div className="scr scr-pad-status" style={{ justifyContent: 'flex-start' }}>
      <div style={{ display: 'flex', justifyContent: 'flex-end', padding: '4px 20px' }}>
        <button className="lang-mini" onClick={() => {}} style={{ fontSize: 13, color: 'var(--brand-600)', fontWeight: 600 }}>
          {lang === 'jp' ? 'EN / 日本語' : 'EN / 日本語'}
        </button>
      </div>
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'center', paddingBottom: 40 }}>
        <div style={{ textAlign: 'center', marginBottom: 32 }}>
          <div className="login-mark"><span style={{ fontFamily: 'Georgia', fontStyle: 'italic', fontSize: 38, fontWeight: 700, color: 'var(--brand-700)' }}>r</span></div>
          <Wordmark size={26} />
          <div className="muted" style={{ fontSize: 14, marginTop: 6 }}>{lang === 'jp' ? 'おかえりなさい' : 'Welcome back'}</div>
        </div>

        {state === 'error' && (
          <div className="banner banner-red" style={{ animation: 'shake 250ms ease' }}>
            <Icon n="alert" s={18} />
            <div>{locked ? (lang === 'jp' ? '試行回数が多すぎます。パスワードをリセットしてください。' : 'Too many attempts. Try “Forgot password”.') : (lang === 'jp' ? 'メールアドレスまたはパスワードが正しくありません。' : 'Invalid email or password.')}</div>
          </div>
        )}

        <div className="field">
          <label className="field-label">{lang === 'jp' ? 'メールアドレス' : 'Email'}</label>
          <input className="input" value={email} onChange={e => setEmail(e.target.value)} type="email" inputMode="email" />
        </div>
        <div className="field">
          <label className="field-label">{lang === 'jp' ? 'パスワード' : 'Password'}</label>
          <div className="input-affix">
            <input className="input" value={pw} onChange={e => setPw(e.target.value)} type={showPw ? 'text' : 'password'} placeholder="••••••••" />
            <button className="input-affix-eye" onClick={() => setShowPw(!showPw)}><Icon n={showPw ? 'eyeOff' : 'eye'} s={20} /></button>
          </div>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '0 20px', marginBottom: 20 }}>
          <button style={{ display: 'flex', alignItems: 'center', gap: 8 }} onClick={() => setRemember(!remember)}>
            <span className={`checkbox ${remember ? 'checked' : ''}`} style={{ width: 20, height: 20 }}></span>
            <span style={{ fontSize: 13 }}>{lang === 'jp' ? 'ログイン状態を保持' : 'Remember me'}</span>
          </button>
          <button style={{ fontSize: 13, color: 'var(--brand-600)', fontWeight: 500 }}>{lang === 'jp' ? 'パスワードを忘れた' : 'Forgot password?'}</button>
        </div>

        <div className="field">
          <Btn block disabled={state === 'submitting' || locked} onClick={submit}>
            {state === 'submitting' ? <span className="spin-dot"></span> : state === 'success' ? <Icon n="check" s={20} sw={2.4} /> : L(lang, 'signIn')}
          </Btn>
        </div>

        {hasBiometric && (
          <>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '4px 20px 16px' }}>
              <div style={{ flex: 1, height: 1, background: 'var(--border)' }}></div>
              <span className="subtle" style={{ fontSize: 12 }}>{lang === 'jp' ? 'または' : 'or'}</span>
              <div style={{ flex: 1, height: 1, background: 'var(--border)' }}></div>
            </div>
            <div className="field">
              <Btn block variant="secondary" icon="faceId" onClick={() => { setState('success'); setTimeout(onLogin, 600); }}>
                {lang === 'jp' ? 'Face IDでサインイン' : 'Use Face ID'}
              </Btn>
            </div>
          </>
        )}
      </div>
      <div style={{ textAlign: 'center', paddingBottom: 28, fontSize: 14 }}>
        <span className="muted">{lang === 'jp' ? 'はじめての方は' : 'New here?'} </span>
        <button style={{ color: 'var(--brand-600)', fontWeight: 600 }} onClick={onCreate}>{lang === 'jp' ? 'アカウント作成' : 'Create account'}</button>
      </div>
      <style>{`
        .login-mark { width: 64px; height: 64px; border-radius: 18px; background: linear-gradient(135deg, #eef3ff, #dce8ff); display: grid; place-items: center; margin: 0 auto 14px; box-shadow: 0 8px 20px rgba(31,79,209,0.12); }
        .spin-dot { width: 18px; height: 18px; border: 2px solid rgba(255,255,255,0.4); border-top-color: #fff; border-radius: 50%; animation: spin 700ms linear infinite; }
        @keyframes spin { to { transform: rotate(360deg); } }
      `}</style>
    </div>
  );
};

/* ============ ACCOUNT CREATION (7 steps) ============ */
const SignupFlow = ({ onDone, onCancel, lang }) => {
  const [step, setStep] = uS1(0); // 0..6
  const total = 7;
  const next = () => setStep(s => Math.min(total - 1, s + 1));
  const back = () => step === 0 ? onCancel() : setStep(s => s - 1);

  return (
    <div className="scr scr-pad-status" style={{ paddingBottom: 0 }}>
      <TopBar onBack={back} lang={lang} />
      {step < 6 && (
        <div className="progress"><div className="progress-bar" style={{ width: `${((step + 1) / total) * 100}%` }}></div></div>
      )}
      <div style={{ flex: 1, overflowY: 'auto', display: 'flex', flexDirection: 'column' }}>
        {step === 0 && <SignupDetails onNext={next} lang={lang} />}
        {step === 1 && <SignupOTP onNext={next} email={DATA.user.emailMasked} lang={lang} />}
        {step === 2 && <SignupConsent onNext={next} lang={lang} />}
        {step === 3 && <SignupPIN onNext={next} lang={lang} />}
        {step === 4 && <SignupBiometric onNext={next} lang={lang} />}
        {step === 5 && <SignupQualia onNext={next} lang={lang} />}
        {step === 6 && <SignupWelcome onDone={onDone} lang={lang} />}
      </div>
    </div>
  );
};

const StepHead = ({ title, sub }) => (
  <div style={{ padding: '12px 20px 8px' }}>
    <div className="h2">{title}</div>
    {sub && <div className="muted" style={{ fontSize: 14, marginTop: 6, lineHeight: 1.5 }}>{sub}</div>}
  </div>
);

const SignupDetails = ({ onNext, lang }) => {
  const [user, setUser] = uS1('');
  const [email, setEmail] = uS1('');
  const [phone, setPhone] = uS1('');
  const [pw, setPw] = uS1('');
  const [pw2, setPw2] = uS1('');
  const [showPw, setShowPw] = uS1(false);
  const userTaken = user.toLowerCase() === 'giri' || user.toLowerCase() === 'admin';
  const userOk = user.length >= 3 && !userTaken;
  const emailOk = /\S+@\S+\.\S+/.test(email);
  const pwScore = [pw.length >= 8, /[A-Z]/.test(pw) && /[a-z]/.test(pw), /\d/.test(pw), /[^A-Za-z0-9]/.test(pw)].filter(Boolean).length;
  const pwLabels = ['', 'weak', 'fair', 'good', 'strong'];
  const matchOk = pw2.length > 0 && pw === pw2;
  const valid = userOk && emailOk && phone.length >= 10 && pwScore >= 3 && matchOk;

  return (
    <div>
      <StepHead title={lang === 'jp' ? 'アカウント情報' : 'Account details'} sub={lang === 'jp' ? 'いくつかの情報を入力してください。' : 'Tell us a few details to get started.'} />
      <div className="field">
        <label className="field-label">{lang === 'jp' ? 'メールアドレス' : 'Email address'}</label>
        <div className="input-affix">
          <input className="input" value={email} onChange={e => setEmail(e.target.value)} type="email" placeholder="you@example.com" />
          {emailOk && <span className="input-affix-check"><Icon n="check" s={18} sw={2.4} /></span>}
        </div>
      </div>
      <div className="field">
        <label className="field-label">{lang === 'jp' ? 'ユーザー名' : 'Username'}</label>
        <div className="input-affix">
          <input className="input" value={user} onChange={e => setUser(e.target.value)} placeholder="giri_t" style={userTaken ? { borderColor: 'var(--red-500)' } : null} />
          {user.length >= 3 && (userOk
            ? <span className="input-affix-check"><Icon n="check" s={18} sw={2.4} /></span>
            : <span className="input-affix-eye" style={{ color: 'var(--red-500)' }}><Icon n="x" s={18} sw={2.4} /></span>)}
        </div>
        {userTaken && <div className="field-error"><Icon n="alert" s={13} /> {lang === 'jp' ? 'このユーザー名は使用されています' : 'That username is taken'}</div>}
        {userOk && <div className="field-help" style={{ color: 'var(--green-600)' }}>{lang === 'jp' ? '利用可能です' : 'Available'}</div>}
      </div>
      <div className="field">
        <label className="field-label">{lang === 'jp' ? '電話番号' : 'Phone number'} <span className="subtle" style={{ fontWeight: 400 }}>· {lang === 'jp' ? 'なぜ必要？' : 'Why we need this'}</span></label>
        <div style={{ display: 'flex', gap: 8 }}>
          <div className="input" style={{ width: 64, display: 'grid', placeItems: 'center', flexShrink: 0, fontWeight: 600 }}>+81</div>
          <input className="input" value={phone} onChange={e => setPhone(e.target.value.replace(/\D/g, ''))} type="tel" inputMode="numeric" placeholder="90-1234-5678" />
        </div>
      </div>
      <div className="field">
        <label className="field-label">{lang === 'jp' ? 'パスワード作成' : 'Create password'}</label>
        <div className="input-affix">
          <input className="input" value={pw} onChange={e => setPw(e.target.value)} type={showPw ? 'text' : 'password'} placeholder="••••••••" />
          <button className="input-affix-eye" onClick={() => setShowPw(!showPw)}><Icon n={showPw ? 'eyeOff' : 'eye'} s={20} /></button>
        </div>
        <div className="pw-meter">
          {[1, 2, 3, 4].map(k => <div key={k} className={`pw-meter-bar ${pwScore >= k ? 'on ' + pwLabels[pwScore] : ''}`}></div>)}
        </div>
        <div className="field-help">{lang === 'jp' ? '8文字以上、大文字・小文字・数字・記号を含む' : 'At least 8 characters with upper, lower, digit & symbol.'} {pw && <strong style={{ textTransform: 'capitalize' }}>· {pwLabels[pwScore]}</strong>}</div>
      </div>
      <div className="field">
        <label className="field-label">{lang === 'jp' ? 'パスワード確認' : 'Confirm password'}</label>
        <div className="input-affix">
          <input className="input" value={pw2} onChange={e => setPw2(e.target.value)} type={showPw ? 'text' : 'password'} placeholder="••••••••" style={pw2 && !matchOk ? { borderColor: 'var(--red-500)' } : null} />
          {matchOk && <span className="input-affix-check"><Icon n="check" s={18} sw={2.4} /></span>}
        </div>
      </div>
      <div className="cta-pinned" style={{ position: 'sticky' }}>
        <Btn block disabled={!valid} onClick={onNext}>{L(lang, 'continue')}</Btn>
      </div>
    </div>
  );
};

const SignupOTP = ({ onNext, email, lang }) => {
  const [digits, setDigits] = uS1(['', '', '', '', '', '']);
  const [err, setErr] = uS1(false);
  const [countdown, setCountdown] = uS1(60);
  uE1(() => { if (countdown <= 0) return; const t = setTimeout(() => setCountdown(c => c - 1), 1000); return () => clearTimeout(t); }, [countdown]);
  const filled = digits.filter(Boolean).length;
  const press = (n) => {
    const idx = digits.findIndex(d => d === '');
    if (idx === -1) return;
    const nd = [...digits]; nd[idx] = String(n); setDigits(nd);
    if (idx === 5) {
      setTimeout(() => {
        if (nd.join('') === '123456' || nd.join('').length === 6) { onNext(); }
        else { setErr(true); setTimeout(() => { setDigits(['', '', '', '', '', '']); setErr(false); }, 500); }
      }, 200);
    }
  };
  const del = () => { const idx = [...digits].reverse().findIndex(d => d !== ''); if (idx === -1) return; const real = 5 - idx; const nd = [...digits]; nd[real] = ''; setDigits(nd); };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
      <StepHead title={lang === 'jp' ? 'メール確認' : 'Verify your email'} />
      <div className="muted" style={{ fontSize: 14, padding: '0 20px 4px' }}>
        {lang === 'jp' ? 'に送信した6桁のコードを入力' : 'Enter the 6-digit code we sent to'} <strong className="mono">{email}</strong>
        <button style={{ color: 'var(--brand-600)', fontWeight: 600, marginLeft: 6 }}>{lang === 'jp' ? 'メール変更' : 'Wrong email? Edit'}</button>
      </div>
      <div style={{ padding: '24px 0' }}>
        <div className="otp">
          {digits.map((d, i) => (
            <div key={i} className={`otp-slot ${err ? 'error' : ''} ${d ? 'filled' : ''} ${i === filled && !err ? 'active' : ''}`}>{d}</div>
          ))}
        </div>
      </div>
      <div style={{ textAlign: 'center', fontSize: 13 }} className="muted">
        {countdown > 0
          ? <>{lang === 'jp' ? 'コード再送信' : 'Resend code'} <strong className="mono">0:{String(countdown).padStart(2, '0')}</strong></>
          : <button style={{ color: 'var(--brand-600)', fontWeight: 600 }} onClick={() => setCountdown(60)}>{lang === 'jp' ? 'コードを再送信' : 'Resend code'}</button>}
      </div>
      <div style={{ flex: 1 }}></div>
      <Numpad onPress={press} onDel={del} />
    </div>
  );
};

const Numpad = ({ onPress, onDel }) => (
  <div className="numpad">
    {[1, 2, 3, 4, 5, 6, 7, 8, 9].map(n => <button key={n} className="numkey" onClick={() => onPress(n)}>{n}</button>)}
    <div></div>
    <button className="numkey" onClick={() => onPress(0)}>0</button>
    <button className="numkey numkey-fn" onClick={onDel}><Icon n="chevL" s={22} /></button>
    <style>{`
      .numpad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; padding: 8px 20px 24px; }
      .numkey { height: 52px; border-radius: 12px; background: var(--surface); border: 0.5px solid var(--border); font-family: var(--font-display); font-size: 24px; font-weight: 500; transition: background 80ms; }
      .numkey:active { background: var(--surface-3); }
      .numkey-fn { background: transparent; border: 0; }
    `}</style>
  </div>
);

const SignupConsent = ({ onNext, lang }) => {
  const [c1, setC1] = uS1(false);
  const [c2, setC2] = uS1(false);
  const points = [
    { icon: 'wallet', t: lang === 'jp' ? 'ポイント残高の管理と本人確認に使用します' : 'Used to manage your points balance and verify your identity' },
    { icon: 'link', t: lang === 'jp' ? '連携した提携先とのみ共有します（LifeCard、QUALIA）' : 'Shared only with partners you link (LifeCard, QUALIA)' },
    { icon: 'shield', t: lang === 'jp' ? '設定からいつでもデータをエクスポート・削除できます' : 'Export or delete your data anytime from Settings' },
  ];
  return (
    <div>
      <StepHead title={lang === 'jp' ? '続ける前に' : 'Before you continue'} sub={lang === 'jp' ? '日本の個人情報保護法に基づき、データの取り扱いについてご説明します。' : "Here's how QReward handles your data under Japan's Act on Protection of Personal Information."} />
      <div className="section-title">{lang === 'jp' ? 'データについて、わかりやすく' : 'Your data, plainly'}</div>
      <div style={{ padding: '0 16px' }}>
        {points.map((p, i) => (
          <div key={i} className="surface" style={{ display: 'flex', gap: 12, padding: 14, marginBottom: 10, alignItems: 'flex-start' }}>
            <div className="list-row-icon" style={{ width: 36, height: 36 }}><Icon n={p.icon} s={18} /></div>
            <div style={{ fontSize: 14, lineHeight: 1.5, paddingTop: 4 }}>{p.t}</div>
          </div>
        ))}
      </div>
      <div style={{ padding: '8px 20px' }}>
        <button style={{ display: 'flex', gap: 12, alignItems: 'center', marginBottom: 14, textAlign: 'left' }} onClick={() => setC1(!c1)}>
          <span className={`checkbox ${c1 ? 'checked' : ''}`}></span>
          <span style={{ fontSize: 14 }}>{lang === 'jp' ? '上記に同意します' : 'I agree to the above'}</span>
        </button>
        <button style={{ display: 'flex', gap: 12, alignItems: 'flex-start', textAlign: 'left' }} onClick={() => setC2(!c2)}>
          <span className={`checkbox ${c2 ? 'checked' : ''}`}></span>
          <span style={{ fontSize: 14, lineHeight: 1.5 }}>
            {lang === 'jp' ? '同意します：' : 'I agree to the '}
            <span style={{ color: 'var(--brand-600)', textDecoration: 'underline', fontWeight: 500 }}>{lang === 'jp' ? '利用規約' : 'Terms & Conditions'}</span>
            {lang === 'jp' ? '・' : ' and '}
            <span style={{ color: 'var(--brand-600)', textDecoration: 'underline', fontWeight: 500 }}>{lang === 'jp' ? 'プライバシーポリシー' : 'Privacy Policy'}</span>
          </span>
        </button>
      </div>
      <div className="cta-pinned" style={{ position: 'sticky' }}>
        <Btn block disabled={!c1 || !c2} onClick={onNext}>{lang === 'jp' ? '同意して続ける' : 'Agree & continue'}</Btn>
      </div>
    </div>
  );
};

const SignupPIN = ({ onNext, lang }) => {
  const [pin, setPin] = uS1([]);
  const [confirm, setConfirm] = uS1([]);
  const [phase, setPhase] = uS1('set'); // set | confirm
  const [err, setErr] = uS1(false);
  const cur = phase === 'set' ? pin : confirm;
  const press = (n) => {
    if (cur.length >= 6) return;
    const nc = [...cur, n];
    phase === 'set' ? setPin(nc) : setConfirm(nc);
    if (nc.length === 6) {
      setTimeout(() => {
        if (phase === 'set') { setPhase('confirm'); }
        else {
          if (nc.join('') === pin.join('')) { onNext(); }
          else { setErr(true); setTimeout(() => { setConfirm([]); setErr(false); }, 500); }
        }
      }, 150);
    }
  };
  const del = () => phase === 'set' ? setPin(pin.slice(0, -1)) : setConfirm(confirm.slice(0, -1));
  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
      <StepHead title={phase === 'set' ? (lang === 'jp' ? '取引用PINを設定' : 'Set your transaction PIN') : (lang === 'jp' ? 'PINを確認' : 'Confirm your PIN')}
        sub={lang === 'jp' ? '生体認証が使えないときの購入確認に使用します。' : 'Used to confirm marketplace purchases when biometrics are unavailable.'} />
      <div style={{ padding: '40px 0' }}>
        <div className={`pin`}>
          {[0, 1, 2, 3, 4, 5].map(i => <div key={i} className={`pin-dot ${cur.length > i ? (err ? 'error' : 'filled') : ''}`}></div>)}
        </div>
      </div>
      <div style={{ flex: 1 }}></div>
      <Numpad onPress={press} onDel={del} />
    </div>
  );
};

const SignupBiometric = ({ onNext, lang }) => (
  <div style={{ display: 'flex', flexDirection: 'column', height: '100%', textAlign: 'center' }}>
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', padding: '0 32px' }}>
      <div style={{ width: 120, height: 120, borderRadius: 32, background: 'linear-gradient(135deg, #eef3ff, #dce8ff)', display: 'grid', placeItems: 'center', marginBottom: 24 }}>
        <Icon n="faceId" s={56} c="var(--brand-600)" sw={1.6} />
      </div>
      <div className="h2">{lang === 'jp' ? 'Face IDで\nすばやくサインイン' : 'Sign in faster\nwith Face ID'}</div>
      <div className="muted" style={{ fontSize: 15, marginTop: 12, lineHeight: 1.55, whiteSpace: 'pre-line' }}>
        {lang === 'jp' ? '次回からワンタップでサインイン。\n設定からいつでも変更できます。' : 'Skip the password next time. This is optional and you can change it anytime in Settings.'}
      </div>
    </div>
    <div style={{ padding: '12px 20px 28px' }}>
      <Btn block icon="faceId" onClick={onNext}>{lang === 'jp' ? 'Face IDを有効化' : 'Enable Face ID'}</Btn>
      <button style={{ width: '100%', textAlign: 'center', padding: 14, color: 'var(--fg-muted)', fontWeight: 500, fontSize: 15 }} onClick={onNext}>{lang === 'jp' ? '後で設定' : 'Skip for now'}</button>
    </div>
  </div>
);

const SignupQualia = ({ onNext, lang }) => (
  <div style={{ display: 'flex', flexDirection: 'column', height: '100%', textAlign: 'center' }}>
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', padding: '0 32px' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 14, marginBottom: 24 }}>
        <div className="linked-logo" style={{ background: '#7c3aed', width: 60, height: 60, fontSize: 24 }}>Q</div>
        <Icon n="link" s={22} c="var(--fg-subtle)" />
        <div className="linked-logo" style={{ background: 'linear-gradient(135deg,#1f4fd1,#1b2d6f)', width: 60, height: 60, fontSize: 24 }}><span style={{ fontFamily: 'Georgia', fontStyle: 'italic' }}>r</span></div>
      </div>
      <div className="h2">{lang === 'jp' ? 'QUALIA会員IDを\n連携' : 'Link your QUALIA\nmember ID'}</div>
      <div className="muted" style={{ fontSize: 15, marginTop: 12, lineHeight: 1.55, whiteSpace: 'pre-line' }}>
        {lang === 'jp' ? 'ポイントの同期や取引履歴の表示ができます。' : 'Sync your points and see your full transaction history automatically.'}
      </div>
    </div>
    <div style={{ padding: '12px 20px 28px' }}>
      <Btn block icon="link" onClick={onNext}>{lang === 'jp' ? '今すぐ連携' : 'Link now'}</Btn>
      <button style={{ width: '100%', textAlign: 'center', padding: 14, color: 'var(--fg-muted)', fontWeight: 500, fontSize: 15 }} onClick={onNext}>{lang === 'jp' ? '後で連携する' : "I'll do this later"}</button>
    </div>
  </div>
);

const SignupWelcome = ({ onDone, lang }) => {
  uE1(() => { const t = setTimeout(onDone, 2400); return () => clearTimeout(t); }, []);
  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', justifyContent: 'center', alignItems: 'center', textAlign: 'center', padding: '0 32px', position: 'relative', overflow: 'hidden' }} onClick={onDone}>
      <Confetti />
      <div style={{ animation: 'cardRise 1.2s cubic-bezier(0.2,0.8,0.2,1)', width: '100%', maxWidth: 280, marginBottom: 28 }}>
        <QCard balance={DATA.balance} lifecard={DATA.lifecard} qualia={DATA.qualia} lang={lang} tilt={false} />
      </div>
      <div className="h2" style={{ animation: 'fadeUp 600ms ease 400ms both' }}>{lang === 'jp' ? `ようこそ、${DATA.user.nameJp}さん` : `Welcome to QReward, ${DATA.user.name}`}</div>
      <div className="muted" style={{ fontSize: 15, marginTop: 8, animation: 'fadeUp 600ms ease 600ms both' }}>{lang === 'jp' ? 'すべての準備が整いました。' : "You're all set. Let's go."}</div>
      <style>{`
        @keyframes cardRise { from { transform: translateY(80px) scale(0.9); opacity: 0; } to { transform: translateY(0) scale(1); opacity: 1; } }
        @keyframes fadeUp { from { transform: translateY(8px); opacity: 0; } to { transform: translateY(0); opacity: 1; } }
      `}</style>
    </div>
  );
};

const Confetti = () => {
  const bits = Array.from({ length: 28 });
  const colors = ['#1f4fd1', '#f5b942', '#5eea98', '#ec4899', '#8b5cf6'];
  return (
    <div className="confetti-bg">
      {bits.map((_, i) => {
        const left = Math.random() * 100, delay = Math.random() * 0.5, dur = 1.4 + Math.random() * 1.2;
        const c = colors[i % colors.length], size = 6 + Math.random() * 6;
        return <div key={i} style={{ position: 'absolute', left: left + '%', top: '-20px', width: size, height: size * 1.4, background: c, borderRadius: 1, animation: `fall ${dur}s ease-in ${delay}s infinite` }}></div>;
      })}
      <style>{`@keyframes fall { to { transform: translateY(560px) rotate(420deg); opacity: 0; } }`}</style>
    </div>
  );
};

Object.assign(window, { SplashScreen, TourScreen, LoginScreen, SignupFlow });
