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

export async function GET() {
  try {
    console.log('💰 Getting Drift account balance...')
    
    // 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 balance check with RPC failover
    const result = await executeWithFailover(async (connection) => {
      // Import Drift SDK components
      const { DriftClient, initialize, calculateFreeCollateral, calculatePositionPNL, QUOTE_PRECISION } = await import('@drift-labs/sdk')
      const { Keypair } = await import('@solana/web3.js')
      const { AnchorProvider, BN } = 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 balance check')

        // 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 account balances and positions using Drift's built-in methods
        const spotBalances = userAccount.spotPositions || []
        const perpPositions = userAccount.perpPositions || []

        // Use Drift's built-in calculation methods for accuracy
        let totalCollateral = 0
        let unrealizedPnl = 0
        let marginRequirement = 0

        try {
          // Calculate total collateral using Drift's method
          totalCollateral = await driftClient.getUser().getTotalCollateral() / 1e6 // Convert to USDC
        } catch (collateralError) {
          console.warn('⚠️ Could not get total collateral, calculating manually:', collateralError.message)
          
          // Fallback to manual USDC balance calculation
          const usdcBalance = spotBalances.find(pos => pos.marketIndex === 0)
          if (usdcBalance) {
            totalCollateral = Number(usdcBalance.scaledBalance) / 1e6 // Assume 6 decimal precision for USDC
          }
        }

        try {
          // Calculate unrealized PnL using Drift's method
          unrealizedPnl = await driftClient.getUser().getUnrealizedPNL() / 1e6 // Convert to USDC
        } catch (pnlError) {
          console.warn('⚠️ Could not get unrealized PnL, calculating manually:', pnlError.message)
          unrealizedPnl = 0 // Default to 0 if we can't calculate
        }

        let freeCollateralFromDrift = 0
        try {
          // Calculate margin requirement using proper Drift SDK methods
          freeCollateralFromDrift = await driftClient.getUser().getFreeCollateral() / 1e6 // Convert to USDC
          marginRequirement = Math.max(0, totalCollateral - freeCollateralFromDrift) // Used collateral
        } catch (marginError) {
          console.warn('⚠️ Could not get margin requirement, calculating manually:', marginError.message)
          marginRequirement = 0 // Default to 0 if we can't calculate
        }

        // Calculate free collateral and other derived values
        // Use Drift's free collateral if available, otherwise calculate manually
        const freeCollateral = freeCollateralFromDrift > 0 ? freeCollateralFromDrift : Math.max(0, totalCollateral - marginRequirement + unrealizedPnl)
        const accountValue = totalCollateral + unrealizedPnl
        const leverage = marginRequirement > 0 ? (marginRequirement / accountValue) : 0
        const availableBalance = Math.max(0, freeCollateral)

        // Count active positions
        const activePositions = perpPositions.filter(pos => 
          pos.baseAssetAmount && !pos.baseAssetAmount.isZero()
        )

        const balanceResult = {
          success: true,
          totalCollateral: totalCollateral,
          freeCollateral: freeCollateral,
          marginRequirement: marginRequirement,
          unrealizedPnl: unrealizedPnl,
          accountValue: accountValue,
          leverage: leverage,
          availableBalance: availableBalance,
          activePositionsCount: activePositions.length,
          timestamp: Date.now(),
          rpcEndpoint: getRpcStatus().currentEndpoint,
          details: {
            spotBalances: spotBalances.length,
            perpPositions: activePositions.length,
            wallet: keypair.publicKey.toString()
          }
        }

        await driftClient.unsubscribe()
        
        console.log('💰 Balance retrieved:', {
          totalCollateral: totalCollateral.toFixed(2),
          availableBalance: availableBalance.toFixed(2),
          positions: activePositions.length,
          rpcEndpoint: getRpcStatus().currentEndpoint
        })

        return balanceResult

      } catch (driftError) {
        console.error('❌ Drift balance 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('❌ Balance API error:', error)
    
    return NextResponse.json({
      success: false,
      error: 'Failed to get Drift account balance',
      details: error.message,
      rpcStatus: getRpcStatus()
    }, { status: 500 })
  }
}

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