// Hotel Walks — app shell, top-tab navigation, hash routing.
// All screens mount inside <App>.

const { useState, useEffect, useMemo } = React;
const { SmartKey, Wordmark, Lockup, tokens: HWT } = window.HW;
const { Caps, Btn, Pill } = window.UI;

/* ─────────────────────────────────────────────────────────
   Hash router — supports /, /app, /app/send, /app/incoming/:id,
   /app/letter/:id, /app/invoices, /guest/:id
   ───────────────────────────────────────────────────────── */
function useHashRoute() {
  const parse = () => {
    const raw = window.location.hash.replace(/^#/, "") || "/";
    const [path, queryStr] = raw.split("?");
    const parts = path.split("/").filter(Boolean);
    const query = {};
    if (queryStr) queryStr.split("&").forEach(p => { const [k, v] = p.split("="); query[k] = decodeURIComponent(v || ""); });
    return { path, parts, query, raw };
  };
  const [route, setRoute] = useState(parse());
  useEffect(() => {
    const on = () => setRoute(parse());
    window.addEventListener("hashchange", on);
    return () => window.removeEventListener("hashchange", on);
  }, []);
  return route;
}

function go(path) {
  window.location.hash = path;
  // scroll any internal scroller back to top
  const main = document.querySelector("[data-main-scroll]");
  if (main) main.scrollTop = 0;
}
window.HWgo = go;

/* ─────────────────────────────────────────────────────────
   Tweaks — light/dark mode (host-persisted)
   ───────────────────────────────────────────────────────── */
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "light"
}/*EDITMODE-END*/;

function useTheme() {
  const [theme, setTheme] = useState(TWEAK_DEFAULTS.theme);
  useEffect(() => {
    document.documentElement.setAttribute("data-theme", theme);
  }, [theme]);
  return [theme, setTheme];
}

/* ─────────────────────────────────────────────────────────
   Small stroke icons for the top nav tabs.
   ───────────────────────────────────────────────────────── */
function NavIcon({ kind, size = 18 }) {
  const stroke = "currentColor";
  const sw = 1.6;
  const common = { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke, strokeWidth: sw, strokeLinecap: "square", strokeLinejoin: "round" };
  switch (kind) {
    case "today":     // calendar with current-day pip
      return (
        <svg {...common}>
          <rect x="3.5" y="5" width="17" height="15" />
          <line x1="3.5" y1="10" x2="20.5" y2="10" />
          <line x1="8"   y1="3.5" x2="8"   y2="6.5" />
          <line x1="16"  y1="3.5" x2="16"  y2="6.5" />
          <rect x="11" y="13" width="3" height="3" fill={stroke} />
        </svg>
      );
    case "send":      // outbound paper plane
      return (
        <svg {...common}>
          <polygon points="3.5,12 20.5,4 14,20 11.5,13" />
          <line x1="11.5" y1="13" x2="20.5" y2="4" />
        </svg>
      );
    case "incoming":  // inbox tray with downward arrow
      return (
        <svg {...common}>
          <polyline points="3.5,13 8,13 9.5,16 14.5,16 16,13 20.5,13 20.5,20 3.5,20 3.5,13" />
          <line x1="12" y1="3.5" x2="12" y2="11.5" />
          <polyline points="9,9 12,12 15,9" />
        </svg>
      );
    case "letters":   // document with lines
      return (
        <svg {...common}>
          <polygon points="5,3.5 15,3.5 19,7.5 19,20.5 5,20.5" />
          <polyline points="15,3.5 15,7.5 19,7.5" />
          <line x1="8" y1="12" x2="16" y2="12" />
          <line x1="8" y1="15" x2="16" y2="15" />
          <line x1="8" y1="18" x2="13" y2="18" />
        </svg>
      );
    case "invoices":  // receipt / ledger
      return (
        <svg {...common}>
          <polyline points="5,3.5 5,20.5 8,19 11,20.5 14,19 17,20.5 19,19 19,3.5" />
          <line x1="8" y1="9"  x2="16" y2="9" />
          <line x1="8" y1="13" x2="16" y2="13" />
          <line x1="8" y1="16" x2="13" y2="16" />
        </svg>
      );
    default: return null;
  }
}

/* ─────────────────────────────────────────────────────────
   Top tab nav
   ───────────────────────────────────────────────────────── */
function TopNav({ active, onMarketing }) {
  const { ME } = window.HW_DATA;
  const [open, setOpen] = useState(false);
  const tabs = [
    { id: "app",      label: "Today",     path: "/app",           icon: "today"    },
    { id: "send",     label: "Send",      path: "/app/send",      icon: "send"     },
    { id: "incoming", label: "Incoming",  path: "/app/incoming",  icon: "incoming", badge: window.HW_DATA.INCOMING.length },
    { id: "letters",  label: "Letters",   path: "/app/letters",   icon: "letters"  },
    { id: "invoices", label: "Invoices",  path: "/app/invoices",  icon: "invoices" },
  ];
  const activeTab = tabs.find(t => t.id === active);

  // Close drawer on route change
  useEffect(() => { setOpen(false); }, [active]);

  return (
    <header style={{
      background: "var(--bone)",
      borderBottom: "1px solid var(--rule)",
      position: "sticky", top: 0, zIndex: 50,
    }} className="no-print">
      {/* Top strip: lockup + property + user */}
      <div style={{
        display: "flex", alignItems: "center", justifyContent: "space-between",
        padding: "14px 28px", borderBottom: "1px solid var(--rule)",
      }} className="topbar">
        <a href="#/" style={{ display: "inline-flex", alignItems: "center", gap: 14, textDecoration: "none", color: "inherit" }}>
          <SmartKey size={36} fg="var(--bone)" bg="var(--ink)" />
          <span className="serif-i" style={{ fontSize: 24, lineHeight: 1 }}>Hotel Walks</span>
        </a>

        {/* Desktop right side */}
        <div className="topbar-right" style={{ display: "flex", alignItems: "center", gap: 22 }}>
          <div style={{ textAlign: "right", lineHeight: 1.2 }} className="property-meta">
            <div className="caps">Property</div>
            <div style={{ fontSize: 15, marginTop: 5, fontWeight: 500 }}>{ME.property.name}</div>
          </div>
          <div style={{ width: 1, height: 30, background: "var(--rule-strong)" }} />
          <div title={ME.user.name} style={{
            width: 38, height: 38, borderRadius: "50%",
            background: "var(--ink)", color: "var(--bone)",
            display: "inline-flex", alignItems: "center", justifyContent: "center",
            fontSize: 12, fontWeight: 500, fontFamily: "'JetBrains Mono', monospace", letterSpacing: "0.06em",
          }}>{ME.user.initials}</div>
          <button onClick={onMarketing} style={{
            background: "transparent", border: "none", padding: 0,
          }}><Caps style={{ whiteSpace: "nowrap" }}>Site ↗</Caps></button>
        </div>

        {/* Mobile hamburger */}
        <button
          onClick={() => setOpen(o => !o)}
          className="hamburger"
          aria-label="Menu"
          style={{
            display: "none",
            background: "transparent", border: "1px solid var(--ink)",
            padding: "10px 12px", cursor: "pointer",
            color: "var(--ink)", alignItems: "center", gap: 10,
          }}>
          {/* current page label */}
          <span style={{
            fontFamily: "'JetBrains Mono', monospace",
            fontSize: 11, letterSpacing: "0.14em", textTransform: "uppercase",
          }}>
            {activeTab?.label || "Menu"}
            {activeTab?.badge > 0 ? ` · ${activeTab.badge}` : ""}
          </span>
          {/* hamburger glyph */}
          <span style={{ display: "inline-flex", flexDirection: "column", gap: 3 }}>
            <span style={{ width: 16, height: 1.5, background: "var(--ink)", transition: "transform 0.18s", transform: open ? "translateY(4.5px) rotate(45deg)" : "none", transformOrigin: "center" }}/>
            <span style={{ width: 16, height: 1.5, background: "var(--ink)", opacity: open ? 0 : 1, transition: "opacity 0.12s" }}/>
            <span style={{ width: 16, height: 1.5, background: "var(--ink)", transition: "transform 0.18s", transform: open ? "translateY(-4.5px) rotate(-45deg)" : "none", transformOrigin: "center" }}/>
          </span>
        </button>
      </div>

      {/* Desktop tab strip */}
      <nav className="tab-strip" style={{
        display: "flex", alignItems: "center", gap: 4,
        padding: "0 18px", overflowX: "auto", overflowY: "hidden",
      }}>
        {tabs.map(t => {
          const isActive = active === t.id;
          return (
            <a key={t.id} href={"#" + t.path}
               className={"hw-nav-tab" + (isActive ? " is-active" : "")}
               style={{
              display: "inline-flex", alignItems: "center", gap: 10,
              padding: "16px 16px",
              textDecoration: "none", color: "var(--ink)",
              fontFamily: "'JetBrains Mono', monospace",
              fontSize: 13, letterSpacing: "0.08em", textTransform: "uppercase",
              fontWeight: 500,
              marginBottom: -1,
              opacity: isActive ? 1 : 0.7,
              whiteSpace: "nowrap",
            }}>
              <NavIcon kind={t.icon} size={18} />
              {t.label}
              {t.badge != null && t.badge > 0 && (
                <span style={{
                  display: "inline-flex", alignItems: "center", justifyContent: "center",
                  minWidth: 22, height: 22, padding: "0 7px",
                  background: "var(--ink)",
                  color: "var(--bone)",
                  border: "1px solid var(--ink)",
                  fontSize: 11, fontWeight: 600,
                }}>{t.badge}</span>
              )}
            </a>
          );
        })}

        {/* Spacer + secondary actions */}
        <div style={{ flex: 1 }} />
        <div style={{ display: "flex", alignItems: "center", gap: 14, paddingRight: 10 }}>
          <Caps style={{ fontSize: 12, whiteSpace: "nowrap" }}>{`${window.HW_DATA.ME.user.shift} shift · ${new Date().toLocaleDateString(undefined, { weekday: "short", month: "short", day: "numeric" })}`}</Caps>
        </div>
      </nav>

      {/* Mobile drawer */}
      {open && (
        <div className="mobile-drawer" style={{
          display: "none",
          borderTop: "1px solid var(--rule)",
          background: "var(--bone)",
        }}>
          {/* Property + user */}
          <div style={{
            padding: "20px 24px",
            borderBottom: "1px solid var(--rule)",
            display: "flex", justifyContent: "space-between", alignItems: "center",
          }}>
            <div>
              <Caps>Property</Caps>
              <div style={{ fontSize: 15, marginTop: 4 }}>{ME.property.name}</div>
            </div>
            <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
              <Caps>{ME.user.shift} shift</Caps>
              <div style={{
                width: 36, height: 36, borderRadius: "50%",
                background: "var(--ink)", color: "var(--bone)",
                display: "inline-flex", alignItems: "center", justifyContent: "center",
                fontSize: 12, fontFamily: "'JetBrains Mono', monospace", letterSpacing: "0.06em",
              }}>{ME.user.initials}</div>
            </div>
          </div>

          {/* Routes */}
          {tabs.map(t => {
            const isActive = active === t.id;
            return (
              <a key={t.id} href={"#" + t.path} style={{
                display: "flex", alignItems: "center", justifyContent: "space-between",
                padding: "20px 24px",
                textDecoration: "none", color: "var(--ink)",
                borderBottom: "1px solid var(--rule)",
                background: isActive ? "var(--bone-2)" : "transparent",
              }}>
                <span className="serif-i" style={{ fontSize: 22 }}>{t.label}</span>
                <div style={{ display: "inline-flex", alignItems: "center", gap: 12 }}>
                  {t.badge > 0 && (
                    <span style={{
                      display: "inline-flex", alignItems: "center", justifyContent: "center",
                      minWidth: 22, height: 22, padding: "0 6px",
                      border: "1px solid var(--ink)",
                      fontFamily: "'JetBrains Mono', monospace",
                      fontSize: 10,
                    }}>{t.badge}</span>
                  )}
                  {isActive
                    ? <Caps>Now ·</Caps>
                    : <Caps>→</Caps>}
                </div>
              </a>
            );
          })}

          {/* Footer: site link */}
          <button onClick={onMarketing} style={{
            width: "100%", padding: "20px 24px", textAlign: "left",
            background: "transparent", border: "none",
            borderBottom: "1px solid var(--rule)",
            cursor: "pointer", color: "var(--ink)",
          }}>
            <Caps>Marketing site ↗</Caps>
          </button>
        </div>
      )}
    </header>
  );
}

/* Mobile responsiveness — hide desktop nav, show hamburger + drawer */
const responsiveCSS = `
  @media (max-width: 720px) {
    .property-meta { display: none; }
    .topbar { padding: 12px 18px !important; }
    .topbar-right { display: none !important; }
    .tab-strip { display: none !important; }
    .hamburger { display: inline-flex !important; }
    .mobile-drawer { display: block !important; }
  }
`;

/* ─────────────────────────────────────────────────────────
   Theme tweak panel
   ───────────────────────────────────────────────────────── */
function ThemeTweaks({ theme, setTheme }) {
  const { TweaksPanel, TweakSection, TweakRadio } = window;
  return (
    <TweaksPanel title="Tweaks">
      <TweakSection title="Theme">
        <TweakRadio
          label="Surface"
          value={theme}
          onChange={(v) => {
            setTheme(v);
            window.parent.postMessage({ type: "__edit_mode_set_keys", edits: { theme: v } }, "*");
          }}
          options={[
            { label: "Bone",  value: "light" },
            { label: "Ink",   value: "dark"  },
          ]}
        />
      </TweakSection>
    </TweaksPanel>
  );
}

/* ─────────────────────────────────────────────────────────
   Route resolver
   ───────────────────────────────────────────────────────── */
function Routes({ route }) {
  const p = route.parts;

  // /                  → marketing
  // /guest/:id         → guest cancellation
  // /app               → dashboard
  // /app/send          → send walk request
  // /app/incoming      → incoming queue
  // /app/incoming/:id  → opportunity detail
  // /app/letters       → letters list (just shows most recent)
  // /app/letter/:id    → walk letter doc
  // /app/invoices      → invoices

  if (p.length === 0) return <window.Screens.Marketing />;
  if (p[0] === "guest") return <window.Screens.Guest id={p[1]} />;

  if (p[0] === "app") {
    if (!p[1])                       return <window.Screens.Dashboard />;
    if (p[1] === "send")             return <window.Screens.SendWalk />;
    if (p[1] === "incoming" && !p[2])return <window.Screens.IncomingList />;
    if (p[1] === "incoming" && p[2]) return <window.Screens.IncomingDetail id={p[2]} />;
    if (p[1] === "letters" && !p[2]) return <window.Screens.LettersList />;
    if (p[1] === "letter" && p[2])   return <window.Screens.WalkLetter id={p[2]} />;
    if (p[1] === "invoices")         return <window.Screens.Invoices />;
  }
  return (
    <div style={{ padding: 60 }}>
      <h2 className="serif-i" style={{ fontSize: 36 }}>Not found</h2>
      <p>No screen matches <span className="mono">{route.raw}</span>.</p>
      <Btn onClick={() => go("/app")}>Back to today</Btn>
    </div>
  );
}

/* ─────────────────────────────────────────────────────────
   Root
   ───────────────────────────────────────────────────────── */
function App() {
  const route = useHashRoute();
  const [theme, setTheme] = useTheme();

  // Scroll to top whenever the route changes, regardless of how navigation happened
  // (programmatic via go(), or a static <a href="#..."> link).
  // Use the path part so a hash change to the same screen with new ?query stays put.
  useEffect(() => {
    window.scrollTo(0, 0);
    const main = document.querySelector("[data-main-scroll]");
    if (main) main.scrollTop = 0;
  }, [route.path]);

  // Active tab id
  const activeTab = useMemo(() => {
    const p = route.parts;
    if (p[0] !== "app") return null;
    if (!p[1]) return "app";
    if (p[1] === "send") return "send";
    if (p[1] === "incoming") return "incoming";
    if (p[1] === "letter" || p[1] === "letters") return "letters";
    if (p[1] === "invoices") return "invoices";
    return null;
  }, [route]);

  const isMarketing = route.parts.length === 0;
  const isGuest = route.parts[0] === "guest";
  const isLetter = route.parts[1] === "letter";

  // Show chrome only inside /app
  const showChrome = !isMarketing && !isGuest;

  return (
    <div style={{ minHeight: "100vh", display: "flex", flexDirection: "column" }}>
      <style>{responsiveCSS}</style>
      {showChrome && <TopNav active={activeTab} onMarketing={() => go("/")} />}
      <main data-main-scroll style={{ flex: 1 }}>
        <Routes route={route} />
      </main>
      {showChrome && !isLetter && <ThemeTweaks theme={theme} setTheme={setTheme} />}
    </div>
  );
}

// Wait until all screen modules registered before mounting.
function mount() {
  if (!window.Screens || !window.Screens.Marketing) {
    setTimeout(mount, 30); return;
  }
  ReactDOM.createRoot(document.getElementById("root")).render(<App />);
}
mount();
