/**
 * Trading Agents Service
 * Client for connecting to the Trading Agents API (Atlas, Orion, Nova)
 */

import type {
  AgentType,
  AgentStatusResponse,
  AgentMetrics,
  AgentPosition,
  AgentTrade,
  TradingBotConfig,
  SignalInput,
  TradingAgentsHealthResponse,
  AgentSummary,
  CloseAllPositionsResponse,
  SignalResponse,
  BroadcastSignalResponse,
} from '../types/tradingAgents.types';

const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:3080';

// ============================================================================
// Helper Function
// ============================================================================

/**
 * Generic fetch wrapper with error handling
 */
async function fetchAPI<T>(
  url: string,
  options?: RequestInit
): Promise<T> {
  const response = await fetch(url, {
    credentials: 'include',
    headers: {
      'Content-Type': 'application/json',
      ...options?.headers,
    },
    ...options,
  });

  if (!response.ok) {
    const error = await response.json().catch(() => ({
      error: { message: 'Failed to fetch data', code: 'FETCH_ERROR' },
    }));
    throw new Error(error.error?.message || 'Request failed');
  }

  const data = await response.json();
  return data.data || data;
}

// ============================================================================
// Health & Status
// ============================================================================

/**
 * Get Trading Agents service health
 */
export async function getAgentsHealth(): Promise<TradingAgentsHealthResponse> {
  return fetchAPI<TradingAgentsHealthResponse>(`${API_URL}/api/v1/agents/health`);
}

/**
 * Check if Trading Agents service is available
 */
export async function checkAgentsConnection(): Promise<{ connected: boolean }> {
  return fetchAPI<{ connected: boolean }>(`${API_URL}/api/v1/agents/connection`);
}

/**
 * Get summary of all trading agents
 */
export async function getAllAgentsSummary(): Promise<AgentSummary[]> {
  return fetchAPI<AgentSummary[]>(`${API_URL}/api/v1/agents/summary`);
}

// ============================================================================
// Agent Lifecycle
// ============================================================================

/**
 * Start a trading agent
 */
export async function startAgent(
  agentType: AgentType,
  config: TradingBotConfig
): Promise<AgentStatusResponse> {
  return fetchAPI<AgentStatusResponse>(
    `${API_URL}/api/v1/agents/${agentType}/start`,
    {
      method: 'POST',
      body: JSON.stringify(config),
    }
  );
}

/**
 * Stop a trading agent
 */
export async function stopAgent(agentType: AgentType): Promise<AgentStatusResponse> {
  return fetchAPI<AgentStatusResponse>(
    `${API_URL}/api/v1/agents/${agentType}/stop`,
    {
      method: 'POST',
    }
  );
}

/**
 * Pause a trading agent
 */
export async function pauseAgent(agentType: AgentType): Promise<AgentStatusResponse> {
  return fetchAPI<AgentStatusResponse>(
    `${API_URL}/api/v1/agents/${agentType}/pause`,
    {
      method: 'POST',
    }
  );
}

/**
 * Resume a paused trading agent
 */
export async function resumeAgent(agentType: AgentType): Promise<AgentStatusResponse> {
  return fetchAPI<AgentStatusResponse>(
    `${API_URL}/api/v1/agents/${agentType}/resume`,
    {
      method: 'POST',
    }
  );
}

// ============================================================================
// Agent Status & Metrics
// ============================================================================

/**
 * Get current status of a specific agent
 */
export async function getAgentStatus(agentType: AgentType): Promise<AgentStatusResponse> {
  return fetchAPI<AgentStatusResponse>(`${API_URL}/api/v1/agents/${agentType}/status`);
}

/**
 * Get performance metrics of a specific agent
 */
export async function getAgentMetrics(agentType: AgentType): Promise<AgentMetrics> {
  return fetchAPI<AgentMetrics>(`${API_URL}/api/v1/agents/${agentType}/metrics`);
}

// ============================================================================
// Positions & Trades
// ============================================================================

/**
 * Get open positions for a specific agent
 */
export async function getAgentPositions(agentType: AgentType): Promise<AgentPosition[]> {
  return fetchAPI<AgentPosition[]>(`${API_URL}/api/v1/agents/${agentType}/positions`);
}

/**
 * Get trade history for a specific agent
 */
export async function getAgentTrades(
  agentType: AgentType,
  options?: { limit?: number; offset?: number; symbol?: string }
): Promise<AgentTrade[]> {
  const params = new URLSearchParams();
  if (options?.limit) params.append('limit', options.limit.toString());
  if (options?.offset) params.append('offset', options.offset.toString());
  if (options?.symbol) params.append('symbol', options.symbol);

  const url = `${API_URL}/api/v1/agents/${agentType}/trades${params.toString() ? `?${params.toString()}` : ''}`;
  return fetchAPI<AgentTrade[]>(url);
}

/**
 * Close a specific position
 */
export async function closePosition(
  agentType: AgentType,
  positionId: string
): Promise<AgentTrade> {
  return fetchAPI<AgentTrade>(
    `${API_URL}/api/v1/agents/${agentType}/positions/${positionId}/close`,
    {
      method: 'POST',
    }
  );
}

/**
 * Close all positions for a specific agent
 */
export async function closeAllPositions(
  agentType: AgentType
): Promise<CloseAllPositionsResponse> {
  return fetchAPI<CloseAllPositionsResponse>(
    `${API_URL}/api/v1/agents/${agentType}/positions/close-all`,
    {
      method: 'POST',
    }
  );
}

// ============================================================================
// Signals
// ============================================================================

/**
 * Send a trading signal to a specific agent
 */
export async function sendSignal(
  agentType: AgentType,
  signal: SignalInput
): Promise<SignalResponse> {
  return fetchAPI<SignalResponse>(
    `${API_URL}/api/v1/agents/${agentType}/signal`,
    {
      method: 'POST',
      body: JSON.stringify(signal),
    }
  );
}

/**
 * Broadcast a signal to all running agents
 */
export async function broadcastSignal(
  signal: SignalInput
): Promise<BroadcastSignalResponse> {
  return fetchAPI<BroadcastSignalResponse>(
    `${API_URL}/api/v1/signals/broadcast`,
    {
      method: 'POST',
      body: JSON.stringify(signal),
    }
  );
}
