import { useSyncExternalStore } from 'react';

const subscribe = () => () => {};
const getClientSnapshot = () => true;
const getServerSnapshot = () => false;

export function useHydrated(): boolean {
  return useSyncExternalStore(subscribe, getClientSnapshot, getServerSnapshot);
}

const subscribeReducedMotion = (onStoreChange: () => void) => {
  if (typeof window === 'undefined') return () => {};
  const media = window.matchMedia('(prefers-reduced-motion: reduce)');
  media.addEventListener('change', onStoreChange);
  return () => media.removeEventListener('change', onStoreChange);
};

const getReducedMotionSnapshot = () =>
  typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;

const getReducedMotionServerSnapshot = () => false;

export function usePrefersReducedMotion(): boolean {
  return useSyncExternalStore(
    subscribeReducedMotion,
    getReducedMotionSnapshot,
    getReducedMotionServerSnapshot,
  );
}

const subscribePathname = (onStoreChange: () => void) => {
  if (typeof window === 'undefined') return () => {};
  window.addEventListener('popstate', onStoreChange);
  document.addEventListener('astro:page-load', onStoreChange);
  return () => {
    window.removeEventListener('popstate', onStoreChange);
    document.removeEventListener('astro:page-load', onStoreChange);
  };
};

const getPathnameSnapshot = () => window.location.pathname;
const getPathnameServerSnapshot = () => '/';

export function useBrowserPathname(): string {
  return useSyncExternalStore(subscribePathname, getPathnameSnapshot, getPathnameServerSnapshot);
}

const getHrefSnapshot = () => window.location.href;
const getHrefServerSnapshot = () => '';

export function useBrowserHref(): string {
  return useSyncExternalStore(subscribePathname, getHrefSnapshot, getHrefServerSnapshot);
}

const getBodySnapshot = () => document.body;
const getBodyServerSnapshot = () => null;

export function useBrowserBody(): HTMLElement | null {
  return useSyncExternalStore(subscribePathname, getBodySnapshot, getBodyServerSnapshot);
}
