/**
 * Position Scaling DCA API - Proper DCA Implementation
 * 
 * This API increases existing position size and adjusts SL/TP levels
 * instead of creating multiple fragmented orders.
 */

import { NextResponse } from 'next/server';
import { Connection, Keypair } from '@solana/web3.js';
import { Wallet } from '@project-serum/anchor';
import { 
  DriftClient, 
  PositionDirection, 
  OrderType, 
  OrderTriggerCondition,
  MarketType
} from '@drift-labs/sdk';
import { BN } from '@project-serum/anchor';
import { initialize } from '@drift-labs/sdk';

export async function POST(request) {
  try {
    const { 
      dcaAmount,          // Additional amount to add (in USD)
      analysis = null     // Optional AI analysis for optimal levels
    } = await request.json();

    console.log('🎯 POSITION SCALING DCA STARTED');
    console.log(`💰 Adding $${dcaAmount} to existing position`);

    // 1. Get current position
    const positionResponse = await fetch(`${process.env.INTERNAL_API_URL || 'http://localhost:3000'}/api/drift/positions`);
    const positionData = await positionResponse.json();
    
    if (!positionData.success || positionData.positions.length === 0) {
      return NextResponse.json({
        success: false,
        error: 'No existing position found to scale'
      }, { status: 400 });
    }

    const currentPosition = positionData.positions[0];
    console.log(`📊 Current position: ${currentPosition.side} ${currentPosition.size} ${currentPosition.symbol} @ $${currentPosition.entryPrice}`);

    // 2. Initialize Drift client
    const connection = new Connection(process.env.HELIUS_RPC_URL);
    const privateKeyArray = JSON.parse(process.env.SOLANA_PRIVATE_KEY);
    const keypair = Keypair.fromSecretKey(new Uint8Array(privateKeyArray));
    const wallet = new Wallet(keypair);
    
    const sdkConfig = initialize({ env: 'mainnet-beta' });
    const driftClient = new DriftClient({
      connection,
      wallet,
      programID: sdkConfig.DRIFT_PROGRAM_ID,
      opts: { 
        commitment: 'confirmed',
        skipPreflight: false,
        preflightCommitment: 'confirmed'
      }
    });

    await driftClient.subscribe();
    console.log('✅ Connected to Drift Protocol');

    // 3. Get current market price and calculate DCA parameters
    const marketIndex = 0; // SOL-PERP
    const perpMarketAccount = driftClient.getPerpMarketAccount(marketIndex);
    const currentPrice = Number(perpMarketAccount.amm.lastMarkPriceTwap) / 1e6;
    
    console.log(`📈 Current market price: $${currentPrice.toFixed(4)}`);

    // 4. Calculate new averaged position
    const currentPositionValue = currentPosition.size * currentPosition.entryPrice;
    const dcaPositionSize = dcaAmount / currentPrice;
    const dcaPositionValue = dcaPositionSize * currentPrice;
    
    const newTotalSize = currentPosition.size + dcaPositionSize;
    const newAveragePrice = (currentPositionValue + dcaPositionValue) / newTotalSize;
    
    console.log('🧮 Position scaling calculation:');
    console.log(`   Current: ${currentPosition.size.toFixed(4)} @ $${currentPosition.entryPrice.toFixed(4)} = $${currentPositionValue.toFixed(2)}`);
    console.log(`   DCA Add: ${dcaPositionSize.toFixed(4)} @ $${currentPrice.toFixed(4)} = $${dcaPositionValue.toFixed(2)}`);
    console.log(`   New Total: ${newTotalSize.toFixed(4)} @ $${newAveragePrice.toFixed(4)} = $${(newTotalSize * newAveragePrice).toFixed(2)}`);

    // 5. Cancel existing stop loss and take profit orders
    console.log('🧹 Canceling existing SL/TP orders...');
    try {
      const ordersResponse = await fetch(`${process.env.INTERNAL_API_URL || 'http://localhost:3000'}/api/drift/orders`);
      const ordersData = await ordersResponse.json();
      
      if (ordersData.success && ordersData.orders.length > 0) {
        // Find and cancel reduce-only orders (SL/TP)
        const reduceOnlyOrders = ordersData.orders.filter(order => 
          order.reduceOnly && order.status === 'OPEN'
        );
        
        console.log(`   Found ${reduceOnlyOrders.length} existing SL/TP orders to cancel`);
        
        for (const order of reduceOnlyOrders) {
          try {
            await driftClient.cancelOrder(order.orderId);
            console.log(`   ✅ Canceled order: ${order.orderType} @ $${order.triggerPrice}`);
          } catch (cancelError) {
            console.warn(`   ⚠️ Failed to cancel order ${order.orderId}:`, cancelError.message);
          }
        }
      }
    } catch (ordersError) {
      console.warn('⚠️ Error fetching/canceling orders:', ordersError.message);
    }

    // 6. Place DCA order to increase position
    const dcaBaseAssetAmount = Math.floor(dcaPositionSize * 1e9); // Convert to base units
    const direction = currentPosition.side.toLowerCase() === 'long' ? PositionDirection.LONG : PositionDirection.SHORT;
    
    console.log(`📈 Placing DCA order: ${direction === PositionDirection.LONG ? 'LONG' : 'SHORT'} ${dcaPositionSize.toFixed(4)} SOL`);
    
    const dcaOrderParams = {
      orderType: OrderType.MARKET,
      marketType: MarketType.PERP,
      direction,
      baseAssetAmount: new BN(dcaBaseAssetAmount),
      marketIndex,
    };

    const dcaTxSig = await driftClient.placeAndTakePerpOrder(dcaOrderParams);
    console.log('✅ DCA position increase executed:', dcaTxSig);

    // Wait for order to settle
    await new Promise(resolve => setTimeout(resolve, 3000));

    // 7. Calculate new stop loss and take profit levels
    let newStopLoss, newTakeProfit;
    
    if (analysis && analysis.stopLoss && analysis.takeProfits) {
      // Use AI-calculated levels if available
      console.log('🧠 Using AI-calculated optimal levels');
      newStopLoss = analysis.stopLoss.price || analysis.stopLoss;
      newTakeProfit = analysis.takeProfits.tp1?.price || analysis.takeProfits.tp1 || analysis.takeProfit;
    } else {
      // Calculate adaptive levels based on new average price
      console.log('📊 Calculating adaptive levels for new average price');
      const stopLossPercent = 2.0; // 2% stop loss
      const takeProfitPercent = 4.0; // 4% take profit
      
      if (direction === PositionDirection.LONG) {
        newStopLoss = newAveragePrice * (1 - stopLossPercent / 100);
        newTakeProfit = newAveragePrice * (1 + takeProfitPercent / 100);
      } else {
        newStopLoss = newAveragePrice * (1 + stopLossPercent / 100);
        newTakeProfit = newAveragePrice * (1 - takeProfitPercent / 100);
      }
    }

    console.log('🎯 New risk management levels:');
    console.log(`   Stop Loss: $${newStopLoss.toFixed(4)}`);
    console.log(`   Take Profit: $${newTakeProfit.toFixed(4)}`);

    // 8. Place new stop loss order for entire scaled position
    let stopLossTx = null;
    if (newStopLoss) {
      try {
        console.log('🛡️ Placing new stop loss for scaled position...');
        
        const stopLossParams = {
          orderType: OrderType.TRIGGER_LIMIT,
          marketType: MarketType.PERP,
          direction: direction === PositionDirection.LONG ? PositionDirection.SHORT : PositionDirection.LONG,
          baseAssetAmount: new BN(Math.floor(newTotalSize * 1e9)), // Full position size
          price: new BN(Math.floor(newStopLoss * 0.995 * 1e6)), // 0.5% slippage buffer
          marketIndex,
          triggerPrice: new BN(Math.floor(newStopLoss * 1e6)),
          triggerCondition: direction === PositionDirection.LONG ? OrderTriggerCondition.BELOW : OrderTriggerCondition.ABOVE,
          reduceOnly: true,
        };

        stopLossTx = await driftClient.placePerpOrder(stopLossParams);
        console.log('✅ New stop loss placed:', stopLossTx);
      } catch (slError) {
        console.warn('⚠️ Stop loss placement failed:', slError.message);
      }
    }

    // 9. Place new take profit order for entire scaled position
    let takeProfitTx = null;
    if (newTakeProfit) {
      try {
        console.log('🎯 Placing new take profit for scaled position...');
        
        const takeProfitParams = {
          orderType: OrderType.TRIGGER_LIMIT,
          marketType: MarketType.PERP,
          direction: direction === PositionDirection.LONG ? PositionDirection.SHORT : PositionDirection.LONG,
          baseAssetAmount: new BN(Math.floor(newTotalSize * 1e9)), // Full position size
          price: new BN(Math.floor(newTakeProfit * 1.005 * 1e6)), // 0.5% slippage buffer
          marketIndex,
          triggerPrice: new BN(Math.floor(newTakeProfit * 1e6)),
          triggerCondition: direction === PositionDirection.LONG ? OrderTriggerCondition.ABOVE : OrderTriggerCondition.BELOW,
          reduceOnly: true,
        };

        takeProfitTx = await driftClient.placePerpOrder(takeProfitParams);
        console.log('✅ New take profit placed:', takeProfitTx);
      } catch (tpError) {
        console.warn('⚠️ Take profit placement failed:', tpError.message);
      }
    }

    await driftClient.unsubscribe();

    // 10. Return success result
    return NextResponse.json({
      success: true,
      message: 'Position successfully scaled with DCA',
      scalingResult: {
        dcaTxId: dcaTxSig,
        stopLossTxId: stopLossTx,
        takeProfitTxId: takeProfitTx,
        
        // Original position
        originalSize: currentPosition.size,
        originalEntryPrice: currentPosition.entryPrice,
        originalValue: currentPositionValue,
        
        // DCA addition
        dcaSize: dcaPositionSize,
        dcaPrice: currentPrice,
        dcaValue: dcaPositionValue,
        
        // New scaled position
        newTotalSize: newTotalSize,
        newAveragePrice: newAveragePrice,
        newTotalValue: newTotalSize * newAveragePrice,
        
        // New risk management
        newStopLoss: newStopLoss,
        newTakeProfit: newTakeProfit,
        
        // AI data
        usedAILevels: !!(analysis && analysis.stopLoss && analysis.takeProfits),
        aiAnalysis: analysis ? {
          confidence: analysis.confidence,
          reasoning: analysis.reasoning || analysis.summary
        } : null
      }
    });

  } catch (error) {
    console.error('❌ Position scaling DCA failed:', error.message);
    return NextResponse.json({
      success: false,
      error: `Position scaling failed: ${error.message}`,
      details: error.stack
    }, { status: 500 });
  }
}
