// Apple Bank × Liquid Data — Consumer journey host
// Mobile-first. On desktop, the same mobile app is centered inside a phone frame
// against a navy editorial backdrop (chase.liquiddata.com style).

const { useState: _juseState, useEffect: _juseEffect } = React;

// ───── Supabase config (anon publishable key, RLS INSERT-only) ─────
const SUPABASE_URL = 'https://ywyjahvvoqkgrdceayuf.supabase.co';
const SUPABASE_KEY = 'sb_publishable_OHNLGFSV0Vs4Gata4TQTog_XYrrbdwJ';
const SUPABASE_TABLE = 'apple_bank_responses';

// ───── Capture context — fires once on first load ─────
const CAPTURE_CTX = (() => {
  if (typeof window === 'undefined') return {};
  const p = new URLSearchParams(window.location.search);
  return {
    user_agent: navigator.userAgent,
    device_type: /Mobi|Android/i.test(navigator.userAgent) ? 'mobile' : 'desktop',
    referrer: document.referrer || null,
    utm_source: p.get('utm_source') || p.get('src'),
    utm_medium: p.get('utm_medium'),
    utm_campaign: p.get('utm_campaign'),
    can_id: p.get('can') || p.get('c'),
    scan_timestamp: new Date().toISOString(),
  };
})();

// Geo — fires on first user interaction (S1 "Let's go"), persisted to module scope
let GEO_CACHE = { geo_lat: null, geo_lng: null, geo_borough: null };
function captureGeo() {
  if (typeof navigator === 'undefined' || !navigator.geolocation) return;
  if (GEO_CACHE.geo_lat != null) return; // already captured
  navigator.geolocation.getCurrentPosition(
    (pos) => {
      GEO_CACHE.geo_lat = pos.coords.latitude;
      GEO_CACHE.geo_lng = pos.coords.longitude;
      GEO_CACHE.geo_borough = inferBorough(pos.coords.latitude, pos.coords.longitude);
    },
    () => {},
    { timeout: 8000, maximumAge: 60000 }
  );
}
function inferBorough(lat, lon) {
  if (lat == null) return null;
  if (lat > 40.78 && lat < 40.88 && lon > -74.02 && lon < -73.91) return 'Manhattan (uptown)';
  if (lat > 40.70 && lat < 40.78 && lon > -74.02 && lon < -73.93) return 'Manhattan';
  if (lat > 40.57 && lat < 40.74 && lon > -74.04 && lon < -73.83) return 'Brooklyn';
  if (lat > 40.54 && lat < 40.80 && lon > -73.96 && lon < -73.70) return 'Queens';
  if (lat > 40.79 && lat < 40.92 && lon > -73.93 && lon < -73.75) return 'Bronx';
  if (lat > 40.50 && lat < 40.65 && lon > -74.26 && lon < -74.05) return 'Staten Island';
  if (lat > 40.55 && lat < 41.20 && lon > -73.70 && lon < -71.85) return 'Long Island';
  if (lat > 40.90 && lat < 41.40 && lon > -74.10 && lon < -73.45) return 'Westchester';
  if (lat > 40.50 && lat < 41.30 && lon > -75.00 && lon < -73.90) return 'NJ commute';
  return 'Outside NYC area';
}

// POST to Supabase. Anon key is safe to expose — RLS allows INSERT only.
function submitToSupabase(state, opts = {}) {
  const path = state.path === 'parent' ? 'parent' : 'student';
  const body = {
    path,
    first_name: state.firstName || null,
    last_name: state.lastName || null,
    kid_first_name: state.kidFirstName || null,
    phone: state.phone || null,
    email: state.email || null,
    school: state.school || null,
    year: state.year || null,
    major: state.major || null,
    grade: state.grade || null,
    age_band: state.ageBand || null,
    family_count: state.familyCount || null,
    has_529: state.has529 || null,
    timing: state.timing || null,
    banks: state.banks && state.banks.length ? state.banks : null,
    usage: state.usage || null,
    deposit: state.deposit || null,
    geo_lat: GEO_CACHE.geo_lat,
    geo_lng: GEO_CACHE.geo_lng,
    geo_borough: GEO_CACHE.geo_borough,
    completed: !!opts.completed,
    screens_completed: opts.screens_completed || 0,
    ...CAPTURE_CTX,
  };
  return fetch(`${SUPABASE_URL}/rest/v1/${SUPABASE_TABLE}`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      apikey: SUPABASE_KEY,
      Authorization: `Bearer ${SUPABASE_KEY}`,
      Prefer: 'return=minimal',
    },
    body: JSON.stringify(body),
  }).catch((e) => {
    if (typeof console !== 'undefined') console.warn('[apple-bank] submit failed', e);
  });
}

const INITIAL_STATE = {
  path: null,
  firstName: '', lastName: '', kidFirstName: '',
  school: null, year: null, major: '',
  banks: [], usage: null,
  grade: null, ageBand: null, familyCount: null, has529: null,
  phone: '', email: '', deposit: null, timing: null,
};

const PHONE_W = 390;
const PHONE_H = 844;
const DESKTOP_BP = 900; // ≥ this → show phone-frame against backdrop

function useBreakpoint() {
  const [bp, setBp] = _juseState(() => {
    if (typeof window === 'undefined') return 'mobile';
    return window.innerWidth >= DESKTOP_BP ? 'desktop' : 'mobile';
  });
  _juseEffect(() => {
    const onResize = () => setBp(window.innerWidth >= DESKTOP_BP ? 'desktop' : 'mobile');
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, []);
  return bp;
}

function JourneyApp() {
  const [screen, setScreen] = _juseState('S1');
  const [history, setHistory] = _juseState(['S1']);
  const [state, setState] = _juseState(INITIAL_STATE);
  const bp = useBreakpoint();

  function set(k, v) { setState(s => ({ ...s, [k]: v })); }
  function next(t) {
    // Capture geo on first forward move from S1
    if (screen === 'S1' && t !== 'S1') captureGeo();
    // Submit on entering a confirmation screen (S8 student, P8 parent)
    if (t === 'S8' || t === 'P8') {
      submitToSupabase(state, { completed: true, screens_completed: history.length + 1 });
    }
    setScreen(t);
    setHistory(h => [...h, t]);
  }
  function back() {
    setHistory(h => {
      if (h.length <= 1) return h;
      const nh = h.slice(0, -1);
      setScreen(nh[nh.length - 1]);
      return nh;
    });
  }
  function jump(t) {
    setScreen(t);
    setHistory([t]);
    if (t === 'S1') setState(INITIAL_STATE);
  }

  const ScreenComp = AB_SCREENS[screen];
  const showBack = screen !== 'S1' && screen !== 'S8' && screen !== 'P8';

  const mobileApp = (
    <MobileApp
      screen={screen} state={state} set={set} next={next} back={back} jump={jump}
      ScreenComp={ScreenComp} showBack={showBack}
    />
  );

  if (bp === 'desktop') {
    return <DesktopFrame screen={screen}>{mobileApp}</DesktopFrame>;
  }
  return mobileApp;
}

/* ─────────── MOBILE APP ───────────
   The actual journey. Looks/feels like a native mobile app — no phone bezel,
   no status bar mock. On mobile: fills viewport. On desktop: sized 390×844
   inside the DesktopFrame (which sets the container size). */

function MobileApp({ screen, state, set, next, back, jump, ScreenComp, showBack }) {
  return (
    <div className="ab aj-app" style={{
      position: 'relative',
      width: '100%', height: '100%',
      background: 'var(--ab-cream)',
      display: 'flex', flexDirection: 'column',
      overflow: 'hidden',
      paddingTop: 'env(safe-area-inset-top, 0)',
    }}>
      {/* Status bar — real on iOS via safe-area, mock on desktop phone frame */}
      <PhoneStatusBar />

      {/* Brand bar */}
      <header style={{
        flexShrink: 0,
        padding: '10px 20px 10px',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        background: 'var(--ab-cream)',
        zIndex: 40, gap: 12,
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>
          {showBack ? (
            <button onClick={back} aria-label="back" style={{
              width: 32, height: 32, marginLeft: -8, borderRadius: 999,
              background: 'transparent', border: 'none', cursor: 'pointer',
              color: 'var(--ab-ink)', display: 'flex', alignItems: 'center', justifyContent: 'center',
              flexShrink: 0,
            }}>
              <IconChevron dir="left" size={18} />
            </button>
          ) : (
            <AppleIcon size={22} />
          )}
          <div style={{
            fontFamily: 'var(--ab-serif)', fontWeight: 700, fontSize: 16,
            color: 'var(--ab-ink)', letterSpacing: '-0.005em',
            whiteSpace: 'nowrap',
          }}>Apple Bank</div>
        </div>
        <div style={{
          fontFamily: 'var(--ab-sans)', fontWeight: 600, fontSize: 10,
          color: 'var(--ab-ink-mute)', letterSpacing: '0.14em', textTransform: 'uppercase',
          whiteSpace: 'nowrap',
        }}>× Liquid Data</div>
      </header>

      {/* Screen surface */}
      <main key={screen} style={{
        flex: 1, position: 'relative', overflow: 'auto',
        WebkitOverflowScrolling: 'touch',
      }}>
        <div style={{ minHeight: '100%', display: 'flex', flexDirection: 'column' }}>
          <ScreenComp state={state} set={set} next={next} back={back} jump={jump} />
        </div>
      </main>
    </div>
  );
}

/* ─────────── DESKTOP FRAME ───────────
   On wide screens we wrap the mobile app in a phone bezel against a
   navy editorial backdrop. Same approach as chase.liquiddata.com. */

function DesktopFrame({ screen, children }) {
  return (
    <div className="aj-desktop-frame" style={{
      position: 'fixed', inset: 0, overflow: 'hidden',
      background: 'linear-gradient(160deg, #0F2659 0%, #081A40 70%, #050F2A 100%)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
    }}>
      {/* ambient backdrop */}
      <BackdropArt />

      {/* layout: left editorial, right phone */}
      <div style={{
        position: 'relative', zIndex: 2,
        width: '100%', maxWidth: 1280,
        padding: '40px 56px',
        display: 'grid', gridTemplateColumns: '1fr auto',
        alignItems: 'center', gap: 64,
      }}>
        {/* Editorial column */}
        <DesktopEditorial />

        {/* Phone frame */}
        <div style={{
          width: PHONE_W + 16, height: PHONE_H + 16,
          background: '#0A0A0B', padding: 8,
          borderRadius: 54,
          boxShadow: '0 60px 120px -30px rgba(0,0,0,0.6), 0 30px 60px -20px rgba(0,0,0,0.4), inset 0 1px 0 rgba(255,255,255,0.06), inset 0 -1px 0 rgba(255,255,255,0.04)',
          position: 'relative',
        }}>
          {/* speaker notch */}
          <div style={{
            position: 'absolute', top: 18, left: '50%', transform: 'translateX(-50%)',
            width: 110, height: 32, background: '#0A0A0B', borderRadius: 999, zIndex: 60,
          }} />
          <div style={{
            position: 'relative', width: '100%', height: '100%',
            borderRadius: 46, overflow: 'hidden',
          }}>
            {children}
          </div>
        </div>
      </div>

      {/* corner brand */}
      <div style={{
        position: 'absolute', top: 28, left: 36, zIndex: 3,
        display: 'flex', alignItems: 'center', gap: 10,
        fontFamily: 'var(--ab-serif)', fontWeight: 700, fontSize: 18, color: '#fff',
      }}>
        <AppleIcon size={26} />
        <span>Apple Bank</span>
        <span style={{ marginLeft: 8, fontFamily: 'var(--ab-sans)', fontSize: 10, fontWeight: 600, letterSpacing: '0.14em', textTransform: 'uppercase', color: 'rgba(255,255,255,0.55)' }}>× Liquid Data</span>
      </div>

      <div style={{
        position: 'absolute', bottom: 24, left: 36, zIndex: 3,
        fontFamily: 'var(--ab-sans)', fontSize: 11, color: 'rgba(255,255,255,0.4)',
        maxWidth: 480,
      }}>
        Apple Bank for Savings · NMLS #586470 · FDIC insured · Est. 1863, New York
      </div>
    </div>
  );
}

/* ─────────── DESKTOP EDITORIAL ───────────
   Static editorial copy + dancing can to the left of the phone.
   Doesn't change per screen — keeps the desktop feel calm. */

function DesktopEditorial() {
  return (
    <div style={{ color: '#fff', maxWidth: 520, position: 'relative' }}>
      <div style={{
        fontFamily: 'var(--ab-sans)', fontWeight: 600, fontSize: 11, color: 'var(--ab-red)',
        letterSpacing: '0.18em', textTransform: 'uppercase', marginBottom: 20,
      }}>
        Scan the can · 90 second journey
      </div>
      <h1 style={{
        fontFamily: 'var(--ab-serif)', fontWeight: 700, fontSize: 56, lineHeight: 1.02, letterSpacing: '-0.024em',
        margin: 0, color: '#fff', textWrap: 'balance',
      }}>
        Apple Bank has been&nbsp;<em style={{ color: 'var(--ab-red)', fontStyle: 'italic' }}>Good For New York</em>&nbsp;since 1863.
      </h1>
      <p style={{
        marginTop: 22, fontSize: 17, lineHeight: 1.55, color: 'rgba(255,255,255,0.78)',
        textWrap: 'pretty', maxWidth: 460,
      }}>
        162 years. 80 neighborhood branches. Bankers who live in the same area as our branches — your neighbors. Now we’re paying you to come say hi. Try it →
      </p>

      <div style={{
        marginTop: 36, paddingTop: 24,
        borderTop: '1px solid rgba(255,255,255,0.14)',
        display: 'grid', gridTemplateColumns: 'repeat(4, auto)', gap: 28,
      }}>
        <DStat n="$17.5B" l="assets · privately held" />
        <DStat n="80" l="neighborhood branches" />
        <DStat n="5.00%" l="APY on SmartStart" />
        <DStat n="1863" l="founded in NYC" />
      </div>
    </div>
  );
}

function DStat({ n, l }) {
  return (
    <div>
      <div style={{ fontFamily: 'var(--ab-serif)', fontWeight: 700, fontSize: 22, color: '#fff', letterSpacing: '-0.01em', lineHeight: 1 }}>{n}</div>
      <div style={{ fontSize: 11, color: 'rgba(255,255,255,0.55)', marginTop: 4, lineHeight: 1.3, maxWidth: 90 }}>{l}</div>
    </div>
  );
}

/* ─────────── STATUS BAR ───────────
   Mock iOS-style status bar. On real iOS the OS overlays its own; this gives the
   page a clean 48px gutter at the top that works on desktop (under the notch)
   and mobile (under the safe-area inset). */

function PhoneStatusBar() {
  return (
    <div style={{
      position: 'relative', flexShrink: 0,
      height: 44, padding: '14px 28px 0',
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      fontFamily: '-apple-system, BlinkMacSystemFont, system-ui',
      fontSize: 14, fontWeight: 600, color: 'var(--ab-ink)',
      zIndex: 50, pointerEvents: 'none',
      background: 'var(--ab-cream)',
    }}>
      <span>9:41</span>
      <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
        {/* signal */}
        <svg width="17" height="11" viewBox="0 0 17 11"><g fill="currentColor"><rect x="0" y="7" width="3" height="4" rx="0.5"/><rect x="4.5" y="5" width="3" height="6" rx="0.5"/><rect x="9" y="3" width="3" height="8" rx="0.5"/><rect x="13.5" y="0" width="3" height="11" rx="0.5"/></g></svg>
        {/* wifi */}
        <svg width="15" height="11" viewBox="0 0 15 11" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"><path d="M1 4 C 4 1, 11 1, 14 4" /><path d="M3 6.5 C 5 4.8, 10 4.8, 12 6.5" /><circle cx="7.5" cy="9" r="0.8" fill="currentColor" /></svg>
        {/* battery */}
        <svg width="24" height="11" viewBox="0 0 24 11"><rect x="0.5" y="0.5" width="20" height="10" rx="2" fill="none" stroke="currentColor"/><rect x="21" y="3.5" width="2" height="4" rx="0.5" fill="currentColor"/><rect x="2" y="2" width="17" height="7" rx="1" fill="currentColor"/></svg>
      </span>
    </div>
  );
}

/* ─────────── BACKDROP ART ───────────
   Subtle decorative apple icon + sparkles behind the phone. */

function BackdropArt() {
  return (
    <>
      {/* big faint apple silhouette */}
      <div style={{
        position: 'absolute', right: -120, bottom: -180, opacity: 0.07, transform: 'rotate(-12deg)',
        pointerEvents: 'none',
      }}>
        <AppleIcon size={680} />
      </div>
      {/* tiny stars / dots */}
      {[
        [12, 18], [88, 8], [22, 78], [78, 88], [50, 6], [6, 50], [94, 50], [40, 92],
        [62, 14], [16, 32], [82, 30], [30, 60],
      ].map(([x, y], i) => (
        <div key={i} style={{
          position: 'absolute', left: `${x}%`, top: `${y}%`,
          width: 3, height: 3, borderRadius: 999, background: 'rgba(255,255,255,0.5)',
          opacity: 0.4 + (i % 4) * 0.15,
          boxShadow: i % 3 === 0 ? '0 0 8px rgba(255,255,255,0.4)' : 'none',
        }} />
      ))}
    </>
  );
}

Object.assign(window, { JourneyApp });