import { createContext as createReactContext, useContext } from 'react';
import { createContext, useRouteLoaderData } from 'react-router';

/**
 * Per-request CSP nonce. Set by the root route middleware, read with
 * `context.get(nonceContext)` in loaders/actions and `entry.server`.
 */
export const nonceContext = createContext<string>('');

// Available even when the root loader fails or is skipped by an unmatched route.
export const CspNonceContext = createReactContext<string | undefined>(undefined);

/**
 * Preserve the document nonce during hydration and client navigation. Clearing it
 * makes React-inserted styles fail the original document's Content Security Policy.
 * useCspNonce prefers the document provider over later loader-response nonces.
 */
export const nonce = (value: string | undefined): string | undefined => value;

/**
 * Reads the per-request CSP nonce surfaced by the root loader. Use this
 * inside any non-root route component that needs to render a `<style>`,
 * `<script>`, or other element that the CSP gates by nonce.
 *
 * Centralised here so the cast is in one place — if the root loader's
 * `nonce` field is ever renamed/removed, only this function needs updating
 * (and TypeScript will catch it at the cast site).
 */
export const useCspNonce = (): string | undefined => {
  const rootData = useRouteLoaderData('root') as { nonce?: string } | undefined;

  const documentNonce = useContext(CspNonceContext);
  return documentNonce ?? rootData?.nonce;
};
