/**
 * Alerts Service
 * API client for price alerts management
 *
 * Backend endpoints: /api/v1/trading/alerts/*
 */

import { apiClient as api } from '../lib/apiClient';

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

/**
 * Alert condition types
 * - above: Price goes above target
 * - below: Price goes below target
 * - crosses_above: Price crosses above target (from below)
 * - crosses_below: Price crosses below target (from above)
 */
export type AlertCondition = 'above' | 'below' | 'crosses_above' | 'crosses_below';

/**
 * Alert status for filtering
 */
export type AlertStatus = 'active' | 'triggered' | 'disabled' | 'expired';

/**
 * Notification channels
 */
export type NotificationChannel = 'email' | 'push' | 'sms' | 'webhook';

/**
 * Price Alert entity
 */
export interface PriceAlert {
  id: string;
  userId: string;
  symbol: string;
  condition: AlertCondition;
  price: number;
  note?: string;
  isActive: boolean;
  triggeredAt?: string;
  triggeredPrice?: number;
  notifyEmail: boolean;
  notifyPush: boolean;
  isRecurring: boolean;
  expiresAt?: string;
  createdAt: string;
  updatedAt: string;
}

/**
 * Input for creating a new alert
 */
export interface CreateAlertInput {
  symbol: string;
  condition: AlertCondition;
  price: number;
  note?: string;
  notifyEmail?: boolean;
  notifyPush?: boolean;
  isRecurring?: boolean;
  expiresAt?: string;
}

/**
 * Input for updating an existing alert
 */
export interface UpdateAlertInput {
  price?: number;
  note?: string;
  notifyEmail?: boolean;
  notifyPush?: boolean;
  isRecurring?: boolean;
  isActive?: boolean;
  expiresAt?: string;
}

/**
 * Filter options for listing alerts
 */
export interface AlertsFilter {
  isActive?: boolean;
  symbol?: string;
  condition?: AlertCondition;
  status?: AlertStatus;
}

/**
 * Alert statistics
 */
export interface AlertStats {
  total: number;
  active: number;
  triggered: number;
  disabled: number;
  expired: number;
}

/**
 * API response wrapper
 */
interface ApiResponse<T> {
  success: boolean;
  data: T;
  error?: string;
}

// ============================================================================
// Alert CRUD Operations
// ============================================================================

/**
 * Get user's price alerts with optional filtering
 *
 * @param filter - Optional filter criteria
 * @returns List of price alerts
 */
export async function getAlerts(filter: AlertsFilter = {}): Promise<PriceAlert[]> {
  try {
    const params: Record<string, string> = {};
    if (filter.isActive !== undefined) params.isActive = String(filter.isActive);
    if (filter.symbol) params.symbol = filter.symbol;
    if (filter.condition) params.condition = filter.condition;
    if (filter.status) params.status = filter.status;

    const response = await api.get<ApiResponse<PriceAlert[]>>('/trading/alerts', { params });
    return response.data.data || response.data as unknown as PriceAlert[];
  } catch (error) {
    console.error('Failed to fetch alerts:', error);
    throw new Error('Failed to fetch alerts');
  }
}

/**
 * Get a specific alert by ID
 *
 * @param alertId - The alert ID
 * @returns The price alert
 */
export async function getAlert(alertId: string): Promise<PriceAlert> {
  try {
    const response = await api.get<ApiResponse<PriceAlert>>(`/trading/alerts/${alertId}`);
    return response.data.data || response.data as unknown as PriceAlert;
  } catch (error) {
    console.error('Failed to fetch alert:', error);
    throw new Error('Failed to fetch alert');
  }
}

/**
 * Create a new price alert
 *
 * @param input - Alert creation data
 * @returns The created price alert
 */
export async function createAlert(input: CreateAlertInput): Promise<PriceAlert> {
  try {
    const response = await api.post<ApiResponse<PriceAlert>>('/trading/alerts', input);
    return response.data.data || response.data as unknown as PriceAlert;
  } catch (error) {
    console.error('Failed to create alert:', error);
    throw new Error('Failed to create alert');
  }
}

/**
 * Update an existing alert
 *
 * @param alertId - The alert ID to update
 * @param data - Fields to update
 * @returns The updated price alert
 */
export async function updateAlert(alertId: string, data: UpdateAlertInput): Promise<PriceAlert> {
  try {
    const response = await api.patch<ApiResponse<PriceAlert>>(`/trading/alerts/${alertId}`, data);
    return response.data.data || response.data as unknown as PriceAlert;
  } catch (error) {
    console.error('Failed to update alert:', error);
    throw new Error('Failed to update alert');
  }
}

/**
 * Delete an alert
 *
 * @param alertId - The alert ID to delete
 */
export async function deleteAlert(alertId: string): Promise<void> {
  try {
    await api.delete(`/trading/alerts/${alertId}`);
  } catch (error) {
    console.error('Failed to delete alert:', error);
    throw new Error('Failed to delete alert');
  }
}

// ============================================================================
// Alert Enable/Disable Operations
// ============================================================================

/**
 * Enable an alert (set isActive to true)
 *
 * @param alertId - The alert ID
 * @returns The updated price alert
 */
export async function enableAlert(alertId: string): Promise<PriceAlert> {
  try {
    const response = await api.post<ApiResponse<PriceAlert>>(`/trading/alerts/${alertId}/enable`);
    return response.data.data || response.data as unknown as PriceAlert;
  } catch (error) {
    console.error('Failed to enable alert:', error);
    throw new Error('Failed to enable alert');
  }
}

/**
 * Disable an alert (set isActive to false)
 *
 * @param alertId - The alert ID
 * @returns The updated price alert
 */
export async function disableAlert(alertId: string): Promise<PriceAlert> {
  try {
    const response = await api.post<ApiResponse<PriceAlert>>(`/trading/alerts/${alertId}/disable`);
    return response.data.data || response.data as unknown as PriceAlert;
  } catch (error) {
    console.error('Failed to disable alert:', error);
    throw new Error('Failed to disable alert');
  }
}

/**
 * Toggle alert enabled/disabled status
 *
 * @param alertId - The alert ID
 * @param enabled - Whether to enable or disable
 * @returns The updated price alert
 */
export async function toggleAlert(alertId: string, enabled: boolean): Promise<PriceAlert> {
  return enabled ? enableAlert(alertId) : disableAlert(alertId);
}

// ============================================================================
// Alert Statistics
// ============================================================================

/**
 * Get alert statistics for the current user
 *
 * @returns Alert statistics (total, active, triggered counts)
 */
export async function getAlertStats(): Promise<AlertStats> {
  try {
    const response = await api.get<ApiResponse<AlertStats>>('/trading/alerts/stats');
    return response.data.data || response.data as unknown as AlertStats;
  } catch (error) {
    console.error('Failed to fetch alert stats:', error);
    throw new Error('Failed to fetch alert stats');
  }
}

// ============================================================================
// Convenience Functions
// ============================================================================

/**
 * Get all active alerts
 *
 * @returns List of active price alerts
 */
export async function getActiveAlerts(): Promise<PriceAlert[]> {
  return getAlerts({ isActive: true });
}

/**
 * Get alerts for a specific symbol
 *
 * @param symbol - Trading symbol (e.g., 'BTCUSDT')
 * @returns List of alerts for the symbol
 */
export async function getAlertsBySymbol(symbol: string): Promise<PriceAlert[]> {
  return getAlerts({ symbol });
}

/**
 * Create a price above alert
 *
 * @param symbol - Trading symbol
 * @param price - Target price
 * @param options - Additional options
 * @returns The created alert
 */
export async function createPriceAboveAlert(
  symbol: string,
  price: number,
  options: Omit<CreateAlertInput, 'symbol' | 'condition' | 'price'> = {}
): Promise<PriceAlert> {
  return createAlert({
    symbol,
    condition: 'above',
    price,
    ...options,
  });
}

/**
 * Create a price below alert
 *
 * @param symbol - Trading symbol
 * @param price - Target price
 * @param options - Additional options
 * @returns The created alert
 */
export async function createPriceBelowAlert(
  symbol: string,
  price: number,
  options: Omit<CreateAlertInput, 'symbol' | 'condition' | 'price'> = {}
): Promise<PriceAlert> {
  return createAlert({
    symbol,
    condition: 'below',
    price,
    ...options,
  });
}

/**
 * Delete all alerts for a specific symbol
 *
 * @param symbol - Trading symbol
 */
export async function deleteAlertsBySymbol(symbol: string): Promise<void> {
  const alerts = await getAlertsBySymbol(symbol);
  await Promise.all(alerts.map(alert => deleteAlert(alert.id)));
}

/**
 * Disable all alerts for a specific symbol
 *
 * @param symbol - Trading symbol
 */
export async function disableAlertsBySymbol(symbol: string): Promise<void> {
  const alerts = await getAlertsBySymbol(symbol);
  await Promise.all(
    alerts
      .filter(alert => alert.isActive)
      .map(alert => disableAlert(alert.id))
  );
}

// ============================================================================
// Export
// ============================================================================

export const alertsService = {
  // CRUD
  getAlerts,
  getAlert,
  createAlert,
  updateAlert,
  deleteAlert,

  // Enable/Disable
  enableAlert,
  disableAlert,
  toggleAlert,

  // Statistics
  getAlertStats,

  // Convenience
  getActiveAlerts,
  getAlertsBySymbol,
  createPriceAboveAlert,
  createPriceBelowAlert,
  deleteAlertsBySymbol,
  disableAlertsBySymbol,
};

export default alertsService;
