/**
 * ML Engine Service
 * Client for connecting to the ML Engine API via Express Proxy
 * ARCH-001: All ML calls now go through authenticated Express gateway
 */

import { apiClient } from '@/lib/apiClient';

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

export interface MLSignal {
  signal_id: string;
  symbol: string;
  direction: 'long' | 'short';
  entry_price: number;
  stop_loss: number;
  take_profit: number;
  risk_reward_ratio: number;
  confidence_score: number;
  prob_tp_first: number;
  amd_phase: string;
  volatility_regime: string;
  valid_until: string;
  created_at: string;
}

export interface AMDPhase {
  symbol: string;
  phase: 'accumulation' | 'manipulation' | 'distribution' | 'unknown';
  confidence: number;
  phase_duration_bars: number;
  next_phase_probability: {
    accumulation: number;
    manipulation: number;
    distribution: number;
  };
  key_levels: {
    support: number;
    resistance: number;
  };
}

export interface AMDZone {
  phase: 'accumulation' | 'manipulation' | 'distribution' | 'unknown';
  startTime: number;
  endTime: number;
  priceHigh: number;
  priceLow: number;
  confidence: number;
}

export interface RangePrediction {
  symbol: string;
  timeframe: string;
  current_price: number;
  predicted_high: number;
  predicted_low: number;
  expected_range_percent: number;
  volatility_regime: 'low' | 'normal' | 'high' | 'extreme';
  prediction_confidence: number;
}

export interface BacktestResult {
  strategy: string;
  symbol: string;
  start_date: string;
  end_date: string;
  total_trades: number;
  winning_trades: number;
  losing_trades: number;
  win_rate: number;
  total_pnl: number;
  max_drawdown: number;
  sharpe_ratio: number;
  profit_factor: number;
}

// ============================================================================
// API Functions
// ============================================================================

/**
 * Get the latest ML signal for a symbol
 */
export async function getLatestSignal(symbol: string): Promise<MLSignal | null> {
  try {
    const response = await apiClient.get(`/proxy/ml/signals/latest/${symbol}`);
    return response.data?.signal || response.data || null;
  } catch (error) {
    if ((error as { response?: { status: number } }).response?.status === 404) return null;
    console.error('Error fetching latest signal:', error);
    return null;
  }
}

/**
 * Get active signals for all symbols
 */
export async function getActiveSignals(): Promise<MLSignal[]> {
  try {
    const response = await apiClient.get('/proxy/ml/signals/active');
    return response.data?.signals || response.data || [];
  } catch (error) {
    console.error('Error fetching active signals:', error);
    return [];
  }
}

/**
 * Get AMD phase detection for a symbol
 */
export async function getAMDPhase(symbol: string): Promise<AMDPhase | null> {
  try {
    const response = await apiClient.get(`/proxy/ml/amd/${symbol}`);
    return response.data;
  } catch (error) {
    if ((error as { response?: { status: number } }).response?.status === 404) return null;
    console.error('Error fetching AMD phase:', error);
    return null;
  }
}

/**
 * Get historical AMD zones for chart visualization
 * Returns zones within the specified time range
 */
export async function getAMDZones(
  symbol: string,
  timeframe: string = '1h',
  limit: number = 10
): Promise<AMDZone[]> {
  try {
    const response = await apiClient.get(`/proxy/ml/amd/${symbol}/zones`, {
      params: { timeframe, limit },
    });
    return response.data?.zones || response.data || [];
  } catch (error) {
    if ((error as { response?: { status: number } }).response?.status === 404) return [];
    console.error('Error fetching AMD zones:', error);
    return [];
  }
}

/**
 * Get range prediction for a symbol
 */
export async function getRangePrediction(
  symbol: string,
  _timeframe: string = '1h'
): Promise<RangePrediction | null> {
  try {
    const response = await apiClient.get(`/proxy/ml/predict/range/${symbol}`);
    return response.data;
  } catch (error) {
    if ((error as { response?: { status: number } }).response?.status === 404) return null;
    console.error('Error fetching range prediction:', error);
    return null;
  }
}

/**
 * Generate a new signal for a symbol
 */
export async function generateSignal(symbol: string): Promise<MLSignal | null> {
  try {
    const response = await apiClient.post('/proxy/ml/signals/generate', { symbol });
    return response.data?.signal || response.data || null;
  } catch (error) {
    console.error('Error generating signal:', error);
    return null;
  }
}

/**
 * Run backtest for a strategy
 */
export async function runBacktest(params: {
  strategy: string;
  symbol: string;
  start_date: string;
  end_date: string;
  initial_capital?: number;
}): Promise<BacktestResult | null> {
  try {
    const response = await apiClient.post('/proxy/ml/backtest/run', {
      symbol: params.symbol,
      strategy: params.strategy,
      startDate: params.start_date,
      endDate: params.end_date,
    });
    return response.data;
  } catch (error) {
    console.error('Error running backtest:', error);
    return null;
  }
}

/**
 * Check ML Engine health
 */
export async function checkHealth(): Promise<boolean> {
  try {
    const response = await apiClient.get('/proxy/ml/health');
    return response.data?.status === 'healthy';
  } catch {
    return false;
  }
}

// ============================================================================
// ICT/SMC Analysis Types & Functions
// ============================================================================

export interface OrderBlock {
  type: 'bullish' | 'bearish';
  high: number;
  low: number;
  midpoint: number;
  strength: number;
  valid: boolean;
  touched: boolean;
}

export interface FairValueGap {
  type: 'bullish' | 'bearish';
  high: number;
  low: number;
  midpoint: number;
  size_percent: number;
  filled: boolean;
}

export interface ICTAnalysis {
  symbol: string;
  timeframe: string;
  market_bias: 'bullish' | 'bearish' | 'neutral';
  bias_confidence: number;
  current_trend: string;
  order_blocks: OrderBlock[];
  fair_value_gaps: FairValueGap[];
  entry_zone?: { low: number; high: number };
  stop_loss?: number;
  take_profits: { tp1?: number; tp2?: number; tp3?: number };
  risk_reward?: number;
  signals: string[];
  score: number;
  premium_zone: { low: number; high: number };
  discount_zone: { low: number; high: number };
  equilibrium: number;
}

export interface EnsembleSignal {
  symbol: string;
  timeframe: string;
  action: 'BUY' | 'SELL' | 'HOLD';
  strength: 'strong' | 'moderate' | 'weak';
  confidence: number;
  net_score: number;
  strategy_signals: {
    amd: { action: string; score: number; weight: number };
    ict: { action: string; score: number; weight: number };
    range: { action: string; score: number; weight: number };
    tpsl: { action: string; score: number; weight: number };
  };
  entry?: number;
  stop_loss?: number;
  take_profit?: number;
  risk_reward?: number;
  reasoning: string[];
  timestamp: string;
}

export interface ScanResult {
  symbol: string;
  signal: EnsembleSignal;
  priority: number;
}

/**
 * Get ICT/SMC Analysis for a symbol
 */
export async function getICTAnalysis(
  symbol: string,
  timeframe: string = '1H'
): Promise<ICTAnalysis | null> {
  try {
    const response = await apiClient.post(`/proxy/ml/ict/${symbol}`, { timeframe });
    return response.data;
  } catch (error) {
    if ((error as { response?: { status: number } }).response?.status === 404) return null;
    console.error('Error fetching ICT analysis:', error);
    return null;
  }
}

/**
 * Get Ensemble Signal for a symbol
 */
export async function getEnsembleSignal(
  symbol: string,
  _timeframe: string = '1H'
): Promise<EnsembleSignal | null> {
  try {
    const response = await apiClient.post(`/proxy/ml/ensemble/${symbol}`, {});
    return response.data;
  } catch (error) {
    if ((error as { response?: { status: number } }).response?.status === 404) return null;
    console.error('Error fetching ensemble signal:', error);
    return null;
  }
}

/**
 * Get Quick Signal (fast, cached)
 */
export async function getQuickSignal(symbol: string): Promise<{
  symbol: string;
  action: string;
  confidence: number;
  score: number;
} | null> {
  try {
    const response = await apiClient.get(`/proxy/ml/ensemble/quick/${symbol}`);
    return response.data;
  } catch (error) {
    if ((error as { response?: { status: number } }).response?.status === 404) return null;
    console.error('Error fetching quick signal:', error);
    return null;
  }
}

/**
 * Scan multiple symbols for trading opportunities
 */
export async function scanSymbols(
  symbols: string[],
  minConfidence: number = 0.6
): Promise<ScanResult[]> {
  try {
    const response = await apiClient.post('/proxy/ml/scan', {
      symbols,
      filters: { min_confidence: minConfidence, timeframe: '1H' },
    });
    return response.data?.results || response.data || [];
  } catch (error) {
    console.error('Error scanning symbols:', error);
    return [];
  }
}
