import { ConfigurationError } from './_internal/errors/index.js';
import { createOperatorSdk, } from './_internal/operator/index.js';
import { createPeerSdk, } from './_internal/peer/index.js';
import { createEventSourceConnector, createRemoteRuntimeEvents, createWebSocketConnector, } from './_internal/transport-realtime/index.js';
import { createGoodVibesAuthClient, createMemoryTokenStore, } from './auth.js';
function requireBaseUrl(baseUrl) {
    const normalized = baseUrl.trim();
    if (!normalized) {
        throw new ConfigurationError('GoodVibes baseUrl is required');
    }
    return normalized;
}
function requireFetchImplementation(fetchImpl) {
    const resolved = fetchImpl ?? globalThis.fetch;
    if (typeof resolved !== 'function') {
        throw new ConfigurationError('Fetch implementation is required. Pass options.fetch or use a runtime that provides global fetch.');
    }
    return resolved;
}
function requireWebSocketImplementation(webSocketImpl) {
    const resolved = webSocketImpl ?? globalThis.WebSocket;
    if (typeof resolved !== 'function') {
        throw new ConfigurationError('WebSocket implementation is required. Pass options.WebSocketImpl or use a runtime that provides global WebSocket.');
    }
    return resolved;
}
function createOperatorOptions(options) {
    const getAuthToken = options.tokenStore
        ? () => options.tokenStore.getToken()
        : options.getAuthToken;
    return {
        baseUrl: requireBaseUrl(options.baseUrl),
        authToken: options.authToken ?? null,
        ...(getAuthToken ? { getAuthToken } : {}),
        ...(options.fetch ? { fetch: options.fetch } : {}),
        ...(options.headers ? { headers: options.headers } : {}),
        ...(options.getHeaders ? { getHeaders: options.getHeaders } : {}),
        ...(options.retry ? { retry: options.retry } : {}),
    };
}
function createPeerOptions(options) {
    const getAuthToken = options.tokenStore
        ? () => options.tokenStore.getToken()
        : options.getAuthToken;
    return {
        baseUrl: requireBaseUrl(options.baseUrl),
        authToken: options.authToken ?? null,
        ...(getAuthToken ? { getAuthToken } : {}),
        ...(options.fetch ? { fetch: options.fetch } : {}),
        ...(options.headers ? { headers: options.headers } : {}),
        ...(options.getHeaders ? { getHeaders: options.getHeaders } : {}),
        ...(options.retry ? { retry: options.retry } : {}),
    };
}
export function createGoodVibesSdk(options) {
    const baseUrl = requireBaseUrl(options.baseUrl);
    const tokenStore = options.tokenStore ?? (options.getAuthToken ? null : createMemoryTokenStore(options.authToken ?? null));
    const authToken = options.authToken ?? null;
    const getAuthToken = tokenStore
        ? () => tokenStore.getToken()
        : options.getAuthToken;
    const fetchImpl = () => requireFetchImplementation(options.fetch);
    const operator = createOperatorSdk(createOperatorOptions({
        ...options,
        tokenStore: tokenStore ?? undefined,
    }));
    const peer = createPeerSdk(createPeerOptions({
        ...options,
        tokenStore: tokenStore ?? undefined,
    }));
    return {
        operator,
        peer,
        auth: createGoodVibesAuthClient(operator, tokenStore, getAuthToken),
        realtime: {
            viaSse() {
                return createRemoteRuntimeEvents(createEventSourceConnector(baseUrl, getAuthToken ?? authToken, fetchImpl(), {
                    reconnect: options.realtime?.sseReconnect,
                    onError: options.realtime?.onError,
                }));
            },
            viaWebSocket(webSocketImpl) {
                return createRemoteRuntimeEvents(createWebSocketConnector(baseUrl, getAuthToken ?? authToken, requireWebSocketImplementation(webSocketImpl ?? options.WebSocketImpl), {
                    reconnect: options.realtime?.webSocketReconnect,
                    onError: options.realtime?.onError,
                }));
            },
        },
    };
}
