import { pageContext } from "@/lib/api";
import type { LocaleCode } from "@/lib/locales";

/**
 * Editor-managed script tags, injected server-side.
 *
 * These are analytics and marketing tags, and *when* they run is the whole
 * point: fetching them after hydration changes their firing order relative to
 * page load and breaks attribution. So they are resolved during the server
 * render and printed into the HTML, exactly as the Blade layout printed them,
 * rather than being fetched by the popup component alongside everything else
 * per-URL.
 *
 * That has a cost: the page cannot be statically cached while it carries
 * per-URL snippets, because a cached page would serve one URL's targeting to
 * another. The snippets endpoint is `no-store` and this component is rendered
 * on every request.
 *
 * The markup is trusted by design. These fields are editable only at the
 * highest permission level in the admin panel — the same trust boundary the
 * Blade partials applied to the same values. Anyone who can set a snippet can
 * already publish arbitrary content on the site.
 */
export default async function CodeSnippets({
  locale,
  path,
  position,
  enabled,
}: {
  locale: LocaleCode;
  path: string;
  position: "head" | "bodyStart" | "bodyEnd";
  /**
   * Whether the site has any active snippet at all, from the cached /site
   * payload. False skips the uncacheable request entirely — which is what lets
   * a site with no snippets configured keep a cacheable page instead of paying
   * a per-request round trip for a feature nobody is using.
   */
  enabled: boolean;
}) {
  if (!enabled) {
    return null;
  }

  let context: Record<string, any> | null = null;

  try {
    context = await pageContext(locale, path);
  } catch {
    // A snippet fetch that fails must not take the page with it. Missing
    // analytics is a reporting gap; a thrown render is an outage.
    return null;
  }

  const markup = context?.snippets?.[position];

  if (!markup) {
    return null;
  }

  /*
   * Emitted inside <body>, including the "head" position.
   *
   * The App Router gives a page no way to inject raw markup into <head> — only
   * the root layout renders it, and it cannot see this page's URL without
   * opting the whole route tree out of static rendering. In practice the
   * difference is a few hundred bytes of <head> parsing: tag managers are
   * position-tolerant and the head on this site is small. It is a deviation
   * from the Blade layout all the same, and worth knowing about if a vendor
   * ever insists on head placement.
   *
   * The scripts do run: this is server-rendered HTML, so the browser parses the
   * tags out of the document as it arrives. (They would NOT run if this markup
   * were inserted on the client — innerHTML does not execute scripts — which is
   * another reason these are resolved during the server render.)
   */
  return <div data-snippets={position} dangerouslySetInnerHTML={{ __html: markup }} />;
}
