// ===========================================================================
//  AuthGate — wraps the app. In DEMO mode it renders <App/> immediately.
//  In LIVE mode (Supabase keys present) it requires real sign-in, loads the
//  signed-in user's org, and offers a one-time "load sample data" step.
// ===========================================================================
const { useState: useGateState, useEffect: useGateEffect } = React;

function AuthGate() {
  const live = window.STAGEVO_BACKEND === 'live' && window.StagevoAuth;
  const [demoBypass, setDemoBypass] = useGateState(false);
  const [phase, setPhase] = useGateState(live ? 'loading' : 'ready'); // loading | auth | mfa | seed | ready
  const [seeding, setSeeding] = useGateState('');

  useGateEffect(() => {
    if (!live) return;
    let unsub = null;
    const recovery = /type=recovery/.test(location.hash) || /type=recovery/.test(location.search);
    (async () => {
      const res = window.sb.auth.onAuthStateChange((event, session) => {
        if (event === 'PASSWORD_RECOVERY') { setPhase('recover'); return; }
        if (event === 'SIGNED_OUT' || !session) {
          sessionStorage.removeItem('stagevo_org_slug');
          window.STAGEVO_ORG_SLUG = null;
          setPhase('auth');
        }
      });
      unsub = res && res.data && res.data.subscription;
      if (recovery) { setPhase('recover'); return; }
      const { data } = await window.StagevoAuth.session();
      if (data && data.session) await bootstrap(data.session);
      else setPhase('auth');
    })();
    return () => { try { unsub && unsub.unsubscribe(); } catch (e) {} };
  }, []);

  const enterDemo = () => {
    try { window.anonymizeDemoData && window.anonymizeDemoData(); } catch (e) {}
    // Clear any cached real data so the app re-initialises from the anonymised set.
    try {
      ['kub_deals_v1', 'kub_contacts_v1', 'kub_users_v1', 'kub_showrooms_v1',
       'kub_reps_v1', 'kub_targets_v1', 'kub_tasks_v1', 'kub_sitevisits_v1']
        .forEach((k) => localStorage.removeItem(k));
    } catch (e) {}
    setDemoBypass(true);
  };

  async function bootstrap(session) {
    setPhase('loading');
    try {
      window.STAGEVO_AUTHED = true;
      // Preserve the bundled demo data so the seeder can still reach it.
      if (!window.SALES_DATA_DEMO) window.SALES_DATA_DEMO = window.SALES_DATA;
      const liveData = await window.StagevoData.loadWorkspace();

      // Fresh org per sign-in identity → clear any demo working copy once.
      const orgId = liveData.org && liveData.org.id;
      if (orgId && localStorage.getItem('stagevo_live_org') !== orgId) {
        ['kub_deals_v1', 'kub_contacts_v1', 'kub_users_v1', 'kub_showrooms_v1',
         'kub_targets_v1', 'kub_reps_v1', 'kub_tasks_v1', 'kub_sitevisits_v1']
          .forEach((k) => localStorage.removeItem(k));
        localStorage.setItem('stagevo_live_org', orgId);
      }

      // If Supabase returned no profiles (RLS bootstrap issue), inject a
      // minimal current-user record so the app never crashes on load.
      let users = liveData.USERS || [];
      const hasMe = users.some((u) => u.id === session.user.id);
      if (!hasMe) {
        const fallback = {
          id: session.user.id,
          name: session.user.user_metadata?.full_name || session.user.email?.split('@')[0] || 'Admin',
          email: session.user.email || '',
          title: 'Admin',
          role: 'admin',
          status: 'active',
          superAdmin: true,
          home: null, manages: [], works: [],
          repId: session.user.id, quota: 0,
        };
        users = [fallback, ...users];
        liveData.USERS = users;
        // Also ensure REPS and SHOWROOMS are never undefined
        liveData.REPS = liveData.REPS || [];
        liveData.SHOWROOMS = liveData.SHOWROOMS && liveData.SHOWROOMS.length > 0
          ? liveData.SHOWROOMS
          : [{ id: 'default', name: 'Main Showroom', state: '', target: 0, color: 'var(--accent)' }];
      }

      window.SALES_DATA = { ...window.SALES_DATA, ...liveData };
      window.STAGEVO_CURRENT_USER_ID = session.user.id;

      // ── Org-scoped URL (like Xero's go.xero.com/app/!psHM5/) ──────────────
      // Generate a stable short token from the org_id so every company gets
      // a unique URL. Anyone who visits a URL with a DIFFERENT org token is
      // signed out immediately — prevents session confusion across orgs.
      const wsOrgId = (liveData.org && liveData.org.id) || session.user.id;
      const orgSlug = btoa(wsOrgId).replace(/[+/=]/g,'').slice(0,10).toUpperCase();

      // If there's already a hash with a DIFFERENT org, sign out for safety.
      const existingHash = window.location.hash;
      const hashMatch = existingHash.match(/#\/ws\/([A-Z0-9]+)/);
      if (hashMatch && hashMatch[1] !== orgSlug) {
        await window.sb.auth.signOut();
        window.location.hash = '';
        setPhase('auth');
        return;
      }

      // Set the org-scoped URL hash (replaces state so Back button works cleanly)
      if (!hashMatch || hashMatch[1] !== orgSlug) {
        window.history.replaceState(null, '', window.location.pathname + '#/ws/' + orgSlug);
      }

      // Store org slug in sessionStorage so sign-out can verify it
      sessionStorage.setItem('stagevo_org_slug', orgSlug);
      window.STAGEVO_ORG_SLUG = orgSlug;
      // ── end org-scoped URL ────────────────────────────────────────────────

      const me = users.find((u) => u.id === session.user.id);
      const isAdmin = me && (me.role === 'admin' || me.superAdmin);
      if ((liveData.DEALS || []).length === 0 && isAdmin) setPhase('seed');
      else setPhase('ready');
    } catch (e) {
      console.error('[Stagevo] live bootstrap failed:', e);
      alert('Could not load your workspace: ' + (e.message || e) + '\nFalling back to demo.');
      setDemoBypass(true);
    }
  }

  async function runSeed(withData) {
    if (!withData) { setPhase('ready'); return; }
    try {
      setSeeding('Starting…');
      await window.StagevoData.seedDemoData((m) => setSeeding(m));
      const { data } = await window.StagevoAuth.session();
      await bootstrap(data.session);
    } catch (e) { alert('Seeding failed: ' + (e.message || e)); setPhase('ready'); }
  }

  if (!live || demoBypass) return React.createElement(App);
  if (phase === 'ready') return React.createElement(App);
  if (phase === 'loading') return <GateSplash label="Loading your workspace…"/>;
  if (phase === 'recover') return <UpdatePassword onDone={(s) => (s ? bootstrap(s) : setPhase('auth'))}/>;
  if (phase === 'seed') return <SeedStep seeding={seeding} onChoose={runSeed}/>;
  return <AuthScreen onAuthed={(s) => bootstrap(s)} onDemo={enterDemo}/>;
}

function GateSplash({ label }) {
  return (
    <div className="auth-wrap">
      <div className="auth-card" style={{ textAlign: 'center' }}>
        <div className="auth-spinner" style={{ margin: '8px auto 14px' }}></div>
        <div style={{ color: 'var(--ink-3)', fontSize: 13 }}>{label}</div>
      </div>
    </div>
  );
}

function SeedStep({ seeding, onChoose }) {
  return (
    <div className="auth-wrap">
      <div className="auth-card">
        <BrandLockup/>
        <h1 className="auth-title">Welcome to your workspace</h1>
        <p className="auth-sub">Your company workspace is ready. Load a realistic sample pipeline to explore with, or start from a clean slate.</p>
        {seeding ? (
          <div style={{ marginTop: 18 }}>
            <div className="auth-spinner" style={{ margin: '4px auto 12px' }}></div>
            <div style={{ textAlign: 'center', color: 'var(--ink-3)', fontSize: 12.5, fontVariantNumeric: 'tabular-nums' }}>{seeding}</div>
          </div>
        ) : (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginTop: 20 }}>
            <button className="btn primary" style={{ height: 42, justifyContent: 'center' }} onClick={() => onChoose(true)}>
              <Icon name="download" size={14}/> Load sample data (showrooms, deals & contacts)
            </button>
            <button className="btn" style={{ height: 42, justifyContent: 'center' }} onClick={() => onChoose(false)}>
              Start with an empty workspace
            </button>
          </div>
        )}
      </div>
    </div>
  );
}

function AuthScreen({ onAuthed, onDemo }) {
  const [mode, setMode] = useGateState('signin'); // signin | signup
  const [email, setEmail] = useGateState('');
  const [password, setPassword] = useGateState('');
  const [fullName, setFullName] = useGateState('');
  const [orgName, setOrgName] = useGateState('');
  const [busy, setBusy] = useGateState(false);
  const [msg, setMsg] = useGateState(null);     // { type:'err'|'ok', text }
  const [mfa, setMfa] = useGateState(null);      // { factorId }
  const [code, setCode] = useGateState('');
  const [view, setView] = useGateState('form');  // form | forgot | request
  const [req, setReq] = useGateState({ name: '', email: '', company: '', employees: '', current: '', message: '' });

  const A = window.StagevoAuth;
  const err = (e) => setMsg({ type: 'err', text: (e && (e.message || e)) || 'Something went wrong' });

  async function afterPassword() {
    // If the account has TOTP enrolled, step up to AAL2.
    try {
      const { data } = await window.sb.auth.mfa.getAuthenticatorAssuranceLevel();
      if (data && data.nextLevel === 'aal2' && data.currentLevel !== 'aal2') {
        const f = await A.listFactors();
        const totp = f.data && f.data.totp && f.data.totp[0];
        if (totp) { setMfa({ factorId: totp.id }); return false; }
      }
    } catch (e) {}
    return true;
  }

  async function submit(e) {
    e.preventDefault(); setBusy(true); setMsg(null);
    try {
      if (mode === 'signup') {
        const { data, error } = await A.signUp(email, password, { fullName, orgName });
        if (error) throw error;
        if (!data.session) { setMsg({ type: 'ok', text: 'Check your email to confirm your address, then sign in.' }); setMode('signin'); }
        else onAuthed(data.session);
      } else {
        const { data, error } = await A.signIn(email, password);
        if (error) throw error;
        if (await afterPassword()) onAuthed(data.session);
      }
    } catch (e2) { err(e2); } finally { setBusy(false); }
  }

  async function verifyMfa() {
    setBusy(true); setMsg(null);
    try {
      await A.verifyTotp(mfa.factorId, code);
      const { data } = await A.session();
      onAuthed(data.session);
    } catch (e) { err(e); } finally { setBusy(false); }
  }

  async function magic() {
    if (!email) return err('Enter your email first');
    setBusy(true); setMsg(null);
    try { const { error } = await A.magicLink(email); if (error) throw error; setMsg({ type: 'ok', text: 'Magic link sent — check your inbox.' }); }
    catch (e) { err(e); } finally { setBusy(false); }
  }

  async function google() { setMsg(null); try { const { error } = await A.google(); if (error) throw error; } catch (e) { err(e); } }

  async function sendReset() {
    if (!email) return err('Enter your account email first');
    setBusy(true); setMsg(null);
    try {
      const { error } = await window.sb.auth.resetPasswordForEmail(email, { redirectTo: location.origin });
      if (error) throw error;
      setMsg({ type: 'ok', text: 'Password reset link sent — check your inbox.' });
    } catch (e) { err(e); } finally { setBusy(false); }
  }

  async function submitRequest(e) {
    e.preventDefault(); setBusy(true); setMsg(null);
    try {
      if (window.sb) {
        const { error } = await window.sb.from('demo_requests').insert({
          name: req.name, email: req.email, company: req.company,
          employees: req.employees, current_system: req.current, message: req.message,
        });
        if (error && !/does not exist|schema cache/i.test(error.message || '')) throw error;
      }
      onDemo(); // grant the anonymised sample workspace
    } catch (e2) { err(e2); setBusy(false); }
  }

  if (view === 'forgot') {
    return (
      <div className="auth-wrap"><div className="auth-card">
        <BrandLockup/>
        <h1 className="auth-title">Reset your password</h1>
        <p className="auth-sub">Enter your account email and we’ll send you a secure reset link.</p>
        <input className="auth-input" type="email" placeholder="Work email" value={email} onChange={(e) => setEmail(e.target.value)} autoFocus/>
        {msg && <div className={`auth-msg ${msg.type}`} style={{ marginTop: 10 }}>{msg.text}</div>}
        <button className="btn primary" style={{ width: '100%', height: 42, justifyContent: 'center', marginTop: 12 }} disabled={busy} onClick={sendReset}>
          <Icon name="mail" size={14}/> Send reset link
        </button>
        <button className="auth-demo" onClick={() => { setView('form'); setMsg(null); }}>← Back to sign in</button>
      </div></div>
    );
  }

  if (view === 'request') {
    return (
      <div className="auth-wrap"><div className="auth-card" style={{ maxWidth: 440 }}>
        <BrandLockup/>
        <h1 className="auth-title">Request a demo</h1>
        <p className="auth-sub">Tell us about your business and we’ll be in touch — you can explore a sample workspace right away.</p>
        <form onSubmit={submitRequest} style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          <input className="auth-input" placeholder="Your name" value={req.name} onChange={(e) => setReq({ ...req, name: e.target.value })} required/>
          <input className="auth-input" type="email" placeholder="Work email" value={req.email} onChange={(e) => setReq({ ...req, email: e.target.value })} required/>
          <input className="auth-input" placeholder="Company name" value={req.company} onChange={(e) => setReq({ ...req, company: e.target.value })} required/>
          <select className="auth-input" value={req.employees} onChange={(e) => setReq({ ...req, employees: e.target.value })} required style={{ appearance: 'auto' }}>
            <option value="">How many people in the business?</option>
            <option>1–5</option><option>6–20</option><option>21–50</option><option>51–200</option><option>200+</option>
          </select>
          <input className="auth-input" placeholder="Current system (spreadsheets, HubSpot, none…)" value={req.current} onChange={(e) => setReq({ ...req, current: e.target.value })}/>
          <textarea className="auth-input" placeholder="Anything specific you’d like to see? (optional)" value={req.message} onChange={(e) => setReq({ ...req, message: e.target.value })} style={{ height: 72, paddingTop: 10, resize: 'vertical' }}/>
          {msg && <div className={`auth-msg ${msg.type}`}>{msg.text}</div>}
          <button className="btn primary" style={{ height: 42, justifyContent: 'center' }} disabled={busy} type="submit">
            {busy ? 'Please wait…' : 'Submit & explore the demo'}
          </button>
        </form>
        <button className="auth-demo" onClick={() => { setView('form'); setMsg(null); }}>← Back to sign in</button>
      </div></div>
    );
  }

  if (mfa) {
    return (
      <div className="auth-wrap">
        <div className="auth-card">
          <BrandLockup/>
          <h1 className="auth-title">Two-factor authentication</h1>
          <p className="auth-sub">Enter the 6-digit code from your authenticator app.</p>
          <input className="auth-input" inputMode="numeric" maxLength={6} value={code}
            onChange={(e) => setCode(e.target.value.replace(/\D/g, '').slice(0, 6))}
            placeholder="000000" style={{ textAlign: 'center', letterSpacing: '0.4em', fontSize: 20 }} autoFocus/>
          {msg && <div className={`auth-msg ${msg.type}`}>{msg.text}</div>}
          <button className="btn primary" style={{ width: '100%', height: 42, justifyContent: 'center', marginTop: 12 }}
            disabled={busy || code.length !== 6} onClick={verifyMfa}><Icon name="lock" size={14}/> Verify</button>
        </div>
      </div>
    );
  }

  return (
    <div className="auth-wrap">
      <div className="auth-card">
        <BrandLockup/>
        <h1 className="auth-title">{mode === 'signin' ? 'Sign in to Stagevo' : 'Create your workspace'}</h1>
        <p className="auth-sub">{mode === 'signin' ? 'Welcome back. Sign in to your sales workspace.' : 'Start a new company workspace — you’ll be its admin.'}</p>

        <div className="auth-tabs">
          <button className={mode === 'signin' ? 'on' : ''} onClick={() => { setMode('signin'); setMsg(null); }}>Sign in</button>
          <button className={mode === 'signup' ? 'on' : ''} onClick={() => { setMode('signup'); setMsg(null); }}>Create workspace</button>
        </div>

        <form onSubmit={submit} style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          {mode === 'signup' && (
            <React.Fragment>
              <input className="auth-input" placeholder="Your name" value={fullName} onChange={(e) => setFullName(e.target.value)}/>
              <input className="auth-input" placeholder="Company / workspace name" value={orgName} onChange={(e) => setOrgName(e.target.value)} required/>
            </React.Fragment>
          )}
          <input className="auth-input" type="email" placeholder="Work email" value={email} onChange={(e) => setEmail(e.target.value)} required autoComplete="email"/>
          <input className="auth-input" type="password" placeholder="Password" value={password} onChange={(e) => setPassword(e.target.value)} required minLength={6} autoComplete={mode === 'signin' ? 'current-password' : 'new-password'}/>
          {mode === 'signin' && (
            <button type="button" onClick={() => { setView('forgot'); setMsg(null); }}
              style={{ alignSelf: 'flex-end', marginTop: -3, fontSize: 12, color: 'var(--ink-3)', background: 'none', cursor: 'pointer' }}>
              Forgot password?
            </button>
          )}
          {msg && <div className={`auth-msg ${msg.type}`}>{msg.text}</div>}
          <button className="btn primary" style={{ height: 42, justifyContent: 'center', marginTop: 4 }} disabled={busy} type="submit">
            {busy ? 'Please wait…' : (mode === 'signin' ? 'Sign in' : 'Create workspace')}
          </button>
        </form>

        <button className="auth-demo" onClick={() => { setView('request'); setMsg(null); }}>Not a customer yet? Request a demo →</button>
      </div>
    </div>
  );
}

function BrandLockup() {
  return (
    <div className="auth-brand">
      <span className="auth-brand-mark">S</span>
    </div>
  );
}

function UpdatePassword({ onDone }) {
  const [pw, setPw] = useGateState('');
  const [pw2, setPw2] = useGateState('');
  const [busy, setBusy] = useGateState(false);
  const [msg, setMsg] = useGateState(null);
  async function save() {
    if (pw.length < 6) return setMsg({ type: 'err', text: 'Use at least 6 characters.' });
    if (pw !== pw2) return setMsg({ type: 'err', text: 'Passwords don\u2019t match.' });
    setBusy(true); setMsg(null);
    try {
      const { error } = await window.sb.auth.updateUser({ password: pw });
      if (error) throw error;
      const { data } = await window.sb.auth.getSession();
      onDone(data && data.session);
    } catch (e) { setMsg({ type: 'err', text: e.message || String(e) }); setBusy(false); }
  }
  return (
    <div className="auth-wrap"><div className="auth-card">
      <BrandLockup/>
      <h1 className="auth-title">Set a new password</h1>
      <p className="auth-sub">Choose a new password for your account.</p>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        <input className="auth-input" type="password" placeholder="New password" value={pw} onChange={(e) => setPw(e.target.value)} autoFocus/>
        <input className="auth-input" type="password" placeholder="Confirm new password" value={pw2} onChange={(e) => setPw2(e.target.value)}/>
        {msg && <div className={`auth-msg ${msg.type}`}>{msg.text}</div>}
        <button className="btn primary" style={{ height: 42, justifyContent: 'center' }} disabled={busy} onClick={save}>
          <Icon name="lock" size={14}/> Update password
        </button>
      </div>
    </div></div>
  );
}

window.AuthGate = AuthGate;
