import { client, listSessions as apiListSessions, createSession as apiCreateSession, listMessages as apiListMessages, createMessage as apiCreateMessage, abortSession as apiAbortSession, getConfig as apiGetConfig, getProviderModels as apiGetProviderModels, listFiles as apiListFiles, getGitStatus as apiGetGitStatus, getGitDiff as apiGetGitDiff, getGitBranch as apiGetGitBranch, stageFiles as apiStageFiles, unstageFiles as apiUnstageFiles, restoreFiles as apiRestoreFiles, deleteFiles as apiDeleteFiles, commitChanges as apiCommitChanges, generateCommitMessage as apiGenerateCommitMessage, pushCommits as apiPushCommits, } from '@agi-cli/api';
import { API_BASE_URL } from './config';
/**
 * Extract error message from API error response
 * Handles both string errors and structured error objects
 */
function extractErrorMessage(error) {
    if (!error) {
        return 'Unknown error';
    }
    // If it's a string, return it
    if (typeof error === 'string') {
        return error;
    }
    // If it's an error object with our standardized structure
    if (error && typeof error === 'object') {
        const errObj = error;
        // New standardized format: { error: { message, type, ... } }
        if (errObj.error && typeof errObj.error === 'object') {
            const innerError = errObj.error;
            if (typeof innerError.message === 'string') {
                return innerError.message;
            }
        }
        // Legacy format: { error: "message" }
        if (typeof errObj.error === 'string') {
            return errObj.error;
        }
        // Direct message property
        if (typeof errObj.message === 'string') {
            return errObj.message;
        }
        // Try to JSON stringify if it's a complex object
        try {
            return JSON.stringify(error);
        }
        catch {
            return 'Error occurred (unable to parse)';
        }
    }
    return 'Unknown error';
}
/**
 * Configure the API client with the correct base URL
 * This should be called once at application startup
 */
export function configureApiClient() {
    const win = window;
    const baseURL = win.AGI_SERVER_URL || API_BASE_URL;
    client.setConfig({
        baseURL,
    });
}
// Configure the client immediately when this module is imported
configureApiClient();
// Type conversion helpers
function convertSession(apiSession) {
    return {
        ...apiSession,
        title: apiSession.title ?? null,
        createdAt: typeof apiSession.createdAt === 'string'
            ? new Date(apiSession.createdAt).getTime()
            : apiSession.createdAt,
        lastActiveAt: typeof apiSession.lastActiveAt === 'string'
            ? new Date(apiSession.lastActiveAt).getTime()
            : apiSession.lastActiveAt,
    };
}
function convertMessage(apiMessage) {
    return {
        ...apiMessage,
        createdAt: typeof apiMessage.createdAt === 'string'
            ? new Date(apiMessage.createdAt).getTime()
            : apiMessage.createdAt,
        completedAt: apiMessage.completedAt
            ? typeof apiMessage.completedAt === 'string'
                ? new Date(apiMessage.completedAt).getTime()
                : apiMessage.completedAt
            : null,
    };
}
class ApiClient {
    get baseUrl() {
        // Always check for injected URL at runtime
        const win = window;
        if (win.AGI_SERVER_URL) {
            return win.AGI_SERVER_URL;
        }
        return API_BASE_URL;
    }
    // Session methods using new API
    async getSessions() {
        const response = await apiListSessions();
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        return (response.data || []).map(convertSession);
    }
    async createSession(data) {
        const response = await apiCreateSession({
            body: data,
        });
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        if (!response.data) {
            throw new Error('No data returned from create session');
        }
        return convertSession(response.data);
    }
    async updateSession(sessionId, data) {
        const response = await fetch(`${this.baseUrl}/v1/sessions/${sessionId}`, {
            method: 'PATCH',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(data),
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to update session' }));
            throw new Error(extractErrorMessage(errorData));
        }
        const sessionData = await response.json();
        return convertSession(sessionData);
    }
    async deleteSession(sessionId) {
        const response = await fetch(`${this.baseUrl}/v1/sessions/${sessionId}`, {
            method: 'DELETE',
            headers: {
                'Content-Type': 'application/json',
            },
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to delete session' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async abortSession(sessionId) {
        const response = await apiAbortSession({
            path: { sessionId },
        });
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        return response.data;
    }
    async abortMessage(sessionId, messageId) {
        const baseUrl = this.baseUrl;
        const response = await fetch(`${baseUrl}/v1/sessions/${sessionId}/abort`, {
            method: 'DELETE',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ messageId }),
        });
        if (!response.ok) {
            throw new Error('Failed to abort message');
        }
        return response.json();
    }
    async getQueueState(sessionId) {
        const baseUrl = this.baseUrl;
        const response = await fetch(`${baseUrl}/v1/sessions/${sessionId}/queue`);
        if (!response.ok) {
            throw new Error('Failed to get queue state');
        }
        return response.json();
    }
    async removeFromQueue(sessionId, messageId) {
        const baseUrl = this.baseUrl;
        const response = await fetch(`${baseUrl}/v1/sessions/${sessionId}/queue/${messageId}`, { method: 'DELETE' });
        if (!response.ok) {
            throw new Error('Failed to remove from queue');
        }
        return response.json();
    }
    async getMessages(sessionId) {
        const response = await apiListMessages({
            path: { id: sessionId },
        });
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        return (response.data || []).map(convertMessage);
    }
    async sendMessage(sessionId, data) {
        const response = await apiCreateMessage({
            path: { id: sessionId },
            body: data,
        });
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        return response.data;
    }
    getStreamUrl(sessionId) {
        return `${this.baseUrl}/v1/sessions/${sessionId}/stream`;
    }
    // Config methods using new API
    async getConfig() {
        const response = await apiGetConfig();
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        return response.data;
    }
    async getModels(providerId) {
        const response = await apiGetProviderModels({
            // biome-ignore lint/suspicious/noExplicitAny: API type mismatch between client and server
            path: { provider: providerId },
        });
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        return response.data;
    }
    async getAllModels() {
        const response = await fetch(`${this.baseUrl}/v1/config/models`, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
            },
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to fetch models' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async updateDefaults(data) {
        const response = await fetch(`${this.baseUrl}/v1/config/defaults`, {
            method: 'PATCH',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(data),
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to update defaults' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    // Git methods using new API
    async getGitStatus() {
        const response = await apiGetGitStatus();
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        // biome-ignore lint/suspicious/noExplicitAny: API response structure mismatch
        return response.data?.data;
    }
    async getGitDiff(file, staged = false) {
        const response = await apiGetGitDiff({
            query: {
                file,
                staged: staged ? 'true' : 'false',
            },
        });
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        // biome-ignore lint/suspicious/noExplicitAny: API response structure mismatch
        return response.data?.data;
    }
    async generateCommitMessage(sessionId) {
        const response = await apiGenerateCommitMessage({
            body: sessionId ? { sessionId } : {},
        });
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        // biome-ignore lint/suspicious/noExplicitAny: API response structure mismatch
        return response.data?.data;
    }
    async stageFiles(files) {
        const response = await apiStageFiles({
            // biome-ignore lint/suspicious/noExplicitAny: API type mismatch between client and server
            body: { files },
        });
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        // biome-ignore lint/suspicious/noExplicitAny: API response structure mismatch
        return response.data?.data;
    }
    async unstageFiles(files) {
        const response = await apiUnstageFiles({
            // biome-ignore lint/suspicious/noExplicitAny: API type mismatch between client and server
            body: { files },
        });
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        // biome-ignore lint/suspicious/noExplicitAny: API response structure mismatch
        return response.data?.data;
    }
    async restoreFiles(files) {
        const response = await apiRestoreFiles({
            // biome-ignore lint/suspicious/noExplicitAny: API type mismatch between client and server
            body: { files },
        });
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        // biome-ignore lint/suspicious/noExplicitAny: API response structure mismatch
        return response.data?.data;
    }
    async deleteFiles(files) {
        const response = await apiDeleteFiles({
            // biome-ignore lint/suspicious/noExplicitAny: API type mismatch between client and server
            body: { files },
        });
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        // biome-ignore lint/suspicious/noExplicitAny: API response structure mismatch
        return response.data?.data;
    }
    async commitChanges(message) {
        const response = await apiCommitChanges({
            // biome-ignore lint/suspicious/noExplicitAny: API type mismatch between client and server
            body: { message },
        });
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        // biome-ignore lint/suspicious/noExplicitAny: API response structure mismatch
        return response.data?.data;
    }
    async getGitBranch() {
        const response = await apiGetGitBranch();
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        // biome-ignore lint/suspicious/noExplicitAny: API response structure mismatch
        return response.data?.data;
    }
    async pushCommits() {
        const response = await apiPushCommits({
            // biome-ignore lint/suspicious/noExplicitAny: API type mismatch between client and server
            body: {},
        });
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        // biome-ignore lint/suspicious/noExplicitAny: API response structure mismatch
        return response.data?.data;
    }
    async listFiles() {
        const response = await apiListFiles();
        if (response.error) {
            throw new Error(extractErrorMessage(response.error));
        }
        return response.data;
    }
    async getSessionFiles(sessionId) {
        const response = await fetch(`${this.baseUrl}/v1/sessions/${sessionId}/files`, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
            },
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to fetch session files' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async createBranch(sessionId, data) {
        const response = await fetch(`${this.baseUrl}/v1/sessions/${sessionId}/branch`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(data),
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to create branch' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async listBranches(sessionId) {
        const response = await fetch(`${this.baseUrl}/v1/sessions/${sessionId}/branches`, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
            },
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to list branches' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async getParentSession(sessionId) {
        const response = await fetch(`${this.baseUrl}/v1/sessions/${sessionId}/parent`, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
            },
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to get parent session' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async getSetuBalance() {
        try {
            const response = await fetch(`${this.baseUrl}/v1/setu/balance`, {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json',
                },
            });
            if (!response.ok) {
                return null;
            }
            return await response.json();
        }
        catch {
            return null;
        }
    }
    async getSetuWallet() {
        try {
            const response = await fetch(`${this.baseUrl}/v1/setu/wallet`, {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json',
                },
            });
            if (!response.ok) {
                return { configured: false };
            }
            return await response.json();
        }
        catch {
            return { configured: false };
        }
    }
    async getSetuUsdcBalance(network = 'mainnet') {
        try {
            const response = await fetch(`${this.baseUrl}/v1/setu/usdc-balance?network=${network}`, {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json',
                },
            });
            if (!response.ok) {
                return null;
            }
            return await response.json();
        }
        catch {
            return null;
        }
    }
    async getShareStatus(sessionId) {
        const response = await fetch(`${this.baseUrl}/v1/sessions/${sessionId}/share`, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
            },
        });
        if (!response.ok) {
            return { shared: false };
        }
        return await response.json();
    }
    async shareSession(sessionId) {
        const response = await fetch(`${this.baseUrl}/v1/sessions/${sessionId}/share`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to share session' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async syncSession(sessionId) {
        const response = await fetch(`${this.baseUrl}/v1/sessions/${sessionId}/share`, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json',
            },
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to sync session' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async approveToolCall(sessionId, callId, approved) {
        const response = await fetch(`${this.baseUrl}/v1/sessions/${sessionId}/approval`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ callId, approved }),
        });
        if (!response.ok) {
            throw new Error('Failed to send tool approval');
        }
        return await response.json();
    }
    async getPendingApprovals(sessionId) {
        const response = await fetch(`${this.baseUrl}/v1/sessions/${sessionId}/approval/pending`, {
            method: 'GET',
            headers: { 'Content-Type': 'application/json' },
        });
        if (!response.ok) {
            return { ok: false, pending: [] };
        }
        return await response.json();
    }
    async getPolarTopupEstimate(amount) {
        try {
            const response = await fetch(`${this.baseUrl}/v1/setu/topup/polar/estimate?amount=${amount}`, {
                method: 'GET',
                headers: { 'Content-Type': 'application/json' },
            });
            if (!response.ok) {
                return null;
            }
            return await response.json();
        }
        catch {
            return null;
        }
    }
    async createPolarCheckout(amount, successUrl) {
        const response = await fetch(`${this.baseUrl}/v1/setu/topup/polar`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ amount, successUrl }),
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to create checkout' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async selectTopupMethod(sessionId, method) {
        const response = await fetch(`${this.baseUrl}/v1/setu/topup/select`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ sessionId, method }),
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to select topup method' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async cancelTopup(sessionId, reason) {
        const response = await fetch(`${this.baseUrl}/v1/setu/topup/cancel`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ sessionId, reason }),
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to cancel topup' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async getPendingTopup(sessionId) {
        try {
            const response = await fetch(`${this.baseUrl}/v1/setu/topup/pending?sessionId=${sessionId}`, {
                method: 'GET',
                headers: { 'Content-Type': 'application/json' },
            });
            if (!response.ok) {
                return { hasPending: false };
            }
            return await response.json();
        }
        catch {
            return { hasPending: false };
        }
    }
    async getPolarTopupStatus(checkoutId) {
        try {
            const response = await fetch(`${this.baseUrl}/v1/setu/topup/polar/status?checkoutId=${checkoutId}`, {
                method: 'GET',
                headers: { 'Content-Type': 'application/json' },
            });
            if (!response.ok) {
                return null;
            }
            return await response.json();
        }
        catch {
            return null;
        }
    }
    async retryMessage(sessionId, messageId) {
        const response = await fetch(`${this.baseUrl}/v1/sessions/${sessionId}/messages/${messageId}/retry`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to retry message' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async getAuthStatus() {
        const response = await fetch(`${this.baseUrl}/v1/auth/status`, {
            method: 'GET',
            headers: { 'Content-Type': 'application/json' },
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to get auth status' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async setupSetuWallet() {
        const response = await fetch(`${this.baseUrl}/v1/auth/setu/setup`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to setup wallet' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async importSetuWallet(privateKey) {
        const response = await fetch(`${this.baseUrl}/v1/auth/setu/import`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ privateKey }),
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to import wallet' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async addProvider(provider, apiKey) {
        const response = await fetch(`${this.baseUrl}/v1/auth/${provider}`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ apiKey }),
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to add provider' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async removeProvider(provider) {
        const response = await fetch(`${this.baseUrl}/v1/auth/${provider}`, {
            method: 'DELETE',
            headers: { 'Content-Type': 'application/json' },
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to remove provider' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async completeOnboarding() {
        const response = await fetch(`${this.baseUrl}/v1/auth/onboarding/complete`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to complete onboarding' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    getOAuthStartUrl(provider, mode) {
        const baseUrl = `${this.baseUrl}/v1/auth/${provider}/oauth/start`;
        if (mode) {
            return `${baseUrl}?mode=${mode}`;
        }
        return baseUrl;
    }
    async getOAuthUrl(provider, mode) {
        const response = await fetch(`${this.baseUrl}/v1/auth/${provider}/oauth/url`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ mode }),
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to get OAuth URL' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
    async exchangeOAuthCode(provider, code, sessionId) {
        const response = await fetch(`${this.baseUrl}/v1/auth/${provider}/oauth/exchange`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ code, sessionId }),
        });
        if (!response.ok) {
            const errorData = await response
                .json()
                .catch(() => ({ error: 'Failed to exchange OAuth code' }));
            throw new Error(extractErrorMessage(errorData));
        }
        return await response.json();
    }
}
export const apiClient = new ApiClient();
//# sourceMappingURL=api-client.js.map