import { ConfigurationError } from './_internal/errors/index.js';
function requireStorage(storage) {
    const resolved = storage ?? globalThis.localStorage;
    if (!resolved) {
        throw new ConfigurationError('Browser token storage is unavailable. Pass BrowserTokenStoreOptions.storage or use createMemoryTokenStore().');
    }
    return resolved;
}
export function createMemoryTokenStore(initialToken = null) {
    let token = initialToken;
    return {
        async getToken() {
            return token;
        },
        async setToken(nextToken) {
            token = nextToken;
        },
        async clearToken() {
            token = null;
        },
    };
}
export function createBrowserTokenStore(options = {}) {
    const storage = requireStorage(options.storage);
    const key = options.key?.trim() || 'goodvibes.token';
    return {
        async getToken() {
            const value = storage.getItem(key);
            return value && value.trim() ? value : null;
        },
        async setToken(token) {
            if (!token) {
                storage.removeItem(key);
                return;
            }
            storage.setItem(key, token);
        },
        async clearToken() {
            storage.removeItem(key);
        },
    };
}
async function readToken(tokenStore, getAuthToken) {
    if (tokenStore) {
        return await tokenStore.getToken();
    }
    if (getAuthToken) {
        return (await getAuthToken()) ?? null;
    }
    return null;
}
function assertWritableTokenStore(tokenStore) {
    if (!tokenStore) {
        throw new ConfigurationError('This SDK instance uses a read-only auth token resolver. Pass tokenStore to enable token persistence and mutation.');
    }
    return tokenStore;
}
export function createGoodVibesAuthClient(operator, tokenStore, getAuthToken) {
    return {
        writable: tokenStore !== null,
        async current() {
            return await operator.control.auth.current();
        },
        async login(input, options = {}) {
            const result = await operator.control.auth.login(input);
            if ((options.persistToken ?? true) && tokenStore) {
                await tokenStore.setToken(result.token);
            }
            return result;
        },
        async getToken() {
            return await readToken(tokenStore, getAuthToken);
        },
        async setToken(token) {
            await assertWritableTokenStore(tokenStore).setToken(token);
        },
        async clearToken() {
            await assertWritableTokenStore(tokenStore).clearToken();
        },
    };
}
