/**
 * TanStack Query hooks for the Trading Engine API.
 * All endpoints are proxied through /trading/ in nginx.
 * Requirements: 14.4, 14.5, 14.6, 14.7, 15.6, 16.5, 17.4, 19.10, 20.9
 */
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { apiGet, apiPost, apiPut } from './client';

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

export interface TradingEngineStatus {
  enabled: boolean;
  paused: boolean;
  risk_tier: string;
  circuit_breaker_active: boolean;
  circuit_breaker_trigger_type: string | null;
  circuit_breaker_cooldown_expires: string | null;
  active_pool: number;
  reserve_pool: number;
  portfolio_heat: number;
  portfolio_value: number;
  open_position_count: number;
  max_open_positions: number;
  absolute_position_cap: number;
  last_decision_at: string | null;
  micro_trading_enabled: boolean;
  uptime_seconds: number | null;
}

export interface TradingDecision {
  id: string;
  recommendation_id: string | null;
  decision: string;
  skip_reason: string | null;
  ticker: string;
  computed_position_size: number | null;
  computed_share_quantity: number | null;
  risk_tier_at_decision: string;
  portfolio_heat_at_decision: number | null;
  active_pool_at_decision: number | null;
  reserve_pool_at_decision: number | null;
  circuit_breaker_status: string;
  correlation_check_result: Record<string, unknown>;
  sector_exposure_check_result: Record<string, unknown>;
  earnings_proximity_flag: boolean;
  is_micro_trade: boolean;
  decision_trace: Record<string, unknown>;
  created_at: string;
}

export interface TradingMetrics {
  total_portfolio_value: number;
  active_pool: number;
  reserve_pool: number;
  unrealized_pnl: number;
  realized_pnl: number;
  daily_pnl: number;
  win_count: number;
  loss_count: number;
  win_rate: number;
  avg_win: number;
  avg_loss: number;
  profit_factor: number;
  sharpe_ratio: number;
  max_drawdown: number;
  current_drawdown_pct: number;
  portfolio_heat: number;
  computed_at: string;
}

export interface PortfolioSnapshot {
  id: string;
  snapshot_date: string;
  portfolio_value: number;
  active_pool: number;
  reserve_pool: number;
  daily_return: number | null;
  cumulative_return: number | null;
  unrealized_pnl: number | null;
  realized_pnl: number | null;
  win_count: number;
  loss_count: number;
  win_rate: number | null;
  sharpe_ratio: number | null;
  max_drawdown: number | null;
  current_drawdown_pct: number | null;
  portfolio_heat: number | null;
  risk_tier: string | null;
  positions: unknown[];
  metrics: Record<string, unknown>;
  created_at: string;
}

export interface TradingEngineConfig {
  id: string;
  enabled: boolean;
  paused: boolean;
  risk_tier: string;
  reserve_siphon_pct: number;
  polling_interval_seconds: number;
  gradual_entry_tranches: number;
  gradual_entry_threshold_dollars: number;
  gradual_entry_interval_minutes: number;
  trading_window_start_minutes: number;
  trading_window_end_minutes: number;
  max_open_positions: number;
  circuit_breaker_daily_loss_pct: number;
  circuit_breaker_single_position_loss_pct: number;
  circuit_breaker_ticker_cooldown_hours: number;
  circuit_breaker_volatility_pause_hours: number;
  circuit_breaker_stop_loss_hits_threshold: number;
  circuit_breaker_stop_loss_window_minutes: number;
  active_pool_minimum: number;
  emergency_drawdown_threshold_pct: number;
  reserve_high_water_pct: number;
  absolute_position_cap: number;
  correlation_reduction_threshold: number;
  correlation_rejection_threshold: number;
  earnings_pre_window_days: number;
  earnings_post_cooldown_days: number;
  micro_trading_enabled: boolean;
  micro_trading_interval_seconds: number;
  micro_trading_allocation_cap_pct: number;
  micro_trading_max_daily: number;
  micro_trading_max_hold_minutes: number;
  notification_sms_enabled: boolean;
  notification_email_enabled: boolean;
  notification_phone_number: string | null;
  notification_email_recipient: string | null;
  notification_sns_topic_arn: string | null;
  notification_rate_limit_sms_per_hour: number;
  notification_rate_limit_email_per_hour: number;
  notification_daily_summary_time: string;
  created_at: string;
  updated_at: string;
}

export interface BacktestResult {
  id: string;
  start_date: string;
  end_date: string;
  initial_capital: number;
  risk_tier: string;
  config: Record<string, unknown>;
  total_return: number | null;
  sharpe_ratio: number | null;
  max_drawdown: number | null;
  win_rate: number | null;
  profit_factor: number | null;
  trade_count: number | null;
  equity_curve: Array<{ date: string; portfolio_value: number }>;
  status: string;
  completed_at: string | null;
  created_at: string;
}

export interface NotificationConfig {
  sms_enabled: boolean;
  email_enabled: boolean;
  phone_number: string | null;
  email_recipient: string | null;
  sns_topic_arn: string | null;
  rate_limit_sms_per_hour: number;
  rate_limit_email_per_hour: number;
  daily_summary_time: string;
}

export interface NotificationRecord {
  id: string;
  channel: string;
  event_type: string;
  message: string;
  delivery_status: string;
  retry_count: number;
  error_message: string | null;
  created_at: string;
  delivered_at: string | null;
}

// ---------------------------------------------------------------------------
// Query hooks
// ---------------------------------------------------------------------------

/** Fetch current trading engine status (risk tier, circuit breaker, pools, etc.) */
export function useTradingStatus() {
  return useQuery<TradingEngineStatus>({
    queryKey: ['trading-status'],
    queryFn: () => apiGet<TradingEngineStatus>('trading', '/api/trading/status'),
  });
}

/** Fetch recent trading decisions with optional pagination and filters. */
export function useTradingDecisions(params?: {
  ticker?: string;
  decision?: string;
  is_micro_trade?: boolean;
  limit?: number;
  offset?: number;
}) {
  const qs = new URLSearchParams();
  if (params?.ticker) qs.set('ticker', params.ticker);
  if (params?.decision) qs.set('decision', params.decision);
  if (params?.is_micro_trade !== undefined) qs.set('is_micro_trade', String(params.is_micro_trade));
  if (params?.limit) qs.set('limit', String(params.limit));
  if (params?.offset) qs.set('offset', String(params.offset));
  const path = `/api/trading/decisions${qs.toString() ? '?' + qs : ''}`;
  return useQuery<TradingDecision[]>({
    queryKey: ['trading-decisions', params],
    queryFn: () => apiGet<TradingDecision[]>('trading', path),
  });
}

/** Fetch current performance metrics. */
export function useTradingMetrics() {
  return useQuery<TradingMetrics>({
    queryKey: ['trading-metrics'],
    queryFn: () => apiGet<TradingMetrics>('trading', '/api/trading/metrics'),
  });
}

/** Fetch historical daily portfolio snapshots. */
export function useTradingMetricsHistory() {
  return useQuery<PortfolioSnapshot[]>({
    queryKey: ['trading-metrics-history'],
    queryFn: () => apiGet<PortfolioSnapshot[]>('trading', '/api/trading/metrics/history'),
  });
}

/** Fetch trading engine configuration. */
export function useTradingConfig() {
  return useQuery<TradingEngineConfig>({
    queryKey: ['trading-config'],
    queryFn: () => apiGet<TradingEngineConfig>('trading', '/api/trading/config'),
  });
}

/** Fetch a backtest result by ID. Polls every 2s while status is pending/running. */
export function useBacktestResult(id: string | undefined) {
  return useQuery<BacktestResult>({
    queryKey: ['backtest-result', id],
    queryFn: () => apiGet<BacktestResult>('trading', `/api/trading/backtest/${id}`),
    enabled: !!id,
    refetchInterval: (query) => {
      const status = query.state.data?.status;
      if (!status || status === 'running' || status === 'pending') return 2000;
      return false;
    },
  });
}

/** Fetch notification preferences. */
export function useNotificationConfig() {
  return useQuery<NotificationConfig>({
    queryKey: ['notification-config'],
    queryFn: () => apiGet<NotificationConfig>('trading', '/api/trading/notifications/config'),
  });
}

/** Fetch notification history. */
export function useNotificationHistory() {
  return useQuery<NotificationRecord[]>({
    queryKey: ['notification-history'],
    queryFn: () => apiGet<NotificationRecord[]>('trading', '/api/trading/notifications/history'),
  });
}

// ---------------------------------------------------------------------------
// Mutation hooks
// ---------------------------------------------------------------------------

/** Update trading engine configuration. */
export function useUpdateTradingConfig() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (body: Partial<TradingEngineConfig>) =>
      apiPut<TradingEngineConfig>('trading', '/api/trading/config', body),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['trading-config'] });
      qc.invalidateQueries({ queryKey: ['trading-status'] });
    },
  });
}

/** Pause the trading engine. */
export function usePauseTradingEngine() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: () => apiPost<unknown>('trading', '/api/trading/pause', {}),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['trading-status'] }),
  });
}

/** Resume the trading engine. */
export function useResumeTradingEngine() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: () => apiPost<unknown>('trading', '/api/trading/resume', {}),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['trading-status'] }),
  });
}

/** Launch a new backtest run. */
export function useBacktestLaunch() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (body: { start_date: string; end_date: string; initial_capital: number; risk_tier: string }) =>
      apiPost<BacktestResult>('trading', '/api/trading/backtest', body),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['backtest-result'] }),
  });
}

/** Full paper trading reset: liquidates broker positions, cancels orders,
 *  clears all local trading state, and syncs capital from the broker. */
export function useResetPaperTrading() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (params: { initial_capital?: number; reserve_pct?: number } = {}) =>
      apiPost<{ reset: boolean; initial_capital: number; active_pool: number; reserve_pool: number; broker: Record<string, number> }>(
        'trading', '/api/trading/reset', {
          initial_capital: params.initial_capital ?? 0,
          reserve_pct: params.reserve_pct ?? undefined,
        },
      ),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['trading-status'] });
      qc.invalidateQueries({ queryKey: ['trading-decisions'] });
      qc.invalidateQueries({ queryKey: ['trading-metrics'] });
      qc.invalidateQueries({ queryKey: ['trading-metrics-history'] });
    },
  });
}

/** Update notification preferences. */
export function useUpdateNotificationConfig() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (body: Partial<NotificationConfig>) =>
      apiPut<NotificationConfig>('trading', '/api/trading/notifications/config', body),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['notification-config'] }),
  });
}

// ---------------------------------------------------------------------------
// Override Order (manual trade submission)
// ---------------------------------------------------------------------------

export interface OverrideOrderRequest {
  ticker: string;
  side: 'buy' | 'sell';
  quantity: number;
  order_type: 'market' | 'limit' | 'stop' | 'stop_limit';
  limit_price?: number;
  stop_price?: number;
}

export interface OverrideOrderResponse {
  job_id: string;
  status: string;
  ticker: string;
  side: string;
  quantity: number;
  auto_registered: boolean;
}

/** Submit a manual override order to the trading engine. */
export function useSubmitOverrideOrder() {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (body: OverrideOrderRequest) =>
      apiPost<OverrideOrderResponse>('trading', '/api/trading/override/order', body),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['orders'] });
      qc.invalidateQueries({ queryKey: ['positions'] });
      qc.invalidateQueries({ queryKey: ['companies'] });
    },
  });
}
