// app.jsx — Orchestrator. Mounts island components, runs the live countdown,
// and renders the Tweaks panel which drives body data-attributes.

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "forest",
  "displayFont": "bigshoulders",
  "showIllustrations": true,
  "density": "regular",
  "tone": "guide"
}/*EDITMODE-END*/;

// ── Live countdown ────────────────────────────────────────────────────────
// Launch is Sunday, June 21, 2026, 9:00 AM Mountain Time (UTC-6 in summer).
// We treat 09:00 MDT = 15:00 UTC.
const LAUNCH_UTC = new Date("2026-06-21T15:00:00Z");

function useCountdown() {
  const [now, setNow] = React.useState(() => new Date());
  React.useEffect(() => {
    const id = setInterval(() => setNow(new Date()), 1000);
    return () => clearInterval(id);
  }, []);
  let diff = Math.max(0, LAUNCH_UTC.getTime() - now.getTime());
  const days = Math.floor(diff / (24 * 3600 * 1000)); diff -= days * 24 * 3600 * 1000;
  const hours = Math.floor(diff / (3600 * 1000));    diff -= hours * 3600 * 1000;
  const minutes = Math.floor(diff / (60 * 1000));    diff -= minutes * 60 * 1000;
  const seconds = Math.floor(diff / 1000);
  return { days, hours, minutes, seconds, done: LAUNCH_UTC.getTime() <= Date.now() };
}

function Countdown() {
  const c = useCountdown();
  const fmt = (n) => String(n).padStart(2, "0");
  // Update the static DOM cells so the section that was server-rendered as
  // plain HTML stays in sync — this component owns the values, but those
  // dashes were placeholders so they show during paint.
  React.useEffect(() => {
    const set = (k, v) => {
      const el = document.querySelector(`[data-cd="${k}"]`);
      if (el) el.textContent = v;
    };
    set("days", fmt(c.days));
    set("hours", fmt(c.hours));
    set("minutes", fmt(c.minutes));
    set("seconds", fmt(c.seconds));
  }, [c.days, c.hours, c.minutes, c.seconds]);
  return null;
}

function NavCountdown() {
  const c = useCountdown();
  if (c.done) {
    return <span className="nav-countdown"><b>ON RIVER</b></span>;
  }
  return (
    <span className="nav-countdown" title="Time to launch">
      <b>T-{c.days}d</b><span>·</span><span>{String(c.hours).padStart(2,"0")}:{String(c.minutes).padStart(2,"0")}:{String(c.seconds).padStart(2,"0")}</span>
    </span>
  );
}

// ── Tweaks → body data attribute syncer ──────────────────────────────────
function applyTweaks(t) {
  document.body.dataset.palette = t.palette;
  document.body.dataset.illustrations = t.showIllustrations ? "on" : "off";
  document.body.dataset.density = t.density;
  document.body.dataset.tone = t.tone;
  document.body.dataset.display = t.displayFont;

  const FONT_MAP = {
    bigshoulders: '"Big Shoulders Display"',
    alfaslab:     '"Alfa Slab One"',
    anton:        '"Anton"',
    cinzel:       '"Cinzel"',
    bungee:       '"Bungee"',
  };
  document.documentElement.style.setProperty(
    "--font-display",
    FONT_MAP[t.displayFont] || FONT_MAP.bigshoulders
  );
}

function Tweaks() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  React.useEffect(() => { applyTweaks(t); }, [t]);

  return (
    <TweaksPanel title="Field Hub Tweaks">
      <TweakSection label="Palette" />
      <TweakColor
        label="Color story"
        value={[paletteSwatch(t.palette)[0], paletteSwatch(t.palette)[1], paletteSwatch(t.palette)[2]]}
        options={[
          ["#ece1c6", "#2d4a3e", "#b85c38"],
          ["#f3e0c4", "#6b3c1e", "#d97134"],
          ["#1c2734", "#4ea88f", "#e8a652"],
          ["#e8e0cc", "#4a6a64", "#a64a2e"],
        ]}
        onChange={(arr) => {
          const map = {
            "#ece1c6": "forest",
            "#f3e0c4": "sunset",
            "#1c2734": "alpine",
            "#e8e0cc": "fadedmap",
          };
          setTweak("palette", map[arr[0].toLowerCase()] || "forest");
        }}
      />

      <TweakSection label="Type" />
      <TweakSelect
        label="Display font"
        value={t.displayFont}
        options={[
          { value: "bigshoulders", label: "Big Shoulders (default)" },
          { value: "alfaslab",     label: "Alfa Slab One" },
          { value: "anton",        label: "Anton" },
          { value: "cinzel",       label: "Cinzel" },
          { value: "bungee",       label: "Bungee" },
        ]}
        onChange={(v) => setTweak("displayFont", v)}
      />

      <TweakSection label="Layout" />
      <TweakRadio
        label="Density"
        value={t.density}
        options={["compact", "regular"]}
        onChange={(v) => setTweak("density", v)}
      />
      <TweakToggle
        label="Paper texture + illustrations"
        value={t.showIllustrations}
        onChange={(v) => setTweak("showIllustrations", v)}
      />
    </TweaksPanel>
  );
}

// The TweakColor control compares by array value; we need a stable swatch
// triplet keyed off the current palette so the chip stays selected after
// reloads.
function paletteSwatch(palette) {
  return {
    forest:   ["#ece1c6", "#2d4a3e", "#b85c38"],
    sunset:   ["#f3e0c4", "#6b3c1e", "#d97134"],
    alpine:   ["#1c2734", "#4ea88f", "#e8a652"],
    fadedmap: ["#e8e0cc", "#4a6a64", "#a64a2e"],
  }[palette] || ["#ece1c6", "#2d4a3e", "#b85c38"];
}

// ── Mount everything ─────────────────────────────────────────────────────
function mount(elId, Component) {
  const el = document.getElementById(elId);
  if (!el) return;
  ReactDOM.createRoot(el).render(<Component />);
}

mount("tweaks-root", Tweaks);
mount("river-mount", window.RiverMap);
mount("weather-mount", window.Weather);
mount("packing-mount", window.PackingChecklist);
mount("nav-countdown-mount", NavCountdown);

// Countdown runs everywhere; mount as an invisible side-effect component.
// Append a hidden host into the body so React has something to render into.
const cdHost = document.createElement("div");
cdHost.style.display = "none";
document.body.appendChild(cdHost);
ReactDOM.createRoot(cdHost).render(<Countdown />);
