import { msalInstance, msalrequest } from '@/views/pages/auth/MsalConfig';
import axios from 'axios';

export class AuthService {
    /**
     * Attempts to refresh tokens based on the authentication type
     * @param {Object} authInstance - The vue-auth instance
     * @returns {Promise<{success: boolean, token?: string, error?: string}>}
     */
    static async refreshToken(authInstance = null) {
        try {
            console.log('[AuthService] Starting token refresh process...');

            // Check if we have MSAL accounts first
            await msalInstance.initialize();
            const accounts = msalInstance.getAllAccounts();

            if (accounts.length > 0) {
                // User logged in with MSAL - use MSAL refresh
                console.log('[AuthService] Using MSAL token refresh...');
                return await this.refreshMsalToken();
            } else if (authInstance && authInstance.check()) {
                // User logged in with classic authentication - use vue-auth refresh
                console.log('[AuthService] Using classic authentication token refresh...');
                return await this.refreshClassicToken(authInstance);
            } else {
                console.warn('[AuthService] No valid authentication method found');
                return { success: false, error: 'No valid authentication method found' };
            }
        } catch (error) {
            console.error('[AuthService] Token refresh failed:', error);
            return { success: false, error: error.message };
        }
    }

    /**
     * Refreshes token using classic username/password authentication
     * @param {Object} authInstance - The vue-auth instance
     * @returns {Promise<{success: boolean, token?: string, error?: string}>}
     */
    static async refreshClassicToken(authInstance) {
        try {
            console.log('[AuthService] Attempting classic token refresh...');

            const refreshResponse = await authInstance.refresh();
            console.log('[AuthService] Classic refresh response:', refreshResponse);

            // Check multiple possible response structures
            let token = null;

            if (refreshResponse && refreshResponse.data) {
                // Try different token field names
                token = refreshResponse.data.token || refreshResponse.data.accessToken || refreshResponse.data.access_token;

                // If still no token, check if the token is directly in data
                if (!token && typeof refreshResponse.data === 'string') {
                    token = refreshResponse.data;
                }
            }

            // Also check if token is in headers (as backend sets it there)
            if (!token && refreshResponse && refreshResponse.headers) {
                token = refreshResponse.headers.authorization || refreshResponse.headers.Authorization;
            }

            if (token) {
                console.log('[AuthService] Classic token refresh successful');
                return {
                    success: true,
                    token: token,
                    response: refreshResponse
                };
            } else {
                console.error('[AuthService] No token found in classic refresh response:', refreshResponse);
                return { success: false, error: 'No token in refresh response' };
            }
        } catch (error) {
            console.error('[AuthService] Classic token refresh failed:', error);
            return { success: false, error: 'Classic token refresh failed' };
        }
    }

    /**
     * Attempts to refresh the MSAL token and exchange it for a new backend token
     * @returns {Promise<{success: boolean, token?: string, error?: string}>}
     */
    static async refreshMsalToken() {
        try {
            console.log('[AuthService] Starting MSAL token refresh process...');

            // Get all accounts from MSAL
            await msalInstance.initialize();
            const accounts = msalInstance.getAllAccounts();

            if (accounts.length === 0) {
                console.warn('[AuthService] No MSAL accounts found for MSAL refresh');
                return { success: false, error: 'No MSAL accounts found' };
            }

            const account = accounts[0];
            console.log('[AuthService] Using account:', account.username);

            // Try to acquire token silently
            let tokenResponse;
            try {
                tokenResponse = await msalInstance.acquireTokenSilent({
                    scopes: msalrequest.scopes,
                    account: account
                });
                console.log('[AuthService] MSAL token acquired silently');
            } catch (silentError) {
                console.warn('[AuthService] Silent token acquisition failed, trying interactive...');

                // If silent fails, try interactive
                try {
                    tokenResponse = await msalInstance.acquireTokenPopup({
                        scopes: msalrequest.scopes,
                        account: account
                    });
                    console.log('[AuthService] MSAL token acquired interactively');
                } catch (interactiveError) {
                    console.error('[AuthService] Interactive token acquisition failed:', interactiveError);
                    return { success: false, error: 'Token acquisition failed' };
                }
            }

            if (!tokenResponse || !tokenResponse.accessToken) {
                console.error('[AuthService] No access token received');
                return { success: false, error: 'No access token received' };
            }

            // Exchange the MSAL token for a backend token
            try {
                const exchangeResponse = await axios.post(
                    '/msauth/exchange',
                    {},
                    {
                        headers: { Authorization: `Bearer ${tokenResponse.accessToken}` }
                    }
                );

                if (exchangeResponse.data && exchangeResponse.data.token) {
                    console.log('[AuthService] MSAL token refresh successful');
                    return {
                        success: true,
                        token: exchangeResponse.data.token,
                        response: exchangeResponse
                    };
                } else {
                    console.error('[AuthService] No token in MSAL exchange response');
                    return { success: false, error: 'No token in exchange response' };
                }
            } catch (exchangeError) {
                console.error('[AuthService] MSAL token exchange failed:', exchangeError);
                return { success: false, error: 'Token exchange failed' };
            }
        } catch (error) {
            console.error('[AuthService] MSAL token refresh failed:', error);
            return { success: false, error: error.message };
        }
    }

    /**
     * Checks if the current MSAL session is still valid
     * @returns {Promise<boolean>}
     */
    static async isSessionValid() {
        try {
            await msalInstance.initialize();
            const accounts = msalInstance.getAllAccounts();

            if (accounts.length === 0) {
                return false;
            }

            // Try to acquire token silently to check if session is valid
            try {
                await msalInstance.acquireTokenSilent({
                    scopes: msalrequest.scopes,
                    account: accounts[0]
                });
                return true;
            } catch (error) {
                console.warn('[AuthService] Session validation failed:', error);
                return false;
            }
        } catch (error) {
            console.error('[AuthService] Session validation error:', error);
            return false;
        }
    }

    /**
     * Logs out from MSAL
     * @returns {Promise<void>}
     */
    static async logout() {
        try {
            await msalInstance.initialize();
            const accounts = msalInstance.getAllAccounts();

            if (accounts.length > 0) {
                const logoutRequest = {
                    account: accounts[0],
                    mainWindowRedirectUri: window.location.origin + '/auth/login'
                };

                await msalInstance.logoutPopup(logoutRequest);
                console.log('[AuthService] MSAL logout completed');
            }
        } catch (error) {
            console.error('[AuthService] Logout error:', error);
        }
    }
}
