// Tiny SPA router — History API, link interception, popstate.
// No deps. Pages link with <a href="/foo" data-link>.

const RouteContext = React.createContext({ path: "/", navigate: () => {} });

const Router = ({ children }) => {
  const [path, setPath] = React.useState(window.location.pathname);

  React.useEffect(() => {
    const onPop = () => setPath(window.location.pathname);
    window.addEventListener("popstate", onPop);

    const onClick = (e) => {
      if (e.defaultPrevented) return;
      if (e.button !== 0) return;
      if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;
      const a = e.target.closest("a[data-link]");
      if (!a) return;
      const href = a.getAttribute("href");
      if (!href || !href.startsWith("/")) return;
      e.preventDefault();
      if (href !== window.location.pathname) {
        window.history.pushState({}, "", href);
        setPath(href);
        window.scrollTo(0, 0);
      }
    };
    document.addEventListener("click", onClick);

    return () => {
      window.removeEventListener("popstate", onPop);
      document.removeEventListener("click", onClick);
    };
  }, []);

  const navigate = React.useCallback((to, replace = false) => {
    if (replace) window.history.replaceState({}, "", to);
    else window.history.pushState({}, "", to);
    setPath(to);
    window.scrollTo(0, 0);
  }, []);

  return (
    <RouteContext.Provider value={{ path, navigate }}>
      {children}
    </RouteContext.Provider>
  );
};

const useRoute = () => React.useContext(RouteContext);

const useViewport = () => {
  const [size, setSize] = React.useState({
    w: window.innerWidth,
    h: window.innerHeight,
  });
  React.useEffect(() => {
    const onResize = () =>
      setSize({ w: window.innerWidth, h: window.innerHeight });
    window.addEventListener("resize", onResize);
    return () => window.removeEventListener("resize", onResize);
  }, []);
  return size;
};

// Connection state — stored as JSON { email, name }. Legacy raw-email strings
// are migrated transparently on read.
const parseConnected = () => {
  const raw = localStorage.getItem("redgone_connected");
  if (!raw) return null;
  try {
    const obj = JSON.parse(raw);
    if (obj && typeof obj === "object" && obj.email) {
      return { email: obj.email, name: obj.name || obj.email.split("@")[0] };
    }
  } catch (_) {}
  // legacy: raw email string
  const email = raw;
  const localPart = email.split("@")[0] || email;
  const name = localPart
    .split(/[._-]/)
    .filter(Boolean)
    .map(s => s[0].toUpperCase() + s.slice(1))
    .join(" ") || localPart;
  return { email, name };
};

const useConnected = () => {
  const [user, setUser] = React.useState(() => parseConnected());
  React.useEffect(() => {
    const onUpdate = () => setUser(parseConnected());
    window.addEventListener("storage", onUpdate);
    window.addEventListener("redgone:auth", onUpdate);
    return () => {
      window.removeEventListener("storage", onUpdate);
      window.removeEventListener("redgone:auth", onUpdate);
    };
  }, []);
  return user;
};

const setConnected = (val) => {
  if (val === null || val === undefined) {
    localStorage.removeItem("redgone_connected");
  } else if (typeof val === "string") {
    const localPart = val.split("@")[0] || val;
    const name = localPart
      .split(/[._-]/).filter(Boolean)
      .map(s => s[0].toUpperCase() + s.slice(1)).join(" ") || localPart;
    localStorage.setItem("redgone_connected", JSON.stringify({ email: val, name }));
  } else if (typeof val === "object" && val.email) {
    const name = val.name || val.email.split("@")[0];
    localStorage.setItem(
      "redgone_connected",
      JSON.stringify({ email: val.email, name })
    );
  }
  window.dispatchEvent(new Event("redgone:auth"));
};

window.Router = Router;
window.RouteContext = RouteContext;
window.useRoute = useRoute;
window.useViewport = useViewport;
window.useConnected = useConnected;
window.setConnected = setConnected;
