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

const RPC_ENDPOINTS = [
  process.env.SOLANA_RPC_URL_PRIMARY,
  process.env.SOLANA_RPC_URL_SECONDARY,
  process.env.SOLANA_RPC_URL_TERTIARY,
  process.env.SOLANA_RPC_URL_BACKUP,
].filter(Boolean); // Remove any undefined/empty URLs

let currentRpcIndex = 0;
let activeConnection = null;

/**
 * Creates a Solana connection with automatic failover to backup RPCs
 */
export async function createConnectionWithFailover() {
  for (let attempt = 0; attempt < RPC_ENDPOINTS.length; attempt++) {
    const rpcUrl = RPC_ENDPOINTS[currentRpcIndex];
    
    if (!rpcUrl) {
      currentRpcIndex = (currentRpcIndex + 1) % RPC_ENDPOINTS.length;
      continue;
    }

    try {
      console.log(`Attempting to connect to RPC: ${rpcUrl.replace(/\/\/.*@/, '//*****@')}`);
      
      const connection = new Connection(rpcUrl, 'confirmed');
      
      // Test the connection by getting the latest blockhash
      await connection.getLatestBlockhash();
      
      console.log(`Successfully connected to RPC: ${rpcUrl.replace(/\/\/.*@/, '//*****@')}`);
      activeConnection = connection;
      return connection;
      
    } catch (error) {
      console.warn(`RPC ${rpcUrl.replace(/\/\/.*@/, '//*****@')} failed:`, error.message);
      
      // Move to next RPC endpoint
      currentRpcIndex = (currentRpcIndex + 1) % RPC_ENDPOINTS.length;
    }
  }
  
  throw new Error('All RPC endpoints failed. Unable to establish connection.');
}

/**
 * Gets the current active connection or creates a new one
 */
export async function getConnection() {
  if (activeConnection) {
    try {
      // Test if current connection is still working
      await activeConnection.getLatestBlockhash();
      return activeConnection;
    } catch (error) {
      console.warn('Active connection failed, attempting failover...');
      activeConnection = null;
    }
  }
  
  return createConnectionWithFailover();
}

/**
 * Executes a function with automatic RPC failover
 */
export async function executeWithFailover(operation, maxRetries = 3) {
  let lastError = null;
  
  for (let retry = 0; retry < maxRetries; retry++) {
    try {
      const connection = await getConnection();
      return await operation(connection);
    } catch (error) {
      lastError = error;
      console.warn(`Operation failed (attempt ${retry + 1}/${maxRetries}):`, error.message);
      
      // Force connection refresh on next attempt
      activeConnection = null;
      
      // Move to next RPC endpoint
      currentRpcIndex = (currentRpcIndex + 1) % RPC_ENDPOINTS.length;
      
      // Wait a bit before retrying
      if (retry < maxRetries - 1) {
        await new Promise(resolve => setTimeout(resolve, 1000 * (retry + 1)));
      }
    }
  }
  
  throw new Error(`Operation failed after ${maxRetries} attempts. Last error: ${lastError?.message}`);
}

/**
 * Get information about current RPC status
 */
export function getRpcStatus() {
  return {
    availableEndpoints: RPC_ENDPOINTS.length,
    currentEndpoint: RPC_ENDPOINTS[currentRpcIndex]?.replace(/\/\/.*@/, '//*****@'),
    hasActiveConnection: !!activeConnection
  };
}
