import { Connection, PublicKey } from '@solana/web3.js';

// Types
export interface TradingBalance {
  totalValue: number;
  availableBalance: number;
  marginUsed: number;
  unrealizedPnl: number;
  positions: {
    symbol: string;
    size: number;
    notionalValue: number;
    unrealizedPnl: number;
    side: 'long' | 'short';
  }[];
}

export interface Position {
  symbol: string;
  side: 'long' | 'short';
  size: number;
  entryPrice: number;
  markPrice: number;
  unrealizedPnl: number;
  notionalValue: number;
}

export interface OrderRequest {
  symbol: string;
  side: 'buy' | 'sell';
  type: 'market' | 'limit';
  amount: number;
  price?: number;
}

export interface OrderResponse {
  success: boolean;
  orderId?: string;
  error?: string;
}

class DriftTradingService {
  private connection: Connection;
  private readonly accountPDA = '7LonnWut5i3h36xyMA5jbwnGFbnzXUPY2dsPfNaSsrTk';

  constructor() {
    this.connection = new Connection(
      process.env.SOLANA_RPC_URL || 'https://api.mainnet-beta.solana.com',
      'confirmed'
    );
  }

  async initialize(): Promise<void> {
    console.log('🚀 Initializing Direct Drift Trading Service...');
    console.log('✅ Direct service ready - no SDK subscriptions needed');
  }

  private async getAccountData(): Promise<Buffer> {
    try {
      const accountInfo = await this.connection.getAccountInfo(
        new PublicKey(this.accountPDA)
      );
      
      if (!accountInfo) {
        throw new Error('Account not found');
      }

      return accountInfo.data;
    } catch (error) {
      console.error('❌ Failed to fetch account data:', error);
      throw error;
    }
  }

  private parseAccountData(data: Buffer) {
    try {
      // Extract USDC balance at offset 106
      const usdcBalance = data.readBigInt64LE(106);
      const usdcValue = Number(usdcBalance) / 1_000_000; // USDC has 6 decimals

      // Extract SOL position at offset 432 (most current/accurate location)
      const solPosition = data.readBigInt64LE(432);
      const solAmount = Number(solPosition) / 1_000_000_000; // SOL has 9 decimals

      // Estimate SOL price (you could fetch this from an oracle)
      const solPrice = 17.11; // Current approximate price
      const solValue = solAmount * solPrice;

      const totalValue = usdcValue + solValue;

      console.log(`💰 Parsed account data:`);
      console.log(`   USDC Balance: $${usdcValue.toFixed(2)}`);
      console.log(`   SOL Position: ${solAmount.toFixed(6)} SOL`);
      console.log(`   SOL Value: $${solValue.toFixed(2)} (@ $${solPrice})`);
      console.log(`   Total Value: $${totalValue.toFixed(2)}`);

      return {
        usdcBalance: usdcValue,
        solPosition: solAmount,
        solPrice,
        solValue,
        totalValue
      };
    } catch (error) {
      console.error('❌ Failed to parse account data:', error);
      throw error;
    }
  }

  async getTradingBalance(): Promise<TradingBalance> {
    try {
      const data = await this.getAccountData();
      const parsed = this.parseAccountData(data);

      // Calculate unrealized PnL (SOL value minus some baseline)
      const unrealizedPnl = parsed.solValue - (parsed.solPosition * 15); // Assuming $15 entry price

      return {
        totalValue: parsed.totalValue,
        availableBalance: parsed.usdcBalance,
        marginUsed: 0, // Not available without full account parsing
        unrealizedPnl,
        positions: parsed.solPosition > 0 ? [{
          symbol: 'SOL',
          size: parsed.solPosition,
          notionalValue: parsed.solValue,
          unrealizedPnl,
          side: 'long' as const
        }] : []
      };
    } catch (error) {
      console.error('❌ Failed to get trading balance:', error);
      throw error;
    }
  }

  async getPositions(): Promise<Position[]> {
    try {
      const data = await this.getAccountData();
      const parsed = this.parseAccountData(data);

      if (parsed.solPosition <= 0) {
        return [];
      }

      const unrealizedPnl = parsed.solValue - (parsed.solPosition * 15); // Assuming $15 entry

      return [{
        symbol: 'SOL',
        side: 'long',
        size: parsed.solPosition,
        entryPrice: 15, // Estimated entry price
        markPrice: parsed.solPrice,
        unrealizedPnl,
        notionalValue: parsed.solValue
      }];
    } catch (error) {
      console.error('❌ Failed to get positions:', error);
      throw error;
    }
  }

  async placeOrder(orderRequest: OrderRequest): Promise<OrderResponse> {
    console.log('📝 Order placement not implemented in direct mode:', orderRequest);
    return {
      success: false,
      error: 'Order placement requires SDK integration'
    };
  }

  async disconnect(): Promise<void> {
    console.log('✅ Direct service disconnected (no cleanup needed)');
  }
}

// Export singleton instance
export const driftTradingService = new DriftTradingService();
