const TOKEN_KEY = 'token';
const USER_DATA_KEY = 'userData';
const IS_TFA_KEY = 'isTfa';

/** Matches backend jwt.token-validity-time (PT30M). */
const SESSION_MAX_AGE_SECONDS = 30 * 60;

function getCookie(name) {
    const prefix = `${encodeURIComponent(name)}=`;
    const parts = document.cookie ? document.cookie.split('; ') : [];

    for (const part of parts) {
        if (part.startsWith(prefix)) {
            return decodeURIComponent(part.slice(prefix.length));
        }
    }

    return null;
}

function setCookie(name, value, maxAgeSeconds = SESSION_MAX_AGE_SECONDS) {
    const secure = window.location.protocol === 'https:' ? '; Secure' : '';
    document.cookie = [
        `${encodeURIComponent(name)}=${encodeURIComponent(value)}`,
        `Path=/`,
        `Max-Age=${maxAgeSeconds}`,
        `SameSite=Lax`,
        secure,
    ].join('; ');
}

function removeCookie(name) {
    document.cookie = `${encodeURIComponent(name)}=; Path=/; Max-Age=0; SameSite=Lax`;
}

function migrateFromLocalStorage(key) {
    const legacy = localStorage.getItem(key);
    if (legacy == null) {
        return null;
    }

    setCookie(key, legacy);
    localStorage.removeItem(key);
    return legacy;
}

export function getToken() {
    return getCookie(TOKEN_KEY) ?? migrateFromLocalStorage(TOKEN_KEY);
}

export function setToken(token) {
    if (token == null || token === '') {
        removeCookie(TOKEN_KEY);
        localStorage.removeItem(TOKEN_KEY);
        return;
    }

    setCookie(TOKEN_KEY, token);
    localStorage.removeItem(TOKEN_KEY);
}

export function getUserData() {
    const raw = getCookie(USER_DATA_KEY) ?? migrateFromLocalStorage(USER_DATA_KEY);
    if (!raw) {
        return null;
    }

    try {
        return JSON.parse(raw);
    } catch {
        removeCookie(USER_DATA_KEY);
        return null;
    }
}

export function setUserData(userData) {
    if (userData == null) {
        removeCookie(USER_DATA_KEY);
        localStorage.removeItem(USER_DATA_KEY);
        return;
    }

    setCookie(USER_DATA_KEY, JSON.stringify(userData));
    localStorage.removeItem(USER_DATA_KEY);
}

export function getIsTfa() {
    const raw = getCookie(IS_TFA_KEY) ?? migrateFromLocalStorage(IS_TFA_KEY);
    if (raw == null) {
        return false;
    }

    try {
        return JSON.parse(raw);
    } catch {
        return raw === 'true';
    }
}

export function setIsTfa(isTfa) {
    setCookie(IS_TFA_KEY, JSON.stringify(Boolean(isTfa)));
    localStorage.removeItem(IS_TFA_KEY);
}

export function setSession({ token, userData, isTfa } = {}) {
    if (token !== undefined) {
        setToken(token);
    }
    if (userData !== undefined) {
        setUserData(userData);
    }
    if (isTfa !== undefined) {
        setIsTfa(isTfa);
    }
}

export function clearSession() {
    removeCookie(TOKEN_KEY);
    removeCookie(USER_DATA_KEY);
    removeCookie(IS_TFA_KEY);
    localStorage.removeItem(TOKEN_KEY);
    localStorage.removeItem(USER_DATA_KEY);
    localStorage.removeItem(IS_TFA_KEY);
}
