/**
 * Configuration Module
 *
 * Manages environment variables and creates Binance clients via CCXT.
 *
 * @version 1.0.0
 * @author Trading Platform Trading Platform
 */

import ccxt from 'ccxt';
import dotenv from 'dotenv';

// Load environment variables
dotenv.config();

// ==========================================
// Configuration Interface
// ==========================================

export interface BinanceConfig {
  apiKey: string;
  apiSecret: string;
  testnet: boolean;
  futuresTestnet: boolean;
  timeout: number;
}

export interface RiskConfig {
  maxOrderValueUsdt: number;
  maxDailyVolumeUsdt: number;
  maxLeverage: number;
  maxPositionSizePct: number;
}

export interface ServerConfig {
  port: number;
  nodeEnv: string;
  mcpApiKey: string;
  logLevel: string;
}

// ==========================================
// Configuration Loading
// ==========================================

export const binanceConfig: BinanceConfig = {
  apiKey: process.env.BINANCE_API_KEY || '',
  apiSecret: process.env.BINANCE_API_SECRET || '',
  testnet: process.env.BINANCE_TESTNET === 'true',
  futuresTestnet: process.env.BINANCE_FUTURES_TESTNET === 'true',
  timeout: parseInt(process.env.REQUEST_TIMEOUT || '10000', 10),
};

export const riskConfig: RiskConfig = {
  maxOrderValueUsdt: parseFloat(process.env.MAX_ORDER_VALUE_USDT || '1000'),
  maxDailyVolumeUsdt: parseFloat(process.env.MAX_DAILY_VOLUME_USDT || '10000'),
  maxLeverage: parseInt(process.env.MAX_LEVERAGE || '20', 10),
  maxPositionSizePct: parseFloat(process.env.MAX_POSITION_SIZE_PCT || '5'),
};

export const serverConfig: ServerConfig = {
  port: parseInt(process.env.PORT || '3606', 10),
  nodeEnv: process.env.NODE_ENV || 'development',
  mcpApiKey: process.env.MCP_API_KEY || '',
  logLevel: process.env.LOG_LEVEL || 'info',
};

// ==========================================
// Binance Client Factory
// ==========================================

/**
 * Create a Binance Spot client
 */
export function createBinanceSpotClient(): ccxt.binance {
  const isTestnet = binanceConfig.testnet;

  const client = new ccxt.binance({
    apiKey: binanceConfig.apiKey,
    secret: binanceConfig.apiSecret,
    sandbox: isTestnet,
    options: {
      defaultType: 'spot',
      adjustForTimeDifference: true,
    },
    enableRateLimit: true,
    rateLimit: 100,
    timeout: binanceConfig.timeout,
  });

  return client;
}

/**
 * Create a Binance Futures client
 */
export function createBinanceFuturesClient(): ccxt.binance {
  const isTestnet = binanceConfig.futuresTestnet;

  const client = new ccxt.binance({
    apiKey: binanceConfig.apiKey,
    secret: binanceConfig.apiSecret,
    sandbox: isTestnet,
    options: {
      defaultType: 'future',
      adjustForTimeDifference: true,
    },
    enableRateLimit: true,
    rateLimit: 100,
    timeout: binanceConfig.timeout,
  });

  return client;
}

// ==========================================
// Configuration Validation
// ==========================================

export function validateConfig(): { valid: boolean; errors: string[] } {
  const errors: string[] = [];

  // Binance API keys are optional for public endpoints
  // but required for account/trading operations
  if (!binanceConfig.apiKey && serverConfig.nodeEnv === 'production') {
    errors.push('BINANCE_API_KEY is required in production');
  }

  if (!binanceConfig.apiSecret && serverConfig.nodeEnv === 'production') {
    errors.push('BINANCE_API_SECRET is required in production');
  }

  // Validate risk limits
  if (riskConfig.maxOrderValueUsdt <= 0) {
    errors.push('MAX_ORDER_VALUE_USDT must be positive');
  }

  if (riskConfig.maxLeverage < 1 || riskConfig.maxLeverage > 125) {
    errors.push('MAX_LEVERAGE must be between 1 and 125');
  }

  return {
    valid: errors.length === 0,
    errors,
  };
}

// ==========================================
// Exports
// ==========================================

export default {
  binance: binanceConfig,
  risk: riskConfig,
  server: serverConfig,
  createBinanceSpotClient,
  createBinanceFuturesClient,
  validateConfig,
};
