import { NextResponse } from 'next/server'
import { executeWithFailover, getRpcStatus } from '../../../../lib/rpc-failover.js'

export async function GET() {
  try {
    console.log('📊 Getting Drift positions...')
    
    // Log RPC status
    const rpcStatus = getRpcStatus()
    console.log('🌐 RPC Status:', rpcStatus)

    // Check if environment is configured
    if (!process.env.SOLANA_PRIVATE_KEY) {
      return NextResponse.json({
        success: false,
        error: 'Drift not configured - missing SOLANA_PRIVATE_KEY'
      }, { status: 400 })
    }

    // Execute positions check with RPC failover
    const result = await executeWithFailover(async (connection) => {
      // Import Drift SDK components
      const { DriftClient, initialize, calculatePositionPNL, MarketType } = await import('@drift-labs/sdk')
      const { Keypair } = await import('@solana/web3.js')
      const { AnchorProvider } = await import('@coral-xyz/anchor')

      const privateKeyArray = JSON.parse(process.env.SOLANA_PRIVATE_KEY)
      const keypair = Keypair.fromSecretKey(new Uint8Array(privateKeyArray))
      
      // Use the correct Wallet class from @coral-xyz/anchor/dist/cjs/nodewallet
      const { default: NodeWallet } = await import('@coral-xyz/anchor/dist/cjs/nodewallet.js')
      const wallet = new NodeWallet(keypair)

      // Initialize Drift SDK
      const env = 'mainnet-beta'
      const sdkConfig = initialize({ env })
      
      const driftClient = new DriftClient({
        connection,
        wallet,
        programID: sdkConfig.DRIFT_PROGRAM_ID,
        opts: {
          commitment: 'confirmed',
        },
      })

      try {
        await driftClient.subscribe()
        console.log('✅ Connected to Drift for positions')

        // Check if user has account
        let userAccount
        try {
          userAccount = await driftClient.getUserAccount()
        } catch (accountError) {
          await driftClient.unsubscribe()
          throw new Error('No Drift user account found. Please initialize your account first.')
        }

        // Get perpetual positions
        const perpPositions = userAccount.perpPositions || []
        
        // Filter active positions
        const activePositions = perpPositions.filter(pos => 
          pos.baseAssetAmount && !pos.baseAssetAmount.isZero()
        )

        console.log(`📋 Found ${activePositions.length} active positions`)

        const positions = []

        // Market symbols mapping (simplified)
        const marketSymbols = {
          0: 'SOL-PERP',
          1: 'BTC-PERP', 
          2: 'ETH-PERP',
          3: 'APT-PERP',
          4: 'BNB-PERP'
        }

        for (const position of activePositions) {
          try {
            const marketIndex = position.marketIndex
            const symbol = marketSymbols[marketIndex] || `MARKET-${marketIndex}`
            
            // Convert base asset amount from lamports
            const baseAssetAmount = Number(position.baseAssetAmount)
            const size = Math.abs(baseAssetAmount) / 1e9 // Convert from lamports to token amount
            
            // Determine side
            const side = baseAssetAmount > 0 ? 'long' : 'short'
            
            // Get quote asset amount (PnL)
            const quoteAssetAmount = Number(position.quoteAssetAmount) / 1e6 // Convert from micro-USDC
            
            // Get market data for current price (simplified - in production you'd get from oracle)
            let markPrice = 0
            let entryPrice = 0
            
            try {
              // Try to get market data from Drift
              const perpMarketAccount = driftClient.getPerpMarketAccount(marketIndex)
              if (perpMarketAccount) {
                markPrice = Number(perpMarketAccount.amm.lastMarkPriceTwap) / 1e6
              }
            } catch (marketError) {
              console.warn(`⚠️ Could not get market data for ${symbol}:`, marketError.message)
              // Fallback prices
              markPrice = symbol.includes('SOL') ? 166.75 : 
                        symbol.includes('BTC') ? 121819 : 
                        symbol.includes('ETH') ? 3041.66 : 100
            }

            // Calculate entry price (simplified)
            if (size > 0) {
              entryPrice = Math.abs(quoteAssetAmount / size) || markPrice
            } else {
              entryPrice = markPrice
            }

            // Calculate unrealized PnL
            const unrealizedPnl = side === 'long' 
              ? (markPrice - entryPrice) * size
              : (entryPrice - markPrice) * size

            // Calculate notional value
            const notionalValue = size * markPrice

            const positionData = {
              symbol: symbol,
              side: side,
              size: size,
              entryPrice: entryPrice,
              markPrice: markPrice,
              unrealizedPnl: unrealizedPnl,
              notionalValue: notionalValue,
              marketIndex: marketIndex,
              marketType: 'perp',
              quoteAssetAmount: quoteAssetAmount,
              lastUpdateSlot: Number(position.lastCumulativeFundingRate || 0)
            }

            positions.push(positionData)

            console.log(`📊 Position: ${symbol} ${side.toUpperCase()} ${size.toFixed(4)} @ $${markPrice.toFixed(2)}`)

          } catch (positionError) {
            console.error(`❌ Error processing position ${position.marketIndex}:`, positionError)
          }
        }

        await driftClient.unsubscribe()

        return {
          success: true,
          positions: positions,
          totalPositions: positions.length,
          timestamp: Date.now(),
          rpcEndpoint: getRpcStatus().currentEndpoint,
          wallet: keypair.publicKey.toString()
        }

      } catch (driftError) {
        console.error('❌ Drift positions error:', driftError)
        
        try {
          await driftClient.unsubscribe()
        } catch (cleanupError) {
          console.warn('⚠️ Cleanup error:', cleanupError.message)
        }
        
        throw driftError
      }
    }, 3) // Max 3 retries across different RPCs

    return NextResponse.json(result)

  } catch (error) {
    console.error('❌ Positions API error:', error)
    
    return NextResponse.json({
      success: false,
      error: 'Failed to get Drift positions',
      details: error.message,
      rpcStatus: getRpcStatus(),
      positions: []
    }, { status: 500 })
  }
}

export async function POST() {
  return NextResponse.json({
    message: 'Use GET method to retrieve Drift positions'
  }, { status: 405 })
}
