import { Auth, raw, skipCSRFCheck, createActionURL } from "@auth/core";
// @ts-expect-error Next.js does not yet correctly use the `package.json#exports` field
import { headers as nextHeaders, cookies } from "next/headers";
// @ts-expect-error Next.js does not yet correctly use the `package.json#exports` field
import { redirect } from "next/navigation";
export async function signIn(provider, options = {}, authorizationParams, config) {
    const headers = new Headers(await nextHeaders());
    const { redirect: shouldRedirect = true, redirectTo, ...rest } = options instanceof FormData ? Object.fromEntries(options) : options;
    const callbackUrl = redirectTo?.toString() ?? headers.get("Referer") ?? "/";
    const signInURL = createActionURL("signin", 
    // @ts-expect-error `x-forwarded-proto` is not nullable, next.js sets it by default
    headers.get("x-forwarded-proto"), headers, process.env, config);
    if (!provider) {
        signInURL.searchParams.append("callbackUrl", callbackUrl);
        if (shouldRedirect)
            redirect(signInURL.toString());
        return signInURL.toString();
    }
    let url = `${signInURL}/${provider}?${new URLSearchParams(authorizationParams)}`;
    let foundProvider = {};
    for (const providerConfig of config.providers) {
        const { options, ...defaults } = typeof providerConfig === "function" ? providerConfig() : providerConfig;
        const id = options?.id ?? defaults.id;
        if (id === provider) {
            foundProvider = {
                id,
                type: options?.type ?? defaults.type,
            };
            break;
        }
    }
    if (!foundProvider.id) {
        const url = `${signInURL}?${new URLSearchParams({ callbackUrl })}`;
        if (shouldRedirect)
            redirect(url);
        return url;
    }
    if (foundProvider.type === "credentials") {
        url = url.replace("signin", "callback");
    }
    headers.set("Content-Type", "application/x-www-form-urlencoded");
    const body = new URLSearchParams({ ...rest, callbackUrl });
    const req = new Request(url, { method: "POST", headers, body });
    const res = await Auth(req, { ...config, raw, skipCSRFCheck });
    const cookieJar = await cookies();
    for (const c of res?.cookies ?? [])
        cookieJar.set(c.name, c.value, c.options);
    const responseUrl = res instanceof Response ? res.headers.get("Location") : res.redirect;
    // NOTE: if for some unexpected reason the responseUrl is not set,
    // we redirect to the original url
    const redirectUrl = responseUrl ?? url;
    if (shouldRedirect)
        return redirect(redirectUrl);
    return redirectUrl;
}
export async function signOut(options, config) {
    const headers = new Headers(await nextHeaders());
    headers.set("Content-Type", "application/x-www-form-urlencoded");
    const url = createActionURL("signout", 
    // @ts-expect-error `x-forwarded-proto` is not nullable, next.js sets it by default
    headers.get("x-forwarded-proto"), headers, process.env, config);
    const callbackUrl = options?.redirectTo ?? headers.get("Referer") ?? "/";
    const body = new URLSearchParams({ callbackUrl });
    const req = new Request(url, { method: "POST", headers, body });
    const res = await Auth(req, { ...config, raw, skipCSRFCheck });
    const cookieJar = await cookies();
    for (const c of res?.cookies ?? [])
        cookieJar.set(c.name, c.value, c.options);
    if (options?.redirect ?? true)
        return redirect(res.redirect);
    return res;
}
export async function update(data, config) {
    const headers = new Headers(await nextHeaders());
    headers.set("Content-Type", "application/json");
    const url = createActionURL("session", 
    // @ts-expect-error `x-forwarded-proto` is not nullable, next.js sets it by default
    headers.get("x-forwarded-proto"), headers, process.env, config);
    const body = JSON.stringify({ data });
    const req = new Request(url, { method: "POST", headers, body });
    const res = await Auth(req, { ...config, raw, skipCSRFCheck });
    const cookieJar = await cookies();
    for (const c of res?.cookies ?? [])
        cookieJar.set(c.name, c.value, c.options);
    return res.body;
}
