/**
 * Setup Personal Configuration Script
 * Initializes the trading platform with personal configuration from config.yaml
 *
 * Usage: npx ts-node scripts/setup-personal.ts
 */

import * as fs from 'fs';
import * as path from 'path';
import * as yaml from 'js-yaml';

interface AdminConfig {
  email: string;
  first_name: string;
  last_name: string;
  display_name: string;
  role: string;
  status: string;
  profile: {
    timezone: string;
    language: string;
    preferred_currency: string;
  };
  settings: {
    theme: string;
    email_notifications: boolean;
    signal_alerts: boolean;
    portfolio_alerts: boolean;
  };
}

interface RiskProfile {
  profile: string;
  max_risk_percent: number;
  max_positions: number;
  max_daily_trades: number;
  max_drawdown_tolerance: number;
  experience_level: number;
}

interface PriorityAsset {
  symbol: string;
  name: string;
  asset_class: string;
  base_currency: string;
  quote_currency: string;
  pip_value: number;
  lot_size: number;
  min_lot: number;
  max_lot: number;
  is_active: boolean;
  data_provider: string;
  priority: number;
}

interface TradingAgent {
  name: string;
  slug: string;
  description: string;
  risk_profile: string;
  target_monthly_return: number;
  max_drawdown: number;
  max_position_size: number;
  supported_symbols: string[];
  default_timeframe: string;
  min_confidence: number;
  strategy_type: string;
  risk_reward_ratio: number;
  uses_amd: boolean;
  favorable_phases: string[];
  status: string;
  is_public: boolean;
}

interface PaperTrading {
  enabled: boolean;
  initial_balance: number;
  currency: string;
  name: string;
}

interface PersonalConfig {
  admin: AdminConfig;
  risk_profile: RiskProfile;
  priority_assets: PriorityAsset[];
  trading_agents: TradingAgent[];
  default_watchlist: {
    name: string;
    is_default: boolean;
    symbols: { symbol: string; notes: string }[];
  };
  paper_trading: PaperTrading;
  ml_models: {
    auto_retrain: boolean;
    retrain_interval_days: number;
    preferred_models: Record<string, string>;
    thresholds: {
      min_confidence: number;
      min_tp_probability: number;
    };
  };
  system: {
    auto_trade_enabled: boolean;
    auto_trade_require_confirmation: boolean;
    max_concurrent_analysis: number;
    log_level: string;
    cache_predictions: boolean;
    cache_ttl_minutes: number;
  };
}

const CONFIG_PATH = path.join(__dirname, '..', 'config.yaml');
const API_URL = process.env.API_URL || 'http://localhost:3081';

async function loadConfig(): Promise<PersonalConfig> {
  const configFile = fs.readFileSync(CONFIG_PATH, 'utf8');
  return yaml.load(configFile) as PersonalConfig;
}

async function apiCall(endpoint: string, method: string = 'GET', body?: unknown): Promise<unknown> {
  const response = await fetch(`${API_URL}${endpoint}`, {
    method,
    headers: {
      'Content-Type': 'application/json',
    },
    body: body ? JSON.stringify(body) : undefined,
  });

  if (!response.ok) {
    const error = await response.text();
    throw new Error(`API Error ${response.status}: ${error}`);
  }

  return response.json();
}

async function setupAdmin(config: AdminConfig): Promise<void> {
  console.log('Setting up admin account...');

  try {
    await apiCall('/api/v1/admin/setup', 'POST', {
      email: config.email,
      first_name: config.first_name,
      last_name: config.last_name,
      display_name: config.display_name,
      role: config.role,
      profile: config.profile,
      settings: config.settings,
    });
    console.log(`  Admin account created: ${config.email}`);
  } catch (error) {
    console.log(`  Admin setup skipped (may already exist): ${(error as Error).message}`);
  }
}

async function setupAssets(assets: PriorityAsset[]): Promise<void> {
  console.log('\nSetting up priority assets...');

  for (const asset of assets) {
    try {
      await apiCall('/api/v1/trading/symbols', 'POST', asset);
      console.log(`  Added: ${asset.symbol} (${asset.name})`);
    } catch (error) {
      console.log(`  Skipped ${asset.symbol}: ${(error as Error).message}`);
    }
  }
}

async function setupAgents(agents: TradingAgent[]): Promise<void> {
  console.log('\nSetting up trading agents...');

  for (const agent of agents) {
    try {
      await apiCall('/api/v1/agents', 'POST', {
        name: agent.name,
        slug: agent.slug,
        description: agent.description,
        risk_profile: agent.risk_profile,
        config: {
          target_monthly_return: agent.target_monthly_return,
          max_drawdown: agent.max_drawdown,
          max_position_size: agent.max_position_size,
          supported_symbols: agent.supported_symbols,
          default_timeframe: agent.default_timeframe,
          min_confidence: agent.min_confidence,
          strategy_type: agent.strategy_type,
          risk_reward_ratio: agent.risk_reward_ratio,
          uses_amd: agent.uses_amd,
          favorable_phases: agent.favorable_phases,
        },
        status: agent.status,
        is_public: agent.is_public,
      });
      console.log(`  Created agent: ${agent.name} (${agent.risk_profile})`);
    } catch (error) {
      console.log(`  Skipped ${agent.name}: ${(error as Error).message}`);
    }
  }
}

async function setupPaperTrading(config: PaperTrading): Promise<void> {
  console.log('\nSetting up paper trading account...');

  if (!config.enabled) {
    console.log('  Paper trading disabled in config');
    return;
  }

  try {
    await apiCall('/api/v1/investment/accounts', 'POST', {
      name: config.name,
      type: 'paper',
      initial_balance: config.initial_balance,
      currency: config.currency,
    });
    console.log(`  Paper account created: ${config.name} (${config.currency} ${config.initial_balance})`);
  } catch (error) {
    console.log(`  Skipped paper account: ${(error as Error).message}`);
  }
}

async function setupWatchlist(config: PersonalConfig['default_watchlist']): Promise<void> {
  console.log('\nSetting up default watchlist...');

  try {
    await apiCall('/api/v1/trading/watchlists', 'POST', {
      name: config.name,
      is_default: config.is_default,
      symbols: config.symbols.map(s => s.symbol),
    });
    console.log(`  Watchlist created: ${config.name}`);
  } catch (error) {
    console.log(`  Skipped watchlist: ${(error as Error).message}`);
  }
}

async function printSummary(config: PersonalConfig): Promise<void> {
  console.log('\n' + '='.repeat(60));
  console.log('SETUP SUMMARY');
  console.log('='.repeat(60));
  console.log(`\nAdmin Account: ${config.admin.email}`);
  console.log(`Role: ${config.admin.role}`);
  console.log(`\nPriority Assets (${config.priority_assets.length}):`);
  config.priority_assets.forEach(a => {
    console.log(`  ${a.priority}. ${a.symbol} - ${a.name} (${a.data_provider})`);
  });
  console.log(`\nTrading Agents (${config.trading_agents.length}):`);
  config.trading_agents.forEach(a => {
    console.log(`  - ${a.name} [${a.status}] - ${a.risk_profile} (${a.strategy_type})`);
  });
  console.log(`\nPaper Trading: ${config.paper_trading.enabled ? 'Enabled' : 'Disabled'}`);
  if (config.paper_trading.enabled) {
    console.log(`  Balance: ${config.paper_trading.currency} ${config.paper_trading.initial_balance}`);
  }
  console.log(`\nSystem Settings:`);
  console.log(`  Auto Trade: ${config.system.auto_trade_enabled ? 'Enabled' : 'Disabled'}`);
  console.log(`  Require Confirmation: ${config.system.auto_trade_require_confirmation}`);
  console.log(`  Cache Predictions: ${config.system.cache_predictions}`);
  console.log('\n' + '='.repeat(60));
}

async function main(): Promise<void> {
  console.log('='.repeat(60));
  console.log('OrbiQuant IA - Personal Setup');
  console.log('='.repeat(60));
  console.log(`\nLoading config from: ${CONFIG_PATH}`);

  try {
    const config = await loadConfig();
    console.log('Config loaded successfully!\n');

    // Check API availability
    try {
      await apiCall('/health');
      console.log('API is available.\n');
    } catch {
      console.log('\nWARNING: API is not available. Running in dry-run mode.');
      console.log('Start the backend server to apply configuration.\n');
      await printSummary(config);
      return;
    }

    // Run setup steps
    await setupAdmin(config.admin);
    await setupAssets(config.priority_assets);
    await setupAgents(config.trading_agents);
    await setupPaperTrading(config.paper_trading);
    await setupWatchlist(config.default_watchlist);

    await printSummary(config);

    console.log('\nSetup completed successfully!');
    console.log('\nNext steps:');
    console.log('  1. Start the frontend: cd ../frontend && npm run dev');
    console.log('  2. Access admin dashboard: http://localhost:3080/admin');
    console.log('  3. Login with: ' + config.admin.email);

  } catch (error) {
    console.error('\nSetup failed:', (error as Error).message);
    process.exit(1);
  }
}

main();
