const LEGACY_AUTH_KEYS = ['token', 'role', 'departmentId', 'userId'];

let accessToken = null;
let authState = null;
let refreshPromise = null;

purgeLegacyAuthStorage();

export function getAccessToken() {
    return accessToken;
}

export function getAuthState() {
    return authState ? { ...authState } : null;
}

export function storeAuthState(data) {
    if (!data?.token || !data?.role) {
        clearAuthState();
        return null;
    }

    accessToken = data.token;
    authState = {
        role: data.role,
        departmentId: normalizeOptionalId(data.departmentId),
        userId: normalizeOptionalId(data.userId),
        redirect: typeof data.redirect === 'string' ? data.redirect : '/'
    };
    return getAuthState();
}

export function clearAuthState() {
    accessToken = null;
    authState = null;
}

export async function restoreSession() {
    if (accessToken && authState) {
        return getAuthState();
    }

    const refreshed = await refreshAccessToken();
    return refreshed ? getAuthState() : null;
}

export async function refreshAccessToken() {
    if (refreshPromise) {
        return refreshPromise;
    }

    refreshPromise = (async () => {
        let response;
        try {
            response = await fetch('/api/auth/refresh', {
                method: 'POST',
                credentials: 'same-origin'
            });
        } catch (error) {
            clearAuthState();
            return false;
        }

        const data = await response.json().catch(() => null);
        if (!response.ok || !storeAuthState(data)) {
            clearAuthState();
            return false;
        }
        return true;
    })().finally(() => {
        refreshPromise = null;
    });

    return refreshPromise;
}

export async function fetchWithAuth(endpoint, options = {}, retryOnUnauthorized = true) {
    const headers = new Headers(options.headers || {});
    if (accessToken) {
        headers.set('Authorization', `Bearer ${accessToken}`);
    }

    const response = await fetch(endpoint, {
        ...options,
        headers,
        credentials: 'same-origin'
    });

    if (response.status === 401 && retryOnUnauthorized && await refreshAccessToken()) {
        return fetchWithAuth(endpoint, options, false);
    }
    return response;
}

export async function logoutSession() {
    try {
        await fetch('/api/auth/logout', {
            method: 'POST',
            credentials: 'same-origin'
        });
    } catch (error) {
        console.warn('Не удалось завершить серверную сессию');
    } finally {
        clearAuthState();
    }
}

function purgeLegacyAuthStorage() {
    try {
        LEGACY_AUTH_KEYS.forEach(key => localStorage.removeItem(key));
        LEGACY_AUTH_KEYS.forEach(key => sessionStorage.removeItem(key));
    } catch (error) {
        console.warn('Не удалось очистить устаревшие данные авторизации в браузере');
    }
}

function normalizeOptionalId(value) {
    return value === undefined || value === null || value === '' ? null : String(value);
}
