// Real Supabase auth — Google OAuth + magic link email
const { useState: auS, useEffect: auE } = React;

// ---- Supabase client (lazy singleton, fetches config from server) ----
let _sbClient = null;
let _sbPromise = null;

function getSupabase() {
  if (_sbClient) return Promise.resolve(_sbClient);
  if (_sbPromise) return _sbPromise;
  _sbPromise = fetch('/api/config')
    .then(r => r.json())
    .then(cfg => {
      if (!cfg.supabaseUrl || !cfg.supabaseAnonKey) return null;
      _sbClient = window.supabase.createClient(cfg.supabaseUrl, cfg.supabaseAnonKey);
      return _sbClient;
    })
    .catch(() => null);
  return _sbPromise;
}

// Exposed globally so session.jsx can get the current access token
window.MH_getToken = async () => {
  const sb = await getSupabase();
  if (!sb) return null;
  const { data: { session } } = await sb.auth.getSession();
  return session?.access_token || null;
};

// ---- Credits (localStorage, keyed by userId so users don't share credits) ----
const CREDIT_CAP = Infinity; // no upper limit — server is authoritative

function creditsKey(userId) {
  return userId ? `mh-credits-${userId}` : 'mh-credits';
}

const AuthStore = {
  getCredits(userId) { return parseInt(localStorage.getItem(creditsKey(userId)) || '0', 10); },
  setCredits(userId, v) { localStorage.setItem(creditsKey(userId), String(Math.max(0, Math.min(CREDIT_CAP, v)))); },
  get plan() { return localStorage.getItem('mh-plan') || 'free'; },
  set plan(v) { localStorage.setItem('mh-plan', v); },
  get invite() { return localStorage.getItem('mh-invite') || ''; },
  set invite(v) { localStorage.setItem('mh-invite', v || ''); },
  get history() { try { return JSON.parse(localStorage.getItem('mh-history') || '[]'); } catch { return []; } },
  set history(v) { localStorage.setItem('mh-history', JSON.stringify(v.slice(-50))); },
};

function pushHistory(entry) {
  const h = AuthStore.history;
  h.push({ ts: Date.now(), ...entry });
  AuthStore.history = h;
  window.dispatchEvent(new Event('mh-auth-change'));
}

window.MH_Auth = {
  async signOut() {
    const sb = await getSupabase();
    if (sb) await sb.auth.signOut();
    window.dispatchEvent(new Event('mh-auth-change'));
  },
  addCredits(userId, n, note) {
    const cur = AuthStore.getCredits(userId);
    AuthStore.setCredits(userId, cur + n);
    pushHistory({ type: 'credit-add', amount: n, note });
  },
  syncCredits(userId, minutes) {
    AuthStore.setCredits(userId, minutes);
    window.dispatchEvent(new Event('mh-auth-change'));
  },
  setPlan(plan, note) {
    AuthStore.plan = plan;
    pushHistory({ type: 'plan', note: plan + (note ? ' · ' + note : '') });
  },
  applyInvite(code) {
    AuthStore.invite = code;
    pushHistory({ type: 'invite', note: code });
  },
};

// ---- useAuth hook ----
function useAuth() {
  const [user, setUser] = auS(null);
  const [loading, setLoading] = auS(true);
  const [, forceRender] = auS(0);

  auE(() => {
    let subscription;
    getSupabase().then(sb => {
      if (!sb) { setLoading(false); return; }
      sb.auth.getSession().then(({ data: { session } }) => {
        setUser(session?.user ?? null);
        setLoading(false);
      });
      const { data } = sb.auth.onAuthStateChange((event, session) => {
        setUser(session?.user ?? null);
        setLoading(false);
        // Notify app when user freshly signs in (magic link or OAuth redirect)
        if (event === 'SIGNED_IN') {
          window.dispatchEvent(new CustomEvent('mh-signed-in'));
        }
      });
      subscription = data.subscription;
    });
    const handler = () => forceRender(x => x + 1);
    window.addEventListener('mh-auth-change', handler);
    return () => {
      subscription?.unsubscribe();
      window.removeEventListener('mh-auth-change', handler);
    };
  }, []);

  // Sync credits from server when user loads
  auE(() => {
    if (!user) return;
    window.MH_getToken().then(token => {
      if (!token) return;
      fetch('/api/credits', { headers: { 'Authorization': `Bearer ${token}` } })
        .then(r => r.json())
        .then(data => { AuthStore.setCredits(user.id, data.minutes); forceRender(x => x + 1); })
        .catch(() => {});
    });
  }, [user?.id]);

  const credits = AuthStore.getCredits(user?.id);
  const plan = AuthStore.plan;
  const invite = AuthStore.invite;

  return {
    user,
    loading,
    credits,
    plan,
    invite,
    history: AuthStore.history,
    isOwner: !!invite || plan === 'pro',
    canStartSession: plan === 'pro' || !!invite || credits > 0,
    minutes: credits,
  };
}
window.useAuth = useAuth;

// ---- Login Modal ----
function LoginModal({ open, onClose }) {
  const [step, setStep] = auS('intro'); // intro | email | sent | loading | error
  const [email, setEmail] = auS('');
  const [errorMsg, setErrorMsg] = auS('');

  auE(() => {
    if (open) { setStep('intro'); setEmail(''); setErrorMsg(''); }
  }, [open]);

  if (!open) return null;

  const redirectTo = window.location.origin + window.location.pathname;

  const signInWithGoogle = async () => {
    setStep('loading');
    const sb = await getSupabase();
    if (!sb) { setErrorMsg('Supabase не налаштований'); setStep('error'); return; }
    const { error } = await sb.auth.signInWithOAuth({
      provider: 'google',
      options: { redirectTo },
    });
    if (error) { setErrorMsg(error.message); setStep('error'); }
  };

  const signInWithEmail = async () => {
    const trimmed = email.trim();
    if (!trimmed) return;
    setStep('loading');
    const sb = await getSupabase();
    if (!sb) { setErrorMsg('Supabase не налаштований'); setStep('error'); return; }
    const { error } = await sb.auth.signInWithOtp({
      email: trimmed,
      options: { emailRedirectTo: redirectTo },
    });
    if (error) { setErrorMsg(error.message); setStep('email'); }
    else setStep('sent');
  };

  return (
    <div className="modal-backdrop" onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="modal login-modal">
        <button className="modal-x" onClick={onClose}>×</button>

        {step === 'intro' && (
          <React.Fragment>
            <div className="login-head">
              <span className="brand-mark big">M</span>
              <h2>Увійти в Meeting Helper</h2>
              <p>Зберігай кредити та налаштування між пристроями.</p>
            </div>
            <button className="g-btn" onClick={signInWithGoogle}>
              <GoogleG />
              <span>Продовжити з Google</span>
            </button>
            <p className="login-foot">Ми не записуємо твої дзвінки. Жодних паролів.</p>
          </React.Fragment>
        )}

        {step === 'email' && (
          <React.Fragment>
            <div className="login-head">
              <h2>Увійти через email</h2>
              <p>Відправимо посилання — натиснеш і одразу в системі.</p>
            </div>
            {errorMsg && (
              <div style={{ background: '#fef2f2', border: '1px solid #fecaca', borderRadius: 8, padding: '10px 12px', marginBottom: 10, fontSize: 13.5, color: '#b91c1c' }}>
                {errorMsg.includes('429') || errorMsg.toLowerCase().includes('rate') || errorMsg.toLowerCase().includes('too many')
                  ? 'Занадто багато спроб. Зачекай кілька хвилин і спробуй знову.'
                  : errorMsg}
              </div>
            )}
            <div className="form-row" style={{ marginBottom: 8 }}>
              <input
                type="email"
                placeholder="your@email.com"
                value={email}
                onChange={e => setEmail(e.target.value)}
                onKeyDown={e => e.key === 'Enter' && signInWithEmail()}
                autoFocus
                style={{ width: '100%', padding: '10px 12px', border: '1px solid #d4d4d8', borderRadius: 8, fontSize: 15, outline: 'none', boxSizing: 'border-box' }}
              />
            </div>
            <button className="btn btn-primary" style={{ width: '100%', padding: '12px' }} onClick={signInWithEmail} disabled={!email.trim()}>
              Надіслати посилання
            </button>
            <button className="link-back" onClick={() => setStep('intro')}>← назад</button>
          </React.Fragment>
        )}

        {step === 'sent' && (
          <div style={{ textAlign: 'center', padding: '24px 0' }}>
            <div style={{ fontSize: 40, marginBottom: 12 }}>✉</div>
            <h2 style={{ margin: '0 0 8px' }}>Перевір пошту</h2>
            <p style={{ color: '#64748b', margin: 0 }}>Відправили посилання на <b>{email}</b>.<br />Натисни — і ти в системі.</p>
            <button className="link-back" style={{ marginTop: 20 }} onClick={onClose}>Закрити</button>
          </div>
        )}

        {step === 'loading' && (
          <div className="g-loading">
            <GoogleG large />
            <div className="dots"><span /><span /><span /></div>
            <div className="g-loading-text">Входимо…</div>
          </div>
        )}

        {step === 'error' && (
          <div style={{ textAlign: 'center', padding: '24px 0' }}>
            <p style={{ color: '#ef4444', marginBottom: 16 }}>{errorMsg}</p>
            <button className="btn btn-ghost" onClick={() => setStep('intro')}>← Назад</button>
          </div>
        )}
      </div>
    </div>
  );
}
window.LoginModal = LoginModal;

function GoogleG({ large }) {
  const s = large ? 36 : 18;
  return (
    <svg width={s} height={s} viewBox="0 0 48 48" aria-hidden>
      <path fill="#4285F4" d="M45.12 24.5c0-1.56-.14-3.06-.4-4.5H24v8.51h11.84c-.51 2.75-2.06 5.08-4.39 6.64v5.52h7.11c4.16-3.83 6.56-9.47 6.56-16.17z"/>
      <path fill="#34A853" d="M24 46c5.94 0 10.92-1.97 14.56-5.33l-7.11-5.52c-1.97 1.32-4.49 2.1-7.45 2.1-5.73 0-10.58-3.87-12.31-9.07H4.34v5.7C7.96 41.07 15.4 46 24 46z"/>
      <path fill="#FBBC05" d="M11.69 28.18c-.44-1.32-.69-2.73-.69-4.18s.25-2.86.69-4.18v-5.7H4.34A21.99 21.99 0 0 0 2 24c0 3.55.85 6.91 2.34 9.88l7.35-5.7z"/>
      <path fill="#EA4335" d="M24 10.75c3.23 0 6.13 1.11 8.41 3.29l6.31-6.31C34.91 4.18 29.93 2 24 2 15.4 2 7.96 6.93 4.34 14.12l7.35 5.7C13.42 14.62 18.27 10.75 24 10.75z"/>
    </svg>
  );
}

// ---- Wallet page ----
function Wallet({ onBack, onBuyPack, onBuyPro, onBuySingle, t }) {
  const a = useAuth();
  const u = a.user;
  const name = u?.user_metadata?.full_name || u?.email?.split('@')[0] || 'Гість';
  const avatarLetter = (u?.user_metadata?.full_name || u?.email || '?')[0].toUpperCase();
  const planLabel = a.invite ? 'Invited (unlimited)' : a.plan === 'pro' ? 'Pro · unlimited' : a.plan === 'pack' ? 'Pack' : 'Free';
  const atCap = false;

  return (
    <div className="wallet-page">
      <header className="topbar">
        <div className="topbar-inner">
          <a className="brand" href="#" onClick={(e) => { e.preventDefault(); onBack(); }}>
            <span className="brand-mark">M</span>
            Meeting Helper
          </a>
          <div className="topbar-spacer" />
          <button className="btn btn-ghost" onClick={onBack}>← Back</button>
        </div>
      </header>
      <div className="wallet-wrap">
        <div className="wallet-grid">
          <section className="wallet-card profile-card">
            <div className="profile-row">
              <div className="profile-avatar" style={{ background: u ? '#2563eb' : '#cbd5e1' }}>{u ? avatarLetter : '?'}</div>
              <div className="profile-meta">
                <div className="profile-name">{u ? name : 'Не увійшов'}</div>
                <div className="profile-email">{u ? u.email : 'Увійди щоб зберігати кредити між пристроями'}</div>
              </div>
              {u && <button className="btn btn-ghost btn-sm" onClick={() => window.MH_Auth.signOut()}>Sign out</button>}
            </div>
            <div className="profile-plan">
              <span className={"plan-pill plan-" + (a.invite ? 'invited' : a.plan)}>{planLabel}</span>
              {a.invite && <span className="invite-note">via invite: <code>{a.invite}</code></span>}
            </div>
          </section>

          <section className="wallet-card credits-card">
            <div className="credits-top">
              <div>
                <div className="credits-label">Minutes available</div>
                <div className="credits-big">{a.invite || a.plan === 'pro' ? '∞' : a.credits}<span style={{ fontSize: 18, color: '#94a3b8', fontWeight: 500, marginLeft: 6 }}>min</span></div>
                <div className="credits-sub">{a.invite || a.plan === 'pro' ? 'Unlimited' : `~${Math.floor(a.credits / 60)} h ${a.credits % 60} min · don't expire`}</div>
              </div>
              <div className="credits-actions">
                <button className="btn btn-primary btn-sm" onClick={onBuyPack} disabled={atCap}>+ 300 min · $10</button>
                <button className="btn btn-outline btn-sm" onClick={onBuyPro}>Go Pro · $19/mo</button>
                <button className="btn btn-ghost btn-sm" onClick={onBuySingle} disabled={atCap}>+ 60 min · $3</button>
              </div>
            </div>
            <p className="cap-note">Хвилини не згорають — використовуй коли зручно.</p>
          </section>

          <section className="wallet-card history-card">
            <h3>Остання активність</h3>
            {a.history.length === 0 && <p className="muted">Ще нічого немає.</p>}
            <ul className="history-list">
              {[...a.history].reverse().slice(0, 12).map((h, i) => (
                <li key={i}>
                  <span className={"h-type h-" + h.type}>{historyIcon(h.type)}</span>
                  <span className="h-note">{historyLabel(h)}</span>
                  <span className="h-time">{relTime(h.ts)}</span>
                </li>
              ))}
            </ul>
          </section>
        </div>
      </div>
    </div>
  );
}
window.Wallet = Wallet;

function historyIcon(t) {
  return { signin: '↪', 'credit-add': '+', 'credit-spend': '−', session: '▶', plan: '✦', invite: '✉' }[t] || '·';
}
function historyLabel(h) {
  if (h.type === 'signin') return 'Signed in as ' + h.note;
  if (h.type === 'credit-add') return `+${h.amount} хв — ${h.note || 'purchase'}`;
  if (h.type === 'credit-spend') return h.note || 'Session started';
  if (h.type === 'session') return h.note || 'Session started';
  if (h.type === 'plan') return 'Plan: ' + h.note;
  if (h.type === 'invite') return 'Invite applied: ' + h.note;
  return h.note || h.type;
}
function relTime(ts) {
  const s = Math.floor((Date.now() - ts) / 1000);
  if (s < 60) return s + 's ago';
  if (s < 3600) return Math.floor(s / 60) + 'm ago';
  if (s < 86400) return Math.floor(s / 3600) + 'h ago';
  return Math.floor(s / 86400) + 'd ago';
}

// ---- User pill (top bar) ----
function UserPill({ onSignIn, onOpenWallet }) {
  const a = useAuth();
  if (!a.user && !a.invite) {
    return <button className="btn btn-ghost btn-sm" onClick={onSignIn}>Увійти</button>;
  }
  const u = a.user || { email: a.invite };
  const letter = (u.user_metadata?.full_name || u.email || '?')[0].toUpperCase();
  return (
    <button className="user-pill" onClick={onOpenWallet} title="Відкрити гаманець">
      <span className="user-pill-avatar">{letter}</span>
      <span className="user-pill-meta">
        <span className="user-pill-name">{u.user_metadata?.full_name || u.email}</span>
        <span className="user-pill-credits">{a.invite || a.plan === 'pro' ? '∞ хв' : a.credits + ' хв'}</span>
      </span>
    </button>
  );
}
window.UserPill = UserPill;

// ---- Invited banner ----
function InvitedBanner() {
  const a = useAuth();
  if (!a.invite) return null;
  return (
    <div className="invited-banner">
      <span>✦ Invite <b>{a.invite}</b> — необмежений доступ.</span>
      <button onClick={() => { AuthStore.invite = ''; window.dispatchEvent(new Event('mh-auth-change')); }}>Видалити</button>
    </div>
  );
}
window.InvitedBanner = InvitedBanner;
