var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { jsx as _jsx } from "react/jsx-runtime";
import { jwtDecode } from 'jwt-decode';
import { useEffect } from 'react';
import { useLocation, useNavigate } from 'react-router';
import { HTTP_METHOD } from '@darajs/ui-utils';
import { request } from '../../api/http';
import DefaultFallback from '../../components/fallback/default';
import { useRouterContext } from '../../router/context';
import Center from '../../shared/center/center';
import { handleAuthErrors } from '../auth';
import { setSessionToken } from '../use-session-token';
/**
 * Decode the state parameter which is a JWT containing the redirect URL.
 *
 * @param state The state parameter from the callback URL
 * @returns The redirect URL extracted from the state
 */
function decodeStateRedirect(state) {
    var _a;
    if (!state) {
        return null;
    }
    try {
        const payload = jwtDecode(state);
        return (_a = payload.redirect_to) !== null && _a !== void 0 ? _a : null;
    }
    catch (_b) {
        // If decoding fails, try using the raw state as a URL (fallback for non-JWT states)
        try {
            return decodeURIComponent(state);
        }
        catch (_c) {
            return null;
        }
    }
}
/**
 * Makes a call to /sso-callback and returns a new token
 * Returns null if no token was returned (i.e. 403)
 *
 * @param search current search string
 */
export function getSSOCallbackToken(search, defaultPath) {
    return __awaiter(this, void 0, void 0, function* () {
        var _a;
        try {
            const params = new URLSearchParams(search);
            const state = params.get('state');
            const res = yield request('/api/auth/sso-callback', {
                body: JSON.stringify({
                    auth_code: params.get('code'),
                    state,
                }),
                method: HTTP_METHOD.POST,
            });
            const shouldLogOut = yield handleAuthErrors(res);
            if (shouldLogOut) {
                return null;
            }
            if (res.ok) {
                const { token } = yield res.json();
                return {
                    token,
                    redirectTo: (_a = decodeStateRedirect(state)) !== null && _a !== void 0 ? _a : defaultPath,
                };
            }
            throw new Error(`${res.status}: ${res.statusText}`);
        }
        catch (_b) {
            return null;
        }
    });
}
function OIDCAuthSSOCallback() {
    const { search } = useLocation();
    const navigate = useNavigate();
    const routerContext = useRouterContext();
    useEffect(() => {
        getSSOCallbackToken(search, routerContext.defaultPath)
            .then((result) => {
            if (result) {
                setSessionToken(result.token);
                navigate(result.redirectTo);
            }
        })
            .catch((err) => {
            // eslint-disable-next-line no-console
            console.error('Failed to run SSO callback', err);
            navigate('/logout');
        });
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);
    return (_jsx(Center, { children: _jsx(DefaultFallback, {}) }));
}
export default OIDCAuthSSOCallback;
//# sourceMappingURL=sso-callback.js.map