const isRequest = (input) => (
    input !== null
    && typeof input === "object"
    && typeof input.url === "string"
    && (
        (typeof Request !== "undefined" && input instanceof Request)
        || Object.prototype.toString.call(input) === "[object Request]"
    )
);

export const isSameOriginRequest = (input, currentHref) => {
    const currentUrl = new URL(currentHref);
    const requestUrl = new URL(isRequest(input) ? input.url : input, currentUrl);

    return requestUrl.origin === currentUrl.origin;
};

export const withWindowIdFetchInit = (
    input,
    init,
    windowId,
    currentHref,
) => {
    if (!windowId || !isSameOriginRequest(input, currentHref)) {
        return init;
    }

    const effectiveInit = init ?? {};
    const headers = new Headers(
        effectiveInit.headers ?? (isRequest(input) ? input.headers : undefined),
    );

    headers.set("X-Window-Id", windowId);

    return {
        ...effectiveInit,
        headers,
    };
};

export const addWindowIdToTurboHeaders = (
    url,
    headers,
    windowId,
    currentHref,
) => {
    if (!windowId || !url || !isSameOriginRequest(url, currentHref)) {
        return headers;
    }

    const modifiedHeaders = headers ?? {};

    if (typeof modifiedHeaders.set === "function") {
        modifiedHeaders.set("X-Window-Id", windowId);
    } else {
        modifiedHeaders["X-Window-Id"] = windowId;
    }

    return modifiedHeaders;
};
