/**
 * Drift Order Cleanup Service
 * Automatically detects and cancels orphaned orders when positions are closed
 */

class DriftOrderCleanupService {
  constructor() {
    this.isRunning = false
    this.monitoringInterval = null
    this.lastCleanupTime = 0
    this.cleanupCooldown = 30000 // 30 seconds between cleanups
  }

  /**
   * Start monitoring for orphaned orders
   */
  start(intervalMs = 60000) { // Check every 60 seconds by default
    if (this.isRunning) {
      console.log('⚠️ Drift order cleanup service already running')
      return
    }

    this.isRunning = true
    console.log(`🧹 Starting Drift order cleanup service (checking every ${intervalMs/1000}s)`)

    this.monitoringInterval = setInterval(async () => {
      try {
        await this.checkAndCleanupOrders()
      } catch (error) {
        console.error('❌ Error in order cleanup monitoring:', error)
      }
    }, intervalMs)

    // Also run an initial check
    setTimeout(() => this.checkAndCleanupOrders().catch(console.error), 5000)
  }

  /**
   * Stop monitoring
   */
  stop() {
    if (!this.isRunning) {
      console.log('⚠️ Drift order cleanup service not running')
      return
    }

    this.isRunning = false
    
    if (this.monitoringInterval) {
      clearInterval(this.monitoringInterval)
      this.monitoringInterval = null
    }

    console.log('🛑 Drift order cleanup service stopped')
  }

  /**
   * Check for orphaned orders and clean them up
   */
  async checkAndCleanupOrders() {
    if (!this.isRunning) return

    // Prevent too frequent cleanups
    const now = Date.now()
    if (now - this.lastCleanupTime < this.cleanupCooldown) {
      return
    }

    try {
      console.log('🔍 Checking for orphaned orders...')

      // Get current positions and orders
      const [positionsResponse, ordersResponse] = await Promise.all([
        fetch('http://localhost:9001/api/drift/positions'),
        fetch('http://localhost:9001/api/drift/orders')
      ])

      if (!positionsResponse.ok || !ordersResponse.ok) {
        console.warn('⚠️ Failed to fetch positions or orders for cleanup check')
        return
      }

      const positionsData = await positionsResponse.json()
      const ordersData = await ordersResponse.json()

      if (!positionsData.success || !ordersData.success) {
        console.warn('⚠️ API responses indicate failure, skipping cleanup')
        return
      }

      const positions = positionsData.positions || []
      const orders = ordersData.orders || []

      console.log(`📊 Current state: ${positions.length} positions, ${orders.length} orders`)

      // Quick check: if no orphaned orders, skip cleanup
      const positionMarkets = new Set(positions.map(pos => pos.marketIndex))
      const orphanedOrders = orders.filter(order => 
        // CRITICAL FIX: Only cancel non-reduce-only orders when no position exists
        // Stop Loss and Take Profit orders are reduce-only and should exist with positions
        !positionMarkets.has(order.marketIndex) && !order.reduceOnly
      )

      if (orphanedOrders.length === 0) {
        console.log('✅ No orphaned orders detected')
        return
      }

      console.log(`🎯 Found ${orphanedOrders.length} potentially orphaned orders`)

      // Trigger cleanup
      const cleanupResponse = await fetch('http://localhost:9001/api/drift/cleanup-orders', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        }
      })

      if (!cleanupResponse.ok) {
        throw new Error(`Cleanup API failed: ${cleanupResponse.status}`)
      }

      const cleanupResult = await cleanupResponse.json()

      if (cleanupResult.success) {
        const summary = cleanupResult.summary
        console.log('🧹 Order cleanup completed:')
        console.log(`   📊 Orphaned orders: ${summary.orphanedOrders}`)
        console.log(`   ⚠️ Conflicting orders: ${summary.conflictingOrders}`)
        console.log(`   ✅ Successfully canceled: ${summary.totalCanceled}`)
        console.log(`   ❌ Failed to cancel: ${summary.totalFailed}`)

        this.lastCleanupTime = now

        // Log each canceled order
        cleanupResult.canceledOrders.forEach(order => {
          if (order.success) {
            console.log(`   ✅ Canceled ${order.symbol} order ${order.orderId} (${order.reason})`)
          } else {
            console.log(`   ❌ Failed to cancel order ${order.orderId}: ${order.error}`)
          }
        })
      } else {
        console.error('❌ Order cleanup failed:', cleanupResult.error)
      }

    } catch (error) {
      console.error('❌ Error during order cleanup check:', error)
    }
  }

  /**
   * Manual cleanup trigger
   */
  async forceCleanup() {
    console.log('🧹 Manual order cleanup triggered...')
    
    try {
      const response = await fetch('http://localhost:9001/api/drift/cleanup-orders', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        }
      })

      if (!response.ok) {
        throw new Error(`Cleanup API failed: ${response.status}`)
      }

      const result = await response.json()

      if (result.success) {
        console.log('✅ Manual cleanup completed:', result.summary)
        return result
      } else {
        throw new Error(result.error)
      }

    } catch (error) {
      console.error('❌ Manual cleanup failed:', error)
      throw error
    }
  }

  /**
   * Get service status
   */
  getStatus() {
    return {
      isRunning: this.isRunning,
      lastCleanupTime: this.lastCleanupTime,
      lastCleanupAgo: this.lastCleanupTime ? Date.now() - this.lastCleanupTime : null,
      cooldownRemaining: Math.max(0, this.cleanupCooldown - (Date.now() - this.lastCleanupTime))
    }
  }
}

// Export singleton instance
export const driftOrderCleanupService = new DriftOrderCleanupService()

// For CommonJS compatibility
if (typeof module !== 'undefined' && module.exports) {
  module.exports = { driftOrderCleanupService, DriftOrderCleanupService }
}
