/**
 * Trading Bots Service
 * ====================
 * Client for trading bots API (Atlas, Orion, Nova)
 * Endpoints: /api/v1/trading/bots/*
 */

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

// ============================================================================
// Types
// ============================================================================

export type BotStatus = 'active' | 'paused' | 'stopped' | 'error';
export type BotType = 'paper' | 'live';
export type StrategyType = 'atlas' | 'orion' | 'nova' | 'custom';
export type Timeframe = '1m' | '5m' | '15m' | '30m' | '1h' | '4h' | '1d' | '1w';
export type RiskLevel = 'low' | 'medium' | 'high';

export interface TradingBot {
  id: string;
  userId: string;
  name: string;
  botType: BotType;
  status: BotStatus;
  symbols: string[];
  timeframe: Timeframe;
  initialCapital: number;
  currentCapital: number;
  maxPositionSizePct: number;
  maxDailyLossPct: number;
  maxDrawdownPct: number;
  strategyType?: StrategyType;
  strategyConfig: TradingBotStrategyConfig;
  totalTrades: number;
  winningTrades: number;
  totalProfitLoss: number;
  winRate: number;
  startedAt?: string;
  stoppedAt?: string;
  lastTradeAt?: string;
  createdAt: string;
  updatedAt: string;
}

export interface TradingBotStrategyConfig {
  strategy_name?: string;
  entry_rules?: Record<string, unknown>;
  exit_rules?: Record<string, unknown>;
  risk_management?: {
    max_position_size?: number;
    stop_loss_percent?: number;
    take_profit_percent?: number;
    max_daily_loss?: number;
  };
  indicators?: Array<{ name: string; params: Record<string, unknown> }>;
}

export interface BotTemplate {
  type: StrategyType;
  name: string;
  description: string;
  defaultConfig: TradingBotStrategyConfig;
  riskLevel: RiskLevel;
  recommendedTimeframes: Timeframe[];
  recommendedSymbols: string[];
}

export interface BotPerformance {
  totalTrades: number;
  winRate: number;
  profitLoss: number;
  sharpeRatio: number;
  maxDrawdown: number;
  averageWin: number;
  averageLoss: number;
  profitFactor: number;
}

export interface BotExecution {
  id: string;
  botId: string;
  action: 'buy' | 'sell';
  symbol: string;
  price: number;
  quantity: number;
  timestamp: string;
  result: 'success' | 'failed' | 'pending';
  pnl?: number;
  metadata?: Record<string, unknown>;
}

export interface CreateBotInput {
  name: string;
  botType?: BotType;
  symbols: string[];
  timeframe?: Timeframe;
  initialCapital: number;
  strategyType?: StrategyType;
  strategyConfig?: TradingBotStrategyConfig;
  maxPositionSizePct?: number;
  maxDailyLossPct?: number;
  maxDrawdownPct?: number;
}

export interface UpdateBotInput {
  name?: string;
  status?: BotStatus;
  symbols?: string[];
  timeframe?: Timeframe;
  strategyType?: StrategyType;
  strategyConfig?: TradingBotStrategyConfig;
  maxPositionSizePct?: number;
  maxDailyLossPct?: number;
  maxDrawdownPct?: number;
}

export interface BotFilters {
  status?: BotStatus;
  botType?: BotType;
  strategyType?: StrategyType;
  limit?: number;
  offset?: number;
}

// ============================================================================
// 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;
}

// ============================================================================
// Bot CRUD Operations
// ============================================================================

/**
 * Get all bots for the authenticated user
 */
export async function getBots(filters?: BotFilters): Promise<TradingBot[]> {
  const params = new URLSearchParams();
  if (filters?.status) params.append('status', filters.status);
  if (filters?.botType) params.append('botType', filters.botType);
  if (filters?.strategyType) params.append('strategyType', filters.strategyType);
  if (filters?.limit) params.append('limit', filters.limit.toString());
  if (filters?.offset) params.append('offset', filters.offset.toString());

  const queryString = params.toString();
  const url = `${API_URL}/api/v1/trading/bots${queryString ? `?${queryString}` : ''}`;
  return fetchAPI<TradingBot[]>(url);
}

/**
 * Get a specific bot by ID
 */
export async function getBotById(botId: string): Promise<TradingBot> {
  return fetchAPI<TradingBot>(`${API_URL}/api/v1/trading/bots/${botId}`);
}

/**
 * Create a new trading bot
 */
export async function createBot(input: CreateBotInput): Promise<TradingBot> {
  return fetchAPI<TradingBot>(`${API_URL}/api/v1/trading/bots`, {
    method: 'POST',
    body: JSON.stringify(input),
  });
}

/**
 * Update bot configuration
 */
export async function updateBot(botId: string, input: UpdateBotInput): Promise<TradingBot> {
  return fetchAPI<TradingBot>(`${API_URL}/api/v1/trading/bots/${botId}`, {
    method: 'PUT',
    body: JSON.stringify(input),
  });
}

/**
 * Delete a bot (must be stopped first)
 */
export async function deleteBot(botId: string): Promise<void> {
  await fetchAPI<void>(`${API_URL}/api/v1/trading/bots/${botId}`, {
    method: 'DELETE',
  });
}

// ============================================================================
// Bot Control Operations
// ============================================================================

/**
 * Start a bot
 */
export async function startBot(botId: string): Promise<TradingBot> {
  return fetchAPI<TradingBot>(`${API_URL}/api/v1/trading/bots/${botId}/start`, {
    method: 'POST',
  });
}

/**
 * Stop a bot
 */
export async function stopBot(botId: string): Promise<TradingBot> {
  return fetchAPI<TradingBot>(`${API_URL}/api/v1/trading/bots/${botId}/stop`, {
    method: 'POST',
  });
}

// ============================================================================
// Performance & Executions
// ============================================================================

/**
 * Get bot performance metrics
 */
export async function getBotPerformance(botId: string): Promise<BotPerformance> {
  return fetchAPI<BotPerformance>(`${API_URL}/api/v1/trading/bots/${botId}/performance`);
}

/**
 * Get bot execution history
 */
export async function getBotExecutions(
  botId: string,
  options?: { limit?: number; offset?: number }
): Promise<BotExecution[]> {
  const params = new URLSearchParams();
  if (options?.limit) params.append('limit', options.limit.toString());
  if (options?.offset) params.append('offset', options.offset.toString());

  const queryString = params.toString();
  const url = `${API_URL}/api/v1/trading/bots/${botId}/executions${queryString ? `?${queryString}` : ''}`;
  return fetchAPI<BotExecution[]>(url);
}

// ============================================================================
// Bot Templates
// ============================================================================

/**
 * Get available bot templates (Atlas, Orion, Nova, Custom)
 */
export async function getBotTemplates(): Promise<BotTemplate[]> {
  return fetchAPI<BotTemplate[]>(`${API_URL}/api/v1/trading/bots/templates`);
}

/**
 * Get a specific bot template by type
 */
export async function getBotTemplate(type: StrategyType): Promise<BotTemplate> {
  return fetchAPI<BotTemplate>(`${API_URL}/api/v1/trading/bots/templates/${type}`);
}

// ============================================================================
// Export all functions
// ============================================================================

export const botsService = {
  // CRUD
  getBots,
  getBotById,
  createBot,
  updateBot,
  deleteBot,
  // Control
  startBot,
  stopBot,
  // Performance
  getBotPerformance,
  getBotExecutions,
  // Templates
  getBotTemplates,
  getBotTemplate,
};

export default botsService;
