/**
 * Flow Reversal Detector
 * Detects when net premium direction flips (institutions switching sides)
 */

/**
 * Detect flow reversal for a ticker
 * @param {Array} flows - Array of flow records for a ticker (sorted by time desc)
 * @param {number} windowMinutes - Time window to check for reversal (default 30)
 * @returns {Object} Flow reversal analysis
 */
export function detectFlowReversal(flows, windowMinutes = 30) {
  if (!flows || flows.length < 2) {
    return {
      hasReversal: false,
      reversalType: null,
      reversalTime: null,
      trajectory: 'INSUFFICIENT_DATA',
      alert: null
    };
  }
  
  // Filter flows within the time window
  const now = new Date();
  const windowStart = new Date(now.getTime() - windowMinutes * 60 * 1000);
  
  const recentFlows = flows.filter(flow => {
    const flowTime = new Date(flow.flow_ts_utc || flow.CreatedDate || 0);
    return flowTime >= windowStart;
  }).sort((a, b) => {
    const timeA = new Date(a.flow_ts_utc || a.CreatedDate || 0);
    const timeB = new Date(b.flow_ts_utc || b.CreatedDate || 0);
    return timeA - timeB; // Sort ascending (oldest first)
  });
  
  if (recentFlows.length < 2) {
    return {
      hasReversal: false,
      reversalType: null,
      reversalTime: null,
      trajectory: 'INSUFFICIENT_DATA',
      alert: null
    };
  }
  
  // Calculate net premium for each flow
  const netPremiums = recentFlows.map(flow => {
    const bullTotal = flow.bull_total || 0;
    const bearTotal = flow.bear_total || 0;
    const netPrem = bullTotal - bearTotal;
    const direction = netPrem > 0 ? 'BULL' : netPrem < 0 ? 'BEAR' : 'NEUTRAL';
    
    return {
      timestamp: new Date(flow.flow_ts_utc || flow.CreatedDate || 0),
      netPremium: netPrem,
      direction,
      badgeRound: flow.badge_round || flow.badges?.round || ''
    };
  });
  
  // Determine trajectory
  const trajectory = determineTrajectory(netPremiums);
  
  // Check for reversal
  const reversal = detectReversal(netPremiums);
  
  if (reversal.hasReversal) {
    const reversalTime = reversal.reversalTime;
    const fromDirection = reversal.fromDirection;
    const toDirection = reversal.toDirection;
    
    return {
      hasReversal: true,
      reversalType: `${fromDirection}_TO_${toDirection}`,
      reversalTime: reversalTime.toISOString(),
      trajectory,
      alert: `⚠️ FLOW REVERSAL: ${recentFlows[0].Symbol || recentFlows[0].symbol_norm || 'UNKNOWN'} flipped from ${fromDirection} to ${toDirection} at ${reversalTime.toLocaleTimeString()}`,
      fromDirection,
      toDirection,
      netPremiumHistory: netPremiums
    };
  }
  
  return {
    hasReversal: false,
    reversalType: null,
    reversalTime: null,
    trajectory,
    alert: null,
    netPremiumHistory: netPremiums
  };
}

/**
 * Determine net premium trajectory
 */
function determineTrajectory(netPremiums) {
  if (netPremiums.length < 3) return 'INSUFFICIENT_DATA';
  
  // Get first, middle, and last
  const first = netPremiums[0].netPremium;
  const middle = netPremiums[Math.floor(netPremiums.length / 2)].netPremium;
  const last = netPremiums[netPremiums.length - 1].netPremium;
  
  // Calculate trend
  const earlyTrend = middle - first;
  const lateTrend = last - middle;
  
  // Rising trajectory
  if (earlyTrend > 0 && lateTrend > 0) return 'RISING';
  if (earlyTrend > 0 && lateTrend < 0) return 'RISING_THEN_FALLING';
  
  // Falling trajectory
  if (earlyTrend < 0 && lateTrend < 0) return 'FALLING';
  if (earlyTrend < 0 && lateTrend > 0) return 'FALLING_THEN_RISING';
  
  // Flat
  if (Math.abs(earlyTrend) < 10000 && Math.abs(lateTrend) < 10000) return 'FLAT';
  
  return 'MIXED';
}

/**
 * Detect actual reversal (direction flip)
 */
function detectReversal(netPremiums) {
  if (netPremiums.length < 2) {
    return { hasReversal: false };
  }
  
  // Check for badge color changes (more reliable than just net premium)
  for (let i = 1; i < netPremiums.length; i++) {
    const prev = netPremiums[i - 1];
    const curr = netPremiums[i];
    
    // Check if direction flipped
    if (prev.direction !== 'NEUTRAL' && 
        curr.direction !== 'NEUTRAL' && 
        prev.direction !== curr.direction) {
      return {
        hasReversal: true,
        reversalTime: curr.timestamp,
        fromDirection: prev.direction,
        toDirection: curr.direction
      };
    }
  }
  
  // Also check for significant net premium flip (even if both same direction)
  for (let i = 1; i < netPremiums.length; i++) {
    const prev = netPremiums[i - 1];
    const curr = netPremiums[i];
    
    // Significant flip: from strongly positive to strongly negative (or vice versa)
    const prevAbs = Math.abs(prev.netPremium);
    const currAbs = Math.abs(curr.netPremium);
    const flipMagnitude = Math.abs(curr.netPremium - prev.netPremium);
    
    if (prevAbs > 500000 && currAbs > 500000 && flipMagnitude > 1000000) {
      // Check if it crossed zero
      if ((prev.netPremium > 0 && curr.netPremium < 0) ||
          (prev.netPremium < 0 && curr.netPremium > 0)) {
        return {
          hasReversal: true,
          reversalTime: curr.timestamp,
          fromDirection: prev.netPremium > 0 ? 'BULL' : 'BEAR',
          toDirection: curr.netPremium > 0 ? 'BULL' : 'BEAR'
        };
      }
    }
  }
  
  return { hasReversal: false };
}

/**
 * Batch detect flow reversals for multiple tickers
 * @param {Object} tickerFlows - Object mapping ticker symbols to their flow arrays
 * @param {number} windowMinutes - Time window to check
 * @returns {Object} Flow reversal analysis per ticker
 */
export function batchDetectFlowReversals(tickerFlows, windowMinutes = 30) {
  const results = {};
  
  for (const [ticker, flows] of Object.entries(tickerFlows)) {
    results[ticker] = detectFlowReversal(flows, windowMinutes);
  }
  
  return results;
}

/**
 * Format flow reversal for display
 */
export function formatFlowReversal(reversal) {
  if (!reversal || !reversal.hasReversal) {
    return {
      display: 'No reversal',
      color: 'gray',
      icon: '⚪',
      alert: null
    };
  }
  
  const icons = {
    'BULL_TO_BEAR': '🔴',
    'BEAR_TO_BULL': '🟢'
  };
  
  const colors = {
    'BULL_TO_BEAR': 'red',
    'BEAR_TO_BULL': 'green'
  };
  
  return {
    display: `${icons[reversal.reversalType]} Reversal: ${reversal.fromDirection} → ${reversal.toDirection}`,
    color: colors[reversal.reversalType] || 'yellow',
    icon: icons[reversal.reversalType] || '⚠️',
    alert: reversal.alert,
    full: reversal
  };
}

