// Shell — wraps the prototype with optional dev controls and routes between
// the desktop layout (App) and the mobile layout (MobileApp).
//
// Production behavior: viewport width decides. <768 px → mobile components
// rendered fullscreen; ≥768 px → desktop. The dev Tweaks panel and the
// iPhone-frame preview are hidden so real visitors don't see them.
//
// Dev behavior: on localhost (or with ?dev=1 in the URL), the Tweaks panel
// is shown and can override the device choice; "phone" mode renders inside
// an iPhone frame for design preview.

const PHONE_MODELS = {
  'iphone-16-pro-max': { label: 'iPhone 16 Pro Max', width: 440, height: 956 },
  'iphone-16':         { label: 'iPhone 16',         width: 402, height: 874 },
  'iphone-se':         { label: 'iPhone SE',         width: 375, height: 667 },
};

// Mobile viewport breakpoint. Phones (and most tablets in portrait) are below
// this; everything above gets the desktop site.
const MOBILE_BREAKPOINT = 768;

// Mobile router — mirrors App's hash routing but renders mobile screens.
function MobileApp() {
  const [route, setRoute] = React.useState(() => {
    const h = window.location.hash.slice(1);
    return h ? parseRoute(h) : { name: 'landing' };
  });
  const [ctx, setCtxState] = React.useState({
    eventCode: null,
    first: '', last: '', email: '', birthday: '', phone: '',
    careers: [],
    guardianName: '', guardianEmail: '', guardianPhone: '',
    typedSig: '', drawnSig: '', guardianTypedSig: '',
    confirmNum: null, signedAt: null,
  });

  React.useEffect(() => {
    const onHash = () => setRoute(parseRoute(window.location.hash.slice(1)));
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, []);

  const setCtx = (patch) => setCtxState(c => ({ ...c, ...(typeof patch === 'function' ? patch(c) : patch) }));
  const go = (name, params = {}) => {
    if (params.eventCode) setCtx({ eventCode: params.eventCode });
    const newRoute = { name, step: params.step ?? 0 };
    setRoute(newRoute);
    window.location.hash = serializeRoute(newRoute);
  };

  return (
    <div data-screen-label={'Mobile · ' + route.name.toUpperCase()} data-screen style={{ height: '100%', width: '100%' }}>
      {route.name === 'landing' && <LandingMobile go={go} />}
      {route.name === 'signup' && <SignupMobile ctx={ctx} setCtx={setCtx} go={go} step={route.step || 0} />}
      {route.name === 'admin' && <AdminGate go={go}><AdminMobile go={go} /></AdminGate>}
    </div>
  );
}

function PhoneFrame({ model = 'iphone-16', dark = true, children }) {
  const m = PHONE_MODELS[model] || PHONE_MODELS['iphone-16'];
  const [stage, setStage] = React.useState({ w: window.innerWidth, h: window.innerHeight });
  React.useEffect(() => {
    const onResize = () => setStage({ w: window.innerWidth, h: window.innerHeight });
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, []);

  const padX = 64, padY = 48;
  const fit = Math.min(
    (stage.w - padX) / m.width,
    (stage.h - padY) / m.height,
    1,
  );

  return (
    <div className="phone-stage" style={{ width: '100%', height: '100%' }}>
      <div style={{ transform: `scale(${fit})`, transformOrigin: 'center center' }}>
        <IOSDevice width={m.width} height={m.height} dark={dark}>
          <div style={{ width: m.width, height: m.height, overflow: 'hidden', background: '#0e0e10' }}>
            {children}
          </div>
        </IOSDevice>
      </div>
    </div>
  );
}

// Whether to show dev controls (Tweaks panel + iPhone-frame preview). True on
// localhost, or when ?dev=1 is in the URL — handy for design review on the
// deployed site without exposing the panel to real visitors.
function isDevContext() {
  if (typeof window === 'undefined') return false;
  const host = window.location.hostname;
  if (host === 'localhost' || host === '127.0.0.1' || host.endsWith('.local')) return true;
  if (window.location.search.includes('dev=1')) return true;
  return false;
}

function Shell() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [isMobileViewport, setIsMobileViewport] = React.useState(() =>
    typeof window !== 'undefined' && window.innerWidth < MOBILE_BREAKPOINT
  );
  const dev = isDevContext();

  React.useEffect(() => {
    const onResize = () => setIsMobileViewport(window.innerWidth < MOBILE_BREAKPOINT);
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, []);

  // Effective device choice:
  //   prod → viewport width decides
  //   dev  → tweaks panel decides (so designers can preview either layout)
  const useMobile = dev ? t.device === 'phone' : isMobileViewport;
  // The iPhone bezel/frame is purely a dev preview — never wrap real visitors.
  const showFrame = dev && t.device === 'phone';

  React.useEffect(() => {
    document.body.classList.toggle('phone-view', showFrame);
  }, [showFrame]);

  const phoneModelOptions = Object.keys(PHONE_MODELS);
  const mobileEl = showFrame
    ? <PhoneFrame model={t.phoneModel} dark={t.phoneDark}><MobileApp /></PhoneFrame>
    : <MobileApp />;

  return (
    <React.Fragment>
      {useMobile ? mobileEl : <App />}

      {dev && (
        <TweaksPanel title="Tweaks">
          <TweakSection label="Preview" />
          <TweakRadio
            label="Device"
            value={t.device}
            options={['desktop', 'phone']}
            onChange={(v) => setTweak('device', v)}
          />
          {t.device === 'phone' && (
            <React.Fragment>
              <TweakSelect
                label="Model"
                value={t.phoneModel}
                options={phoneModelOptions.map(k => ({ value: k, label: PHONE_MODELS[k].label }))}
                onChange={(v) => setTweak('phoneModel', v)}
              />
              <TweakToggle
                label="Dark bezel"
                value={t.phoneDark}
                onChange={(v) => setTweak('phoneDark', v)}
              />
            </React.Fragment>
          )}
        </TweaksPanel>
      )}
    </React.Fragment>
  );
}
