import { ERRORS, normalizeError } from "../../../../libs/errors.js";
import { isElectron } from "../../../../libs/electron.js";
import { buildRequestSecurity } from "./build-request-security.js";
import { getEnvironmentVariables } from "./get-environment-variables.js";
import { getResolvedUrl } from "./get-resolved-url.js";
import { getDefaultHeaders } from "../../request-block/helpers/get-default-headers.js";
import { buildRequestBody } from "./build-request-body.js";
import { buildRequestCookieHeader } from "./build-request-cookie-header.js";
import { buildRequestParameters } from "./build-request-parameters.js";
import { redirectToProxy, shouldUseProxy } from "@scalar/helpers/url/redirect-to-proxy";
import { getResolvedRef } from "@scalar/workspace-store/helpers/get-resolved-ref";
import { canMethodHaveBody } from "@scalar/helpers/http/can-method-have-body";
//#region src/v2/blocks/operation-block/helpers/build-request.ts
/**
* Builds a fully configured Request object ready for execution.
*
* This function processes an OpenAPI operation and constructs a fetch-compatible
* Request by resolving environment variables, applying security schemes, building
* headers and cookies, handling proxy redirection, and preparing the request body.
*
* The function handles special cases like Electron environments and proxy usage
* where custom cookie headers are required.
*
* @returns A tuple containing either an error or the request object with an abort controller
*/
var buildRequest = ({ environment, exampleKey = "default", globalCookies, method, operation, path, proxyUrl, requestBodyCompositionSelection, server, selectedSecuritySchemes }) => {
	try {
		const requestBody = getResolvedRef(operation.requestBody);
		/** Flatten the environment variables array into a key-value object */
		const env = getEnvironmentVariables(environment);
		/** Build out the request parameters */
		const params = buildRequestParameters(operation.parameters ?? [], env, exampleKey);
		const security = buildRequestSecurity(selectedSecuritySchemes, env);
		const defaultHeaders = getDefaultHeaders({
			method,
			operation,
			exampleKey,
			hideDisabledHeaders: true
		}).filter((header) => !header.isOverridden).reduce((acc, header) => {
			acc[header.name] = header.defaultValue;
			return acc;
		}, {});
		const headers = new Headers({
			...defaultHeaders,
			...params.headers,
			...security.headers
		});
		const urlParams = new URLSearchParams([...params.urlParams, ...security.urlParams]);
		const body = canMethodHaveBody(method) ? buildRequestBody(requestBody, env, exampleKey, requestBodyCompositionSelection) : null;
		if (body && (body instanceof FormData || body instanceof URLSearchParams)) headers.delete("Content-Type");
		/** Combine the server url, path and url params into a single url */
		const url = getResolvedUrl({
			environment,
			server,
			path,
			pathVariables: params.pathVariables,
			allowReservedQueryParameters: params.allowReservedQueryParameters,
			urlParams
		});
		if (!url) throw ERRORS.URL_EMPTY;
		const isUsingProxy = shouldUseProxy(proxyUrl, url);
		const proxiedUrl = redirectToProxy(proxyUrl, url);
		const userAgentHeader = headers.get("User-Agent");
		if (isElectron() && userAgentHeader) headers.set("X-Scalar-User-Agent", userAgentHeader);
		/** Build out the cookies header */
		const cookiesHeader = buildRequestCookieHeader({
			paramCookies: [...params.cookies, ...security.cookies],
			globalCookies,
			env,
			originalCookieHeader: headers.get("Cookie"),
			url,
			useCustomCookieHeader: isElectron() || isUsingProxy,
			disabledGlobalCookies: operation["x-scalar-disable-parameters"]?.["global-cookies"]?.[exampleKey] ?? {}
		});
		if (cookiesHeader) headers.set(cookiesHeader.name, cookiesHeader.value);
		/** Controller to allow aborting the request */
		const controller = new AbortController();
		const isSseAcceptHeader = headers.get("Accept")?.toLowerCase().includes("text/event-stream") ?? false;
		const requestCacheMode = isSseAcceptHeader ? "no-store" : "default";
		if (isSseAcceptHeader) {
			headers.set("Cache-Control", "no-cache");
			headers.set("Pragma", "no-cache");
		}
		return [null, {
			controller,
			isUsingProxy,
			request: new Request(proxiedUrl, {
				method: method.toUpperCase(),
				headers,
				signal: controller.signal,
				body,
				cache: requestCacheMode
			})
		}];
	} catch (error) {
		return [normalizeError(error, ERRORS.BUILDING_REQUEST_FAILED), null];
	}
};
//#endregion
export { buildRequest };

//# sourceMappingURL=build-request.js.map