// App principal — orquestra estado, navegação e telas

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "cream",
  "serifSize": 26,
  "showTrialBanner": true,
  "verseLayout": "centered"
}/*EDITMODE-END*/;

const PALETTES = {
  cream:  { '--cream':'#faf5e9','--cream-2':'#f5ecd3','--paper':'#fffaf0','--ink':'#2a2114','--ink-soft':'#5a4a30','--gold':'#b58a48','--gold-deep':'#7a5a30','--gold-soft':'#e7d3a3','--night':'#2a2540' },
  ivory:  { '--cream':'#f9f6f0','--cream-2':'#efe8d8','--paper':'#ffffff','--ink':'#1f1d1a','--ink-soft':'#4a463e','--gold':'#a8895a','--gold-deep':'#6e5836','--gold-soft':'#dccba6','--night':'#1d2536' },
  rose:   { '--cream':'#faf2ec','--cream-2':'#f3e2d4','--paper':'#fffaf6','--ink':'#2a1d1a','--ink-soft':'#5a3f36','--gold':'#b87862','--gold-deep':'#85503e','--gold-soft':'#e8c5b0','--night':'#3a2530' },
  sage:   { '--cream':'#f3f3ea','--cream-2':'#dde4d2','--paper':'#fdfdf7','--ink':'#1f261a','--ink-soft':'#3f4a36','--gold':'#83936a','--gold-deep':'#576443','--gold-soft':'#c4d2a8','--night':'#1f3030' },
};

// Hotmart checkout links (one per plan)
const HOTMART_LINKS = {
  monthly: 'https://pay.hotmart.com/A105754709Y?off=2rvj1rlg',
  yearly:  'https://pay.hotmart.com/A105754709Y?off=h0efzjr5',
};
function goToHotmart(plan, email) {
  const base = HOTMART_LINKS[plan] || HOTMART_LINKS.yearly;
  const sep = base.includes('?') ? '&' : '?';
  // Pre-fill buyer email on Hotmart checkout so the webhook can match the account
  const url = `${base}${sep}email=${encodeURIComponent(email || '')}&checkoutMode=10`;
  window.location.href = url;
}

const { useState, useEffect, useMemo, useRef } = React;

function App() {
  const [tw, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [lang, setLangRaw] = useState(() => {
    const saved = localStorage.getItem('mv_lang');
    if (saved === 'pt' || saved === 'en' || saved === 'es') return saved;
    const nav = (navigator.language || 'pt').toLowerCase();
    if (nav.startsWith('en')) return 'en';
    if (nav.startsWith('es')) return 'es';
    return 'pt';
  });
  const setLang = (v) => { localStorage.setItem('mv_lang', v); setLangRaw(v); };
  const [route, setRoute] = useState('landing'); // landing | auth | app | paywall | checkout
  const [authMode, setAuthMode] = useState('signup');
  const [plan, setPlan] = useState('yearly'); // monthly | yearly
  const [tab, setTab] = useState('home'); // home | special | history | favorites | settings
  const [user, setUser] = useState(null);
  const [profile, setProfile] = useState(null);
  const [favs, setFavs] = useState([]);
  const [hist, setHist] = useState([]);
  const [share, setShare] = useState(null);
  const [favDetail, setFavDetail] = useState(null);
  const [randomSeed, setRandomSeed] = useState(Math.random());
  const [verifyingPayment, setVerifyingPayment] = useState(false);
  const [newPassword, setNewPassword] = useState('');
  const [resettingPw, setResettingPw] = useState(false);
  const [resetDone, setResetDone] = useState(false);

  // boot: restaurar sessão + detectar retorno do Hotmart (?paid=1)
  useEffect(() => {
    (async () => {
      // ⚠️ Verificar recovery PRIMEIRO — antes de qualquer getSession
      const hash = window.location.hash;
      const searchParams = new URLSearchParams(window.location.search);
      if (hash.includes('type=recovery') ||
          searchParams.get('type') === 'recovery' ||
          (hash.includes('access_token') && !searchParams.get('paid'))) {
        setRoute('reset-password');
        window.history.replaceState({}, '', window.location.pathname);
        return;
      }

      const s = await window.DB.getSession();
      if (s) {
        setUser(s.user); setProfile(s.profile);
        if (s.profile?.language) setLang(s.profile.language);
        setFavs(await window.DB.listFavorites());
        setHist(await window.DB.listHistory());
        setRoute('app');
        // Setup push também ao restaurar sessão
      }

      // Quando voltar do checkout Hotmart, mostra "verificando" e re-busca o perfil
      const params = new URLSearchParams(window.location.search);
      if (params.get('paid') === '1') {
        setVerifyingPayment(true);
        const start = Date.now();
        const tick = async () => {
          const ns = await window.DB.getSession();
          if (ns?.profile?.subscription_status === 'active') {
            setProfile(ns.profile); setUser(ns.user);
            setVerifyingPayment(false); setRoute('app');
            window.history.replaceState({}, '', window.location.pathname);
            return;
          }
          if (Date.now() - start < 90000) setTimeout(tick, 3000);
          else { setVerifyingPayment(false); window.history.replaceState({}, '', window.location.pathname); }
        };
        setTimeout(tick, 1500);
      }
    })();
  }, []);

  const t = window.I18N[lang];

  // Aplicar paleta
  useEffect(() => {
    const p = PALETTES[tw.palette] || PALETTES.cream;
    Object.entries(p).forEach(([k, v]) => document.documentElement.style.setProperty(k, v));
  }, [tw.palette]);

  // Trial logic
  const trialDaysLeft = useMemo(() => {
    if (!profile?.trial_started_at) return 0;
    const started = new Date(profile.trial_started_at);
    const now = new Date();
    const days = Math.floor((now - started) / 86400000);
    return Math.max(0, 7 - days);
  }, [profile]);
  const isTrialExpired = profile?.subscription_status !== 'active' && trialDaysLeft === 0 && !!profile;

  // Persistir lang quando muda
  useEffect(() => {
    if (profile && profile.language !== lang) {
      window.DB.updateProfile({ language: lang }).then(setProfile);
    }
  }, [lang]);

  // Re-busca perfil periodicamente e quando usuário volta para a aba
  // Garante que trial expirado e assinaturas ativas sejam detectados sem recarregar
  useEffect(() => {
    if (!user) return;

    async function refreshProfile() {
      try {
        const s = await window.DB.getSession();
        if (s?.profile) setProfile(s.profile);
      } catch (e) {}
    }

    // A cada 30 minutos
    const interval = setInterval(refreshProfile, 30 * 60 * 1000);

    // Imediatamente ao voltar para a aba
    const onVisible = () => {
      if (document.visibilityState === 'visible') refreshProfile();
    };
    document.addEventListener('visibilitychange', onVisible);

    return () => {
      clearInterval(interval);
      document.removeEventListener('visibilitychange', onVisible);
    };
  }, [user]);

  // Registrar visualização no histórico
  useEffect(() => {
    if (route !== 'app' || !user) return;
    const today = new Date();
    const data = tab === 'special' ? window.getRandomVerse(randomSeed) : window.getVerseForDate(today);
    if (tab === 'home' || tab === 'special') {
      window.DB.addHistory({
        verse_ref: data.verse.ref[lang],
        theme_id: data.theme.id,
        kind: tab === 'special' ? 'random' : 'daily',
      }).then(setHist);
    }
  }, [tab, randomSeed, route, user, lang]);

  function handleAuth(res) {
    setUser(res.user); setProfile(res.profile);
    if (res.profile?.language) setLang(res.profile.language);
    setRoute('app'); setTab('home');
    window.DB.listFavorites().then(setFavs);
    window.DB.listHistory().then(setHist);
  }

  async function handleSignOut() {
    await window.DB.signOut();
    setUser(null); setProfile(null); setRoute('landing');
  }

  const isFav = (ref) => favs.some(f => f.verse_ref === ref);
  async function toggleFav(item) {
    try {
      if (isFav(item.verse_ref)) setFavs(await window.DB.removeFavorite(item.verse_ref));
      else setFavs(await window.DB.addFavorite(item));
    } catch (e) {
      console.error('[favorites] toggle failed:', e);
      alert(e.message || 'Não foi possível salvar o favorito.');
    }
  }

  async function completeSubscription(chosenPlan = 'yearly') {
    const until = new Date();
    if (chosenPlan === 'monthly') until.setMonth(until.getMonth() + 1);
    else until.setFullYear(until.getFullYear() + 1);
    const np = await window.DB.updateProfile({
      subscription_status: 'active',
      subscription_until: until.toISOString(),
      plan: chosenPlan,
    });
    setProfile(np);
    setRoute('app');
  }

  async function setupPushNotifications(userId, userLang) {
    if (!('Notification' in window) || !('serviceWorker' in navigator)) return;

    const isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);
    const isStandalone = window.navigator.standalone === true;

    if (isIOS && !isStandalone) {
      const msg = {
        en: '📱 To receive daily verse notifications, add this app to your Home Screen.\n\nTap Share → "Add to Home Screen"',
        pt: '📱 Para receber notificações do versículo diário, adicione este app à sua tela inicial.\n\nToque em Compartilhar → "Adicionar à tela de início"',
        es: '📱 Para recibir notificaciones del versículo diario, agrega esta app a tu pantalla de inicio.\n\nToca Compartir → "Agregar a la pantalla de inicio"',
      }[userLang] || '';
      setTimeout(() => alert(msg), 1000);
      return;
    }

    try {
      // Registra o SW se ainda não estiver
      const reg = await navigator.serviceWorker.register('/sw.js');
      await navigator.serviceWorker.ready;

      // Pede permissão
      const permission = await Notification.requestPermission();
      if (permission !== 'granted') return;

      // Verifica se já tem subscription
      const existing = await reg.pushManager.getSubscription();
      if (existing) return;

      // Cria subscription
      const sub = await reg.pushManager.subscribe({
        userVisibleOnly: true,
        applicationServerKey: urlBase64ToUint8Array(window.__VAPID_PUBLIC_KEY__),
      });

      // Salva via DB já autenticado
      await window.DB.savePushSubscription({ user_id: userId, subscription: sub.toJSON(), lang: userLang });
    } catch (e) {
      console.error('[push]', e);
    }
  }

  function urlBase64ToUint8Array(base64String) {
    const padding = '='.repeat((4 - base64String.length % 4) % 4);
    const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');
    const raw = atob(base64);
    return new Uint8Array([...raw].map(c => c.charCodeAt(0)));
  }

  // Render
  let screen;
  if (route === 'landing') {
    screen = <Landing t={t} lang={lang} setLang={setLang}
      onStart={() => { setAuthMode('signup'); setRoute('auth'); }}
      onSignIn={() => { setAuthMode('signin'); setRoute('auth'); }} />;
  } else if (route === 'auth') {
    screen = <Auth t={t} lang={lang} setLang={setLang} mode={authMode}
      onAuth={handleAuth} onBack={() => setRoute('landing')}
      onForgot={() => setRoute('forgot')}
      onToggle={() => setAuthMode(authMode === 'signup' ? 'signin' : 'signup')} />;
  } else if (route === 'reset-password') {
    screen = (
      <div style={{ height:'100%', overflowY:'auto', background:'var(--cream)', color:'var(--ink)', display:'flex', alignItems:'center', justifyContent:'center', padding:24 }}>
        <div style={{ width:'100%', maxWidth:340 }}>
          <div style={{ textAlign:'center', marginBottom:24 }}>
            <div style={{ fontSize:40, color:'var(--gold)' }}>✧</div>
            <h2 style={{ fontFamily:'var(--serif)', fontSize:28, margin:'12px 0 8px' }}>
              {lang==='pt' ? 'Nova senha' : lang==='es' ? 'Nueva contraseña' : 'New password'}
            </h2>
            <p style={{ fontSize:14, color:'var(--ink-soft)' }}>
              {lang==='pt' ? 'Digite sua nova senha abaixo.' : lang==='es' ? 'Ingresa tu nueva contraseña.' : 'Enter your new password below.'}
            </p>
          </div>
          {resetDone ? (
            <div style={{ textAlign:'center' }}>
              <p style={{ color:'var(--gold-deep)', marginBottom:16 }}>✓ {lang==='pt' ? 'Senha atualizada!' : lang==='es' ? '¡Contraseña actualizada!' : 'Password updated!'}</p>
              <button className="mv-btn-primary" onClick={() => { setResetDone(false); setRoute('auth'); setAuthMode('signin'); }}>
                {lang==='pt' ? 'Entrar' : lang==='es' ? 'Entrar' : 'Sign in'}
              </button>
            </div>
          ) : (
            <div className="mv-form">
              <label className="mv-field">
                <span>{lang==='pt' ? 'Nova senha' : lang==='es' ? 'Nueva contraseña' : 'New password'}</span>
                <input type="password" value={newPassword} onChange={e => setNewPassword(e.target.value)} minLength={6} required autoFocus />
              </label>
              <button className="mv-btn-primary mv-btn-lg" disabled={resettingPw || newPassword.length < 6}
                onClick={async () => {
                  setResettingPw(true);
                  try {
                    const sb = window.supabase.createClient(window.__SUPABASE_URL__, window.__SUPABASE_KEY__);
                    const { error } = await sb.auth.updateUser({ password: newPassword });
                    if (error) throw error;
                    setResetDone(true);
                  } catch(e) { alert(e.message); }
                  finally { setResettingPw(false); }
                }}>
                {resettingPw ? '…' : (lang==='pt' ? 'Salvar nova senha' : lang==='es' ? 'Guardar contraseña' : 'Save new password')}
              </button>
            </div>
          )}
        </div>
      </div>
    );
  } else if (route === 'forgot') {
    screen = <ForgotPassword t={t} lang={lang} setLang={setLang}
      onBack={() => { setAuthMode('signin'); setRoute('auth'); }} />;
  } else if (route === 'paywall') {
    screen = <Paywall t={t} plan={plan} setPlan={setPlan}
      onSubscribe={(p) => { setPlan(p); goToHotmart(p, user?.email); }}
      onClose={() => setRoute('app')} />;
  } else {
    // App
    if (isTrialExpired && tab !== 'settings') {
      screen = <Paywall t={t} plan={plan} setPlan={setPlan}
        onSubscribe={(p) => { setPlan(p); goToHotmart(p, user?.email); }}
        onClose={() => setTab('settings')} />;
    } else {
      screen = (
        <div className="mv-app">
          <div className="mv-app-bg" />
          <div className="mv-app-top">
            <span className="mv-app-brand"><span className="mv-brand-mark">✧</span> Meu Versículo</span>
            <LangSwitch lang={lang} setLang={setLang} compact />
          </div>
          {tw.showTrialBanner && profile?.subscription_status !== 'active' && trialDaysLeft > 0 && (
            <div className="mv-trial-banner">
              <span>{trialDaysLeft} {t.trial_left}</span>
              <button onClick={() => setRoute('paywall')}>{t.upgrade}</button>
            </div>
          )}
          <div className="mv-app-content" style={{ '--mv-serif-size': tw.serifSize + 'px' }}>
            {tab === 'home' && <VerseScreen t={t} lang={lang} mode="daily" profile={profile}
              onShare={setShare} onFavToggle={toggleFav} isFav={isFav} animateOnMount={true} />}
            {tab === 'special' && <VerseScreen t={t} lang={lang} mode="random" profile={profile}
              onShare={setShare} onFavToggle={toggleFav} isFav={isFav}
              randomSeed={randomSeed} onNewRandom={() => setRandomSeed(Math.random())} animateOnMount={true} />}
            {tab === 'history' && (
              <ListScreen t={t} lang={lang} kind="hist" items={hist} emptyText={t.no_history}
                onOpen={() => setTab('home')} />
            )}
            {tab === 'favorites' && (
              <ListScreen t={t} lang={lang} kind="fav" items={favs} emptyText={t.no_favorites}
                onOpen={(item) => setFavDetail(item)} />
            )}
            {tab === 'settings' && <Settings t={t} lang={lang} setLang={setLang} profile={{ ...profile, email: user?.email }}
              trialDaysLeft={trialDaysLeft} onSignOut={handleSignOut}
              onUpgrade={() => setRoute('paywall')}
              onEnableNotifications={() => setupPushNotifications(user?.id, lang)} />}
          </div>
          <nav className="mv-tabs">
            <TabBtn label={t.home} on={tab === 'home'} onClick={() => setTab('home')} icon={
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M3 9.5L12 3l9 6.5V20a1 1 0 0 1-1 1h-5v-7H9v7H4a1 1 0 0 1-1-1V9.5z"/></svg>
            }/>
            <TabBtn label={t.special} on={tab === 'special'} onClick={() => setTab('special')} icon={
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1"/><circle cx="12" cy="12" r="4"/></svg>
            }/>
            <TabBtn label={t.favorites} on={tab === 'favorites'} onClick={() => setTab('favorites')} icon={
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg>
            }/>
            <TabBtn label={t.settings} on={tab === 'settings'} onClick={() => setTab('settings')} icon={
              <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09a1.65 1.65 0 0 0-1-1.51 1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09a1.65 1.65 0 0 0 1.51-1 1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
            }/>
          </nav>
          {share && <Share t={t} lang={lang} payload={share} onClose={() => setShare(null)} />}
          {favDetail && <FavDetail lang={lang} item={favDetail} onClose={() => setFavDetail(null)}
            onShare={(item) => { setShare({ text: item.text, ref: item.verse_ref, theme: window.THEMES?.find(x => x.id === item.theme_id)?.[lang] || '', themeId: item.theme_id }); }} />}
        </div>
      );
    }
  }

  // Frame só envolve o app autenticado
  const showFrame = route !== 'landing';
  const stage = (
    <div className="mv-stage">
      <div className="mv-frame-wrap">
        <div className="mv-stage-meta">
          <span className="mv-stage-tag">Meu Versículo</span>
          <h1>{t.landing_title}</h1>
          <p style={{ marginTop: 14 }}>
            {window.DB_MODE === 'supabase' ? 'Conectado ao Supabase.' : 'Modo local — dados salvos no navegador para o protótipo.'}
          </p>
        </div>
        {showFrame ? (
          <IOSDevice><IOSStatusBar /><div style={{ flex: 1, minHeight: 0, overflow: 'hidden' }}>{screen}</div></IOSDevice>
        ) : null}
      </div>
    </div>
  );

  return (
    <>
      {verifyingPayment && (
        <div style={{position:'fixed',inset:0,background:'rgba(20,16,8,0.85)',color:'#f5ecd3',display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',zIndex:9999,fontFamily:'var(--sans)',padding:24,textAlign:'center'}}>
          <div style={{fontSize:54,color:'#e7d3a3',marginBottom:18,fontFamily:'Cormorant Garamond, serif'}}>✦</div>
          <div style={{fontSize:22,marginBottom:8,fontFamily:'Cormorant Garamond, serif'}}>{lang==='en'?'Verifying your payment…':lang==='es'?'Verificando tu pago…':'Verificando seu pagamento…'}</div>
          <div style={{fontSize:14,opacity:0.75,maxWidth:340}}>{lang==='en'?'This usually takes a few seconds.':lang==='es'?'Esto suele tardar unos segundos.':'Isso costuma levar alguns segundos.'}</div>
        </div>
      )}
      {route === 'landing' ? screen : stage}
      <TweaksPanel>
        <TweakSection label="Paleta" />
        <TweakRadio label="Cor" value={tw.palette} options={['cream','ivory','rose','sage']}
          onChange={(v) => setTweak('palette', v)} />
        <TweakSection label="Tipografia" />
        <TweakSlider label="Tamanho do versículo" value={tw.serifSize} min={20} max={34} unit="px"
          onChange={(v) => setTweak('serifSize', v)} />
        <TweakSection label="App" />
        <TweakToggle label="Banner de trial" value={tw.showTrialBanner}
          onChange={(v) => setTweak('showTrialBanner', v)} />
      </TweaksPanel>
    </>
  );
}

function TabBtn({ label, on, onClick, icon }) {
  return (
    <button className={'mv-tab' + (on ? ' is-on' : '')} onClick={onClick}>
      {icon}<span>{label}</span>
    </button>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
