import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
/*
 * Copyright (c) 2023-2025 Datalayer, Inc.
 * Distributed under the terms of the Modified BSD License.
 */
import { useEffect, useState } from 'react';
import { PageConfig, URLExt } from '@jupyterlab/coreutils';
import { EyeIcon, EyeClosedIcon, MarkGithubIcon } from '@primer/octicons-react';
import { Button, FormControl, Heading, Link, PageLayout, TextInput, } from '@primer/react';
import { Box } from '@datalayer/primer-addons';
import { asUser, IAMProvidersSpecs } from '../../models/index.js';
import { useIAMStore } from '../../state/index.js';
import { CenteredSpinner } from '../display/index.js';
import { isInsideJupyterLab, validateLength } from '../../utils/index.js';
import { useNavigate, useCache, useToast, useIAM } from '../../hooks/index.js';
import { LoginToken } from './LoginToken.js';
/** Inline Google "G" icon for the login button. */
const GoogleIcon = () => (_jsxs("svg", { width: "16", height: "16", viewBox: "0 0 48 48", children: [_jsx("path", { fill: "#EA4335", d: "M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z" }), _jsx("path", { fill: "#4285F4", d: "M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z" }), _jsx("path", { fill: "#FBBC05", d: "M10.53 28.59a14.5 14.5 0 0 1 0-9.18l-7.98-6.19a24.1 24.1 0 0 0 0 21.56l7.98-6.19z" }), _jsx("path", { fill: "#34A853", d: "M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z" })] }));
export const Login = (props) => {
    const { heading, homeRoute, loginRoute, showEmailLogin = true, showGitHubLogin = true, showGoogleLogin = true, showTokenLogin = true, } = props;
    const { useLogin, useOAuth2AuthorizationURL } = useCache({ loginRoute });
    const loginMutation = useLogin();
    const getOAuth2URLMutation = useOAuth2AuthorizationURL();
    const { loginAndNavigate, setLogin } = useIAM();
    const { externalToken, iamProvidersAuthorizationURL, addIAMProviderAuthorizationURL, iamRunUrl, logout, checkIAMToken, } = useIAMStore();
    const { enqueueToast } = useToast();
    const navigate = useNavigate();
    const [loading, setLoading] = useState(false);
    const [loadingWithToken, setLoadingWithToken] = useState(-1);
    const [formValues, setFormValues] = useState({
        handle: undefined,
        password: undefined,
    });
    const [validationResult, setValidationResult] = useState({
        handle: undefined,
        password: undefined,
    });
    const [passwordVisibility, setPasswordVisibility] = useState(false);
    useEffect(() => {
        const initIAMProvider = (iamProvider) => {
            const callbackURI = isInsideJupyterLab()
                ? URLExt.join(PageConfig.getBaseUrl(), iamProvider.oauth2CallbackServerRoute)
                : location.protocol +
                    '//' +
                    location.hostname +
                    ':' +
                    location.port +
                    iamProvider.oauth2CallbackUIRoute;
            const queryArgs = {
                provider: iamProvider.name,
                callback_uri: callbackURI,
            };
            /*
            const xsrfTokenMatch = document.cookie.match('\\b_xsrf=([^;]*)\\b');
            if (xsrfTokenMatch) {
              queryArgs['xsrf'] = xsrfTokenMatch[1];
            }
            */
            getOAuth2URLMutation.mutate(queryArgs, {
                onSuccess: authUrl => {
                    if (authUrl) {
                        addIAMProviderAuthorizationURL(iamProvider.name, authUrl);
                    }
                    else {
                        console.error(`Failed to get the Login URL from Datalayer IAM for provider ${iamProvider.name}.`);
                    }
                },
            });
        };
        if (!iamProvidersAuthorizationURL[IAMProvidersSpecs.GitHub.name]) {
            initIAMProvider(IAMProvidersSpecs.GitHub);
        }
        if (!iamProvidersAuthorizationURL[IAMProvidersSpecs.Google.name]) {
            initIAMProvider(IAMProvidersSpecs.Google);
        }
        if (!iamProvidersAuthorizationURL[IAMProvidersSpecs.LinkedIn.name]) {
            initIAMProvider(IAMProvidersSpecs.LinkedIn);
        }
    }, [iamRunUrl, iamProvidersAuthorizationURL, addIAMProviderAuthorizationURL]);
    useEffect(() => {
        if (externalToken) {
            setLoadingWithToken(1);
            loginAndNavigate(externalToken, logout, checkIAMToken, navigate, homeRoute)
                .catch(error => {
                console.debug('Failed to login with token from cookie..', error);
                enqueueToast('Failed to check authentication.', { variant: 'error' });
            })
                .finally(() => {
                setLoadingWithToken(-1);
            });
        }
    }, [externalToken]);
    const handleKeyDown = (event) => {
        if (event.key === 'Enter') {
            submit();
        }
    };
    const handleHandleChange = (event) => {
        setFormValues(prevFormValues => ({
            ...prevFormValues,
            handle: event.target.value,
        }));
    };
    const handlePasswordChange = (event) => {
        setFormValues(prevFormValues => ({
            ...prevFormValues,
            password: event.target.value,
        }));
    };
    const submit = async () => {
        if (loading ||
            validationResult.handle !== '' ||
            validationResult.password !== '') {
            return;
        }
        setLoading(true);
        loginMutation.mutate({
            handle: formValues.handle,
            password: formValues.password,
        }, {
            onSuccess: (resp) => {
                if (resp.success) {
                    setValidationResult({ handle: '', password: '' });
                    const user = asUser(resp.user);
                    const token = resp.token;
                    setLogin(user, token);
                    navigate(homeRoute);
                }
                else {
                    enqueueToast('Failed to login. Check your username and password.', {
                        variant: 'warning',
                    });
                    setValidationResult({
                        handle: '',
                        password: 'Invalid credentials',
                    });
                    console.debug(`Failed to login: ${resp.message}`, resp.errors ?? '');
                }
            },
            onSettled: () => {
                setLoading(false);
            },
        });
    };
    useEffect(() => {
        setValidationResult({
            ...validationResult,
            handle: formValues.handle === undefined
                ? undefined
                : validateLength(formValues.handle, 1)
                    ? ''
                    : 'Your username may not be empty.',
            password: formValues.password === undefined
                ? undefined
                : validateLength(formValues.password, 1)
                    ? ''
                    : 'Your password may not be empty.',
        });
    }, [formValues]);
    return (_jsxs(PageLayout, { containerWidth: "medium", padding: "normal", style: { overflow: 'visible', minHeight: 'calc(100vh - 45px)' }, children: [_jsx(PageLayout.Header, { children: _jsx(Heading, { children: heading || 'Login to Datalayer' }) }), _jsx(PageLayout.Content, { children: loadingWithToken < 0 ? (_jsx(_Fragment, { children: _jsxs(Box, { display: "flex", children: [showEmailLogin && (_jsxs(Box, { sx: { label: { marginTop: 2 }, paddingRight: '10%' }, children: [_jsx(Box, { mt: 5, children: _jsxs(FormControl, { required: true, children: [_jsx(FormControl.Label, { children: "Your username" }), _jsx(TextInput, { autoFocus: true, placeholder: "Your username", value: formValues.handle, onChange: handleHandleChange, onKeyDown: handleKeyDown }), validationResult.handle && (_jsx(FormControl.Validation, { variant: validationResult.handle ? 'error' : 'success', children: validationResult.handle }))] }) }), _jsx(Box, { children: _jsxs(FormControl, { required: true, children: [_jsx(FormControl.Label, { children: "Your password" }), _jsx(TextInput, { placeholder: "Your password", type: passwordVisibility ? 'text' : 'password', value: formValues.password, onChange: handlePasswordChange, onKeyDown: handleKeyDown, trailingAction: _jsx(TextInput.Action, { onClick: () => {
                                                            setPasswordVisibility(!passwordVisibility);
                                                        }, icon: passwordVisibility ? EyeClosedIcon : EyeIcon, "aria-label": passwordVisibility
                                                            ? 'Hide password'
                                                            : 'Show password', sx: { color: 'var(--fgColor-muted)' } }), sx: { overflow: 'visible' } }), validationResult.password && (_jsx(FormControl.Validation, { variant: validationResult.password ? 'error' : 'success', children: validationResult.password }))] }) }), _jsxs(Box, { mt: 5, children: [_jsx(Button, { variant: "primary", disabled: loading ||
                                                    validationResult.handle !== '' ||
                                                    validationResult.password !== '', onClick: submit, children: loading
                                                    ? 'Login…'
                                                    : heading
                                                        ? 'Login with Datalayer'
                                                        : 'Login' }), _jsx(Box, { pt: 6 }), _jsx(Link, { href: "https://datalayer.ai/password", target: "_blank", children: "Forgot password?" })] })] })), _jsx(Box, { children: _jsxs(Box, { display: "flex", flexDirection: "column", sx: { margin: 'auto' }, children: [showGitHubLogin &&
                                            iamProvidersAuthorizationURL[IAMProvidersSpecs.GitHub.name] && (_jsx(Button, { leadingVisual: MarkGithubIcon, href: iamProvidersAuthorizationURL[IAMProvidersSpecs.GitHub.name], as: "a", style: { margin: '10px 0' }, children: "Login with GitHub" })), showGoogleLogin &&
                                            iamProvidersAuthorizationURL[IAMProvidersSpecs.Google.name] && (_jsx(Button, { leadingVisual: GoogleIcon, href: iamProvidersAuthorizationURL[IAMProvidersSpecs.Google.name], as: "a", style: { margin: '10px 0' }, children: "Login with Google" })), showTokenLogin && (_jsx(LoginToken, { homeRoute: homeRoute, style: { margin: '10px 0' } }))] }) })] }) })) : loadingWithToken ? (_jsx(CenteredSpinner, { message: "Checking authentication\u2026" })) : (_jsx(_Fragment, {})) })] }));
};
export default Login;
