// app.jsx — shell: theme tokens, bottom nav, tab routing, tweaks, scaling, mount.

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#2f6fed",
  "theme": "Dark",
  "font": "System",
  "radius": 18,
  "units": "mi",
  "demoDistance": "Short walk"
}/*EDITMODE-END*/;

const DEMO_DIST = { "Beside it": 16, "Short walk": 300, "Across town": 2400 };

const ACCENT_OPTS = ["#2f6fed", "#10a3c4", "#7c5cf0", "#e8612c"];
const FONT_STACKS = {
  "System": '-apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif',
  "Space Grotesk": '"Space Grotesk", system-ui, sans-serif',
  "Manrope": '"Manrope", system-ui, sans-serif',
  "IBM Plex Sans": '"IBM Plex Sans", system-ui, sans-serif',
};

function themeVars(t) {
  const dark = t.theme === "Dark";
  const radius = t.radius;
  const radiusSm = Math.max(9, radius - 6);
  const base = {
    "--accent": t.accent,
    "--on-accent": "#ffffff",
    "--accent-soft": `color-mix(in srgb, ${t.accent} 16%, transparent)`,
    "--accent-glow": `color-mix(in srgb, ${t.accent} 32%, transparent)`,
    "--radius": radius + "px",
    "--radius-sm": radiusSm + "px",
    // Respect the device's home-indicator inset when running full-screen on a
    // real phone; falls back to 10px on desktop (where the inset is 0).
    "--safe-bottom": "max(10px, env(safe-area-inset-bottom))",
    "--font-ui": FONT_STACKS[t.font] || FONT_STACKS.System,
  };
  const dk = {
    "--bg": "#0e141b",
    "--surface": "#18212c",
    "--surface-2": "#212c38",
    "--surface-raise": "#2b3744",
    "--text": "#e9eef3",
    "--text-2": "#9aa7b4",
    "--text-3": "#637280",
    "--hairline": "rgba(255,255,255,.07)",
    "--border-strong": "rgba(255,255,255,.17)",
    "--card-shadow": "0 1px 2px rgba(0,0,0,.32)",
    "--danger": "#ff6f6f",
    "--danger-bg": "rgba(255,111,111,.15)",
    "--toast-bg": "#eaf0f5",
    "--toast-ink": "#0e141b",
    "--nav-bg": "rgba(16,23,32,.72)",
    "--accent-ink": `color-mix(in srgb, ${t.accent} 52%, #eaf0f5)`,
  };
  const lt = {
    "--bg": "#eef1f5",
    "--surface": "#ffffff",
    "--surface-2": "#eef2f6",
    "--surface-raise": "#ffffff",
    "--text": "#10171e",
    "--text-2": "#586472",
    "--text-3": "#97a3b0",
    "--hairline": "rgba(16,23,30,.09)",
    "--border-strong": "rgba(16,23,30,.18)",
    "--card-shadow": "0 1px 3px rgba(16,23,30,.07)",
    "--danger": "#d63b3b",
    "--danger-bg": "rgba(214,59,59,.1)",
    "--toast-bg": "#10171e",
    "--toast-ink": "#ffffff",
    "--nav-bg": "rgba(255,255,255,.78)",
    "--accent-ink": `color-mix(in srgb, ${t.accent} 86%, #10171e)`,
  };
  return { ...base, ...(dark ? dk : lt) };
}

const TABS = [
  { id: "garage", label: "Garage", Icon: IconCar },
  { id: "park", label: "Park", Icon: IconPinPlus },
  { id: "find", label: "Find", Icon: IconCompass },
  { id: "history", label: "History", Icon: IconClock },
];

function BottomNav({ active, onChange }) {
  return (
    <div style={{
      position: "absolute", left: 0, right: 0, bottom: 0, zIndex: 100,
      paddingBottom: "calc(8px + var(--safe-bottom))", paddingTop: 8,
      display: "flex", justifyContent: "space-around", alignItems: "stretch",
      background: "var(--nav-bg)", backdropFilter: "blur(20px) saturate(180%)",
      WebkitBackdropFilter: "blur(20px) saturate(180%)",
      borderTop: "1px solid var(--hairline)",
    }}>
      {TABS.map((t) => {
        const on = t.id === active;
        return (
          <button key={t.id} className="wmc-btn" onClick={() => onChange(t.id)} style={{
            flex: 1, border: "none", background: "transparent", cursor: "pointer",
            display: "flex", flexDirection: "column", alignItems: "center", gap: 3,
            padding: "6px 0", color: on ? "var(--accent-ink)" : "var(--text-3)",
            WebkitTapHighlightColor: "transparent", transition: "color .15s ease",
          }}>
            <t.Icon size={25} sw={on ? 2.1 : 1.8} />
            <span style={{ fontSize: 11, fontWeight: on ? 750 : 550, letterSpacing: 0.1 }}>{t.label}</span>
          </button>
        );
      })}
    </div>
  );
}

// Decide how to present the app: full-bleed on phone-sized / touch screens,
// or a scaled iPhone mockup on larger (desktop) viewports for preview.
function computeLayout() {
  const W = 402, H = 874, pad = 24;
  const vw = window.innerWidth, vh = window.innerHeight;
  const coarse = typeof window.matchMedia === "function" && window.matchMedia("(pointer: coarse)").matches;
  const fullscreen = vw <= 520 || (coarse && Math.min(vw, vh) <= 540);
  const scale = Math.min((vw - pad) / W, (vh - pad) / H, 1.15);
  return { fullscreen, scale };
}

function useDeviceLayout() {
  const [layout, setLayout] = React.useState(computeLayout);
  React.useEffect(() => {
    const fit = () => setLayout(computeLayout());
    fit();
    window.addEventListener("resize", fit);
    window.addEventListener("orientationchange", fit);
    return () => {
      window.removeEventListener("resize", fit);
      window.removeEventListener("orientationchange", fit);
    };
  }, []);
  return layout;
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [state, store] = useStore();
  const layout = useDeviceLayout();
  const [tab, setTab] = React.useState(() => localStorage.getItem("wmc.tab") || "garage");

  React.useEffect(() => { localStorage.setItem("wmc.tab", tab); }, [tab]);
  React.useEffect(() => {
    const h = () => { store.resetAll(); toast("Demo data reset"); };
    window.addEventListener("wmc-reset", h);
    return () => window.removeEventListener("wmc-reset", h);
  }, [store]);

  // "Jump to parked car": select a parked car (if needed) and open Find.
  React.useEffect(() => {
    const h = () => {
      const sel = state.cars.find((c) => c.id === state.selectedCarId);
      if (!sel || !sel.current) {
        const parked = state.cars.find((c) => c.current);
        if (parked) store.selectCar(parked.id);
        else { toast("No car is parked yet — park one first"); return; }
      }
      setTab("find");
    };
    window.addEventListener("wmc-goto-find", h);
    return () => window.removeEventListener("wmc-goto-find", h);
  }, [state.cars, state.selectedCarId, store]);

  // Position the simulated "you are here" relative to the car you're viewing,
  // so the Find map / distance / direction reflect the chosen demo distance.
  const selCar = state.cars.find((c) => c.id === state.selectedCarId) || state.cars[0];
  const refSpot = (selCar && selCar.current) || (state.cars.find((c) => c.current) || {}).current || SIM_LOCATION;
  const demoMeters = DEMO_DIST[t.demoDistance] ?? 300;
  window.__simLocation = { ...destPoint(refSpot, demoMeters, 218), accuracy: demoMeters < 40 ? 12 : 22 };
  const simKey = t.demoDistance + "|" + (selCar ? selCar.id : "") + "|" + (refSpot.lat || 0).toFixed(5);

  const dark = t.theme === "Dark";
  const vars = themeVars(t);

  const goTo = (id) => setTab(id);

  let screen;
  if (tab === "garage") screen = <GarageScreen state={state} store={store} />;
  else if (tab === "park") screen = <ParkScreen state={state} store={store} units={t.units} dark={dark} />;
  else if (tab === "find") screen = <FindScreen state={state} store={store} units={t.units} dark={dark} simKey={simKey} onGoPark={() => goTo("park")} />;
  else screen = <HistoryScreen state={state} store={store} units={t.units} onGoFind={() => goTo("find")} />;

  // Full-bleed on a phone: the device's own status bar is above the viewport,
  // so only clear the notch (safe-area inset) plus a little breathing room.
  // Desktop mockup keeps 58px to clear the simulated dynamic island.
  const topPad = layout.fullscreen ? "calc(env(safe-area-inset-top) + 18px)" : "58px";

  return (
    <Stage layout={layout}>
      <IOSDevice dark={dark} fullscreen={layout.fullscreen}>
        <div className="wmc-root" style={{ ...vars, fontFamily: "var(--font-ui)", background: "var(--bg)", color: "var(--text)", height: "100%", position: "relative", display: "flex", flexDirection: "column" }}>
          <div className="wmc-scroll wmc-noscroll" style={{ flex: 1, overflowY: "auto", overflowX: "hidden", padding: `${topPad} 18px 104px`, WebkitOverflowScrolling: "touch" }}>
            {screen}
          </div>
          <BottomNav active={tab} onChange={goTo} />
          <ToastHost />
        </div>
      </IOSDevice>

      <TweaksPanel>
        <TweakSection label="Appearance" />
        <TweakRadio label="Theme" value={t.theme} options={["Dark", "Light"]} onChange={(v) => setTweak("theme", v)} />
        <TweakColor label="Accent" value={t.accent} options={ACCENT_OPTS} onChange={(v) => setTweak("accent", v)} />
        <TweakSelect label="Font" value={t.font} options={Object.keys(FONT_STACKS)} onChange={(v) => setTweak("font", v)} />
        <TweakSlider label="Corner radius" value={t.radius} min={6} max={26} step={1} unit="px" onChange={(v) => setTweak("radius", v)} />
        <TweakSection label="Units" />
        <TweakRadio label="Distance" value={t.units} options={["mi", "km"]} onChange={(v) => setTweak("units", v)} />
        <TweakSection label="Demo · view parked car" />
        <TweakButton label="📍  Jump to parked car" onClick={() => window.dispatchEvent(new CustomEvent("wmc-goto-find"))} />
        <TweakSelect label="Your distance from car" value={t.demoDistance} options={["Beside it", "Short walk", "Across town"]} onChange={(v) => setTweak("demoDistance", v)} />
        <TweakSection label="Data" />
        <TweakButton label="Reset demo data" onClick={() => window.dispatchEvent(new CustomEvent("wmc-reset"))} />
      </TweaksPanel>
    </Stage>
  );
}

// ── Stage ────────────────────────────────────────────────────
// Phone: render children full-bleed (they fill the device screen).
// Desktop: center a scaled 402×874 iPhone mockup for preview.
function Stage({ children, layout }) {
  if (layout.fullscreen) {
    return (
      <div style={{ position: "fixed", inset: 0, background: "var(--page-bg)", overflow: "hidden" }}>
        {children}
      </div>
    );
  }
  return (
    <div style={{ position: "fixed", inset: 0, display: "grid", placeItems: "center", background: "var(--page-bg)", overflow: "hidden" }}>
      <div style={{ transform: `scale(${layout.scale})`, transformOrigin: "center center" }}>
        {children}
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
