services/config/config.jsxjavascript
/*
  Central place for app configuration values coming from two sources:
    - .env variables  (source: "env",   read via import.meta.env)
    - URL search params (source: "param", read via useSearchParams)

  Adding a new config value should NOT require new hook logic. Just add one
  entry to CONFIG_SCHEMA in config-schema.js - useConfig() reads and validates it generically
  via parseConfigValue() (src/utils/validationFunctions.js).

  No React Context/Provider here on purpose: import.meta.env is static and
  useSearchParams() is already globally available via react-router, so a plain
  hook is enough - no extra Provider needed in App.jsx.

  Schema entry fields:
    key      - property name under which the parsed value is returned
    source   - "env" (import.meta.env) or "param" (URL search param)
    name     - the actual env var name (e.g. "VITE_...") or param name to read
    type     - "boolean" | "number" | "string", see parseConfigValue for parsing rules
    default  - fallback value if unset or invalid
    min/max  - optional bounds, "number" type only
    description - human-readable explanation, for docs/debug UIs (not read by useConfig itself)
*/

import { useMemo } from "react";
import { useSearchParams } from "react-router";
import { CONFIG_SCHEMA } from "./config-schema";
import { parseConfigValue } from "../../utils/validationFunctions";

/**
 * React hook that resolves every entry in CONFIG_SCHEMA (config-schema.js)
 * against the current URL search params / import.meta.env and returns them
 * as a flat, typed `{ key: value }` object.
 *
 * @returns {Object} Config values keyed by their CONFIG_SCHEMA `key`.
 */
export const useConfig = () => {
  const [searchParams] = useSearchParams();

  return useMemo(
    () =>
      CONFIG_SCHEMA.reduce((config, def) => {
        const rawValue =
          def.source === "param" ? searchParams.get(def.name) : import.meta.env[def.name];
        config[def.key] = parseConfigValue(rawValue, def);
        return config;
      }, {}),
    [searchParams]
  );
};