<script setup>
import { useAuth } from '@websanova/vue-auth/src/v3.js';
import axios from 'axios';
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { msalInstance } from './MsalConfig';

const router = useRouter();
const auth = useAuth();
const message = ref('');
const visible = ref(false);

onMounted(async () => {
    console.log('[Callback] Mounted on callback');

    try {
        await msalInstance.initialize();
        console.log('[Callback] After initialize on callback');
    } catch (e) {
        console.error('[Callback] Error during MSAL initialization:', e);
        message.value = 'Error during MSAL initialization.';
        visible.value = true;
        return;
    }

    let response;
    try {
        response = await msalInstance.handleRedirectPromise();
        console.log('[Callback] handleRedirectPromise response:', response);
    } catch (e) {
        console.error('[Callback] Error in handleRedirectPromise:', e);
        message.value = 'Error handling the redirect.';
        visible.value = true;
        return;
    }

    if (response && response.accessToken) {
        console.log('[Callback] Access token present:', response.accessToken);

        if (!response.account) {
            console.warn('[Callback] No account present in the response. Possible MSAL anomaly.');
        } else {
            console.log('[Callback] Account info:', response.account);
            localStorage.setItem('msalUser', JSON.stringify(response.account));
        }

        // Wait 2 second to avoid race condition
        await new Promise((resolve) => setTimeout(resolve, 2000));
        message.value = 'Logging in to the application...';

        // Token exchange function with retry
        const tryTokenExchange = async (retry = false) => {
            try {
                console.log(`[Callback] Call to /msauth/exchange (retry=${retry})...`);
                const res = await axios.post(
                    '/msauth/exchange',
                    {},
                    {
                        headers: { Authorization: `Bearer ${response.accessToken}` }
                    }
                );
                return res;
            } catch (err) {
                if (!retry) {
                    console.warn('[Callback] First attempt failed, waiting 1500ms and retrying...');
                    await new Promise((resolve) => setTimeout(resolve, 1500));
                    return tryTokenExchange(true);
                } else {
                    throw err;
                }
            }
        };

        let exchangeResponse;
        try {
            exchangeResponse = await tryTokenExchange();
            console.log('[Callback] Response from /msauth/exchange:', exchangeResponse);

            if (exchangeResponse.data.token) {
                console.log('[Callback] Backend token received:', exchangeResponse.data.token);
                auth.token(null, exchangeResponse.data.token, false);

                try {
                    console.log('[Callback] Calling auth.fetch()...');
                    const userResponse = await auth.fetch();
                    console.log('[Callback] User fetch response:', userResponse);

                    // Start token refresh timer after successful authentication
                    window.dispatchEvent(new CustomEvent('auth-login-success'));

                    const userData = userResponse.data?.data;
                    console.log('[Callback] userResponse.data.data:', userData);

                    if (!userData || !userData.selectedProject) {
                        console.log('[Callback] No project selected, redirecting to projects-list');
                        router.push({ name: 'projects-list' });
                    } else {
                        console.log('[Callback] Project selected, redirecting to scenario-list');
                        router.push({ name: 'scenario-list' });
                    }
                } catch (fetchErr) {
                    console.error('[Callback] Error fetching user after token exchange:', fetchErr);
                    message.value = 'User not configured for this application. Contact the administrator for details.';
                    visible.value = true;
                }
            } else {
                console.error('[Callback] No token received from backend:', exchangeResponse.data);
                message.value = 'User not configured for this application. Contact the administrator for details.';
                visible.value = true;
            }
        } catch (error) {
            console.error('[Callback] Error on token exchange (after retry):', error.response ? error.response.data : error);
            message.value = 'An error occurred during the token exchange. Please try again.';
            visible.value = true;
        }
    } else {
        console.error('[Callback] Invalid response or missing access token:', response);
        message.value = 'Authentication failed. Please log in again.';
        visible.value = true;
    }
});
</script>

<template>
    <div>{{ message }}</div>
</template>
