// AKC Course Booking — App shell + Tweaks panel wiring
// Composes Browse → Register → Confirm. Manages global state + tweaks.

const { useState: useStateA, useEffect: useEffectA, useRef: useRefA } = React;

// ───────────────────────────────────────────────────────────────────────────
// Splash screen — percentage counter + progress bar, logo flies to nav at 100%
// ───────────────────────────────────────────────────────────────────────────

function SplashScreen({ onDone, waitFor }) {
  const overlayRef  = useRefA(null);
  const wrapRef     = useRefA(null); // outer div — used for FLIP fly transform
  const imgRef      = useRefA(null); // inner img — carries float+glow animations
  const [pct, setPct]       = useStateA(0);
  const [flying, setFlying] = useStateA(false);

  useEffectA(() => {
    const DURATION = 3000;
    const start    = performance.now();
    let raf;

    function tick(now) {
      const progress = Math.min((now - start) / DURATION, 1);
      setPct(Math.floor(progress * 100));
      if (progress < 1) {
        raf = requestAnimationFrame(tick);
      } else {
        setPct(100);
        // Wait for prefetch data before flying so the browse screen
        // is never empty after the splash ends.
        Promise.resolve(waitFor).then(() => flyLogoToNav());
      }
    }

    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);

  function flyLogoToNav() {
    // 1. Freeze the img animation so it snaps to centre (1 frame, imperceptible)
    if (imgRef.current) imgRef.current.style.animation = 'none';
    setFlying(true); // fades counter out

    if (!wrapRef.current || !overlayRef.current) { onDone(); return; }

    // 2. Read wrapper position after the snap (clean translateY=0 baseline)
    requestAnimationFrame(() => {
      const rect   = wrapRef.current.getBoundingClientRect();
      const fromCX = rect.left + rect.width  / 2;
      const fromCY = rect.top  + rect.height / 2;

      // Nav logo: padding-left=24, padding-top=14, height=38
      const NAV_LOGO_H = 38;
      const scale      = NAV_LOGO_H / rect.height;
      const toCX       = 24 + (rect.width * scale) / 2;
      const toCY       = 14 + NAV_LOGO_H / 2;

      wrapRef.current.style.transition = 'transform 0.65s cubic-bezier(0.4,0,0.2,1)';
      wrapRef.current.style.transform  = `translate(${toCX - fromCX}px, ${toCY - fromCY}px) scale(${scale})`;

      setTimeout(() => {
        if (!overlayRef.current) return;
        overlayRef.current.style.transition = 'opacity 0.35s ease';
        overlayRef.current.style.opacity    = '0';
        setTimeout(onDone, 370);
      }, 670);
    });
  }

  return (
    <div
      ref={overlayRef}
      style={{
        position: 'fixed', inset: 0, zIndex: 10000,
        background: '#fff',
        display: 'flex', flexDirection: 'column',
        alignItems: 'center', justifyContent: 'center',
        gap: 52,
        pointerEvents: 'none',
      }}
    >
      {/* Wrapper — only the fly transform is applied here */}
      <div ref={wrapRef} style={{ display: 'inline-block' }}>
        {/* Glow ring behind logo */}
        <div style={{
          position: 'absolute', inset: '-24px',
          borderRadius: '50%',
          background: 'radial-gradient(circle, rgba(26,92,191,0.12) 0%, transparent 70%)',
          animation: flying ? 'none' : 'akc-splash-glow 2.5s ease-in-out infinite',
          pointerEvents: 'none',
        }} />
        {/* The actual logo — reveals, floats, glows */}
        <img
          ref={imgRef}
          src="akc-logo.png"
          alt="AKC"
          style={{
            height: 160,
            width: 'auto',
            display: 'block',
            position: 'relative',
            animation: flying
              ? 'none'
              : [
                  'akc-splash-reveal 0.85s cubic-bezier(0.4,0,0.2,1) both',
                  'akc-splash-float 3s ease-in-out 1s infinite',
                  'akc-splash-shine 3.5s ease-in-out 1.2s infinite',
                ].join(', '),
          }}
        />
      </div>

      {/* Counter + progress bar */}
      <div style={{
        display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14,
        opacity: flying ? 0 : 1,
        transition: 'opacity 0.2s ease',
        animation: flying ? 'none' : 'akc-fadein 0.5s ease 0.3s both',
      }}>
        <span style={{
          fontFamily: "'General Sans','Inter',sans-serif",
          fontSize: 28,
          fontWeight: 700,
          color: 'var(--ink)',
          letterSpacing: '-0.03em',
          fontVariantNumeric: 'tabular-nums',
          minWidth: 80,
          textAlign: 'center',
          lineHeight: 1,
        }}>
          {String(pct).padStart(2, '0')} %
        </span>
        <div style={{
          width: 220,
          height: 2,
          background: 'var(--line)',
          borderRadius: 99,
          overflow: 'hidden',
        }}>
          <div style={{
            height: '100%',
            width: pct + '%',
            background: 'linear-gradient(90deg, var(--primary-300, #93b4f5), var(--primary))',
            borderRadius: 99,
            transition: 'width 30ms linear',
          }} />
        </div>
      </div>
    </div>
  );
}

// ───────────────────────────────────────────────────────────────────────────
// Nav bars
// ───────────────────────────────────────────────────────────────────────────

function TopNav({ step, onHome, logoVisible }) {
  return (
    <div className="akc-topnav" data-screen-label="Top nav">
      <button onClick={onHome} style={{ appearance: 'none', border: 0, background: 'transparent', cursor: 'pointer', padding: 0 }}>
        <img
          src="akc-logo.png"
          alt="AKC"
          style={{
            height: 38, width: 'auto', display: 'block',
            opacity: logoVisible ? 1 : 0,
            transition: 'opacity 0.3s ease 0.05s',
          }}
        />
      </button>
      <window.Stepper step={step} />
      <a href="tel:+6566905555" style={{ fontSize: 12, color: 'var(--muted)', fontWeight: 600, textDecoration: 'none', whiteSpace: 'nowrap' }}>
        📞 6690 5555
      </a>
    </div>
  );
}

function TopNavMobile({ step, onHome, logoVisible }) {
  return (
    <div className="akc-topnav" style={{ padding: '12px 16px', flexWrap: 'wrap', gap: 10 }}>
      <button onClick={onHome} style={{ appearance: 'none', border: 0, background: 'transparent', cursor: 'pointer', padding: 0 }}>
        <img
          src="akc-logo.png"
          alt="AKC"
          style={{
            height: 30, width: 'auto', display: 'block',
            opacity: logoVisible ? 1 : 0,
            transition: 'opacity 0.3s ease 0.05s',
          }}
        />
      </button>
      <window.Stepper step={step} />
    </div>
  );
}

// ───────────────────────────────────────────────────────────────────────────
// AKCBookingApp — root for one device
// ───────────────────────────────────────────────────────────────────────────

function AKCBookingApp({ device, tweaks }) {
  // When the app is embedded inside an iframe (e.g. inside a WordPress page),
  // the parent already provides a header / navigation — skip our own nav and
  // splash so the embedded view goes straight to the content.
  const isEmbedded = window.parent !== window;

  // Show splash on every app load/reload.
  const [splashDone, setSplashDone] = useStateA(false);

  function handleSplashDone() {
    setSplashDone(true);
  }

  // Fire browse fetch synchronously (lazy-init) so the Promise is available
  // for SplashScreen on the very first render — SplashScreen will hold at
  // 100% until this resolves, guaranteeing no loading state after the splash.
  const [fetchPromise] = useStateA(() => {
    if (!window.fetchBrowseData) return Promise.resolve();
    const p = new URLSearchParams(window.location.search);
    const filters = {};
    if (p.get('course'))   filters.course_query = p.get('course');
    else if (p.get('q'))   filters.course_query = p.get('q');
    if (p.get('language')) filters.language     = p.get('language');
    if (p.get('location')) filters.location     = p.get('location');
    if (p.get('from'))     filters.date_from    = p.get('from');
    if (p.get('to'))       filters.date_to      = p.get('to');
    return window.fetchBrowseData(filters)
      .then(data => { window.AKC_PREFETCH = data; })
      .catch(() => {}); // fail gracefully — BrowseScreen will load on its own
  });

  // Individual-only form — company users are routed to the old form before reaching this app
  const [step, setStep] = useStateA('browse');     // browse | register | done
  const [course, setCourse] = useStateA(null);
  const [intake, setIntake] = useStateA(null);
  const [result, setResult] = useStateA(null);

  const handleSelectIntake = (c, i) => {
    setCourse(c); setIntake(i); setStep('register');
  };
  const handleSubmit = (payload) => {
    setResult(payload); setStep('done');
  };
  const handleReset = () => {
    setStep('browse'); setCourse(null); setIntake(null); setResult(null);
  };
  const handleBack = () => setStep('browse');

  const isMobile = device === 'mobile';
  const Nav = isMobile ? TopNavMobile : TopNav;

  return (
    <div
      className="akc-app"
      data-palette={tweaks.palette || 'indigo'}
      data-density={tweaks.density || 'cozy'}
      data-device={device}
      style={{ minHeight: '100%', display: 'flex', flexDirection: 'column' }}
    >
      {!splashDone && <SplashScreen onDone={handleSplashDone} waitFor={fetchPromise} />}

      {!isEmbedded && <Nav step={step} onHome={handleReset} logoVisible={splashDone} />}

      <div style={{ flex: 1, overflow: 'auto', background: 'var(--bg)' }}>
        {step === 'browse' && (
          <div data-screen-label="01 Browse intakes">
            <window.BrowseScreen device={device} onSelectIntake={handleSelectIntake} />
          </div>
        )}
        {step === 'register' && course && intake && (
          <div data-screen-label="02 Registration">
            <window.RegistrationScreen
              device={device}
              course={course}
              intake={intake}
              showGrant={tweaks.showGrant !== false}
              onBack={handleBack}
              onSubmit={handleSubmit}
            />
          </div>
        )}
        {step === 'done' && result && (
          <div data-screen-label="03 Confirmation">
            <window.ConfirmationScreen
              device={device}
              course={result.course}
              intake={result.intake}
              fees={result.fees}
              learnerCount={result.learners.length}
              registrationId={result.backendRegistration?.registration_id}
              status={result.backendRegistration?.status}
              onReset={handleReset}
            />
          </div>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { AKCBookingApp });

// ─────────────────────────────────────────────────────────────────────────────
// Iframe auto-resize shim — posts the page height to the parent window so
// the embedding Elementor page (or any iframe host) can grow the iframe to
// match content. Safe no-op when not iframed.
// ─────────────────────────────────────────────────────────────────────────────
(function () {
  if (window.parent === window) return; // not iframed
  let lastH = 0;
  function ping() {
    const h = Math.max(
      document.documentElement.scrollHeight,
      document.body ? document.body.scrollHeight : 0
    );
    if (h && Math.abs(h - lastH) > 4) {
      lastH = h;
      try { window.parent.postMessage({ akc: 'resize', h }, '*'); } catch (_) {}
    }
  }
  setInterval(ping, 350);
  window.addEventListener('load', ping);
  window.addEventListener('resize', ping);
})();
