/**
 * Volume History Service
 * Fetches last 5 days of volume data from database (used as fallback when Yahoo Finance data unavailable)
 */

import { rawQuery } from '../db.js';

/**
 * Fetch last 5 days of volume data for a single symbol
 * @param {string} symbol - Stock symbol (e.g., 'AAPL')
 * @returns {Promise<Array>} Array of volume data objects with date and volume
 */
export async function fetchVolumeHistory(symbol) {
  try {
    const query = `
      SELECT 
        "Date" as date,
        volume,
        open,
        high,
        low,
        close
      FROM public.prices_daily
      WHERE UPPER(symbol) = UPPER($1)
        AND "Date" <= CURRENT_DATE
        AND "Date" >= CURRENT_DATE - INTERVAL '5 days'
      ORDER BY "Date" DESC
      LIMIT 5
    `;
    
    const data = await rawQuery(query, [symbol]);
    
    // Format the data and calculate VWAP
    return data.map(row => {
      const open = parseFloat(row.open) || 0;
      const high = parseFloat(row.high) || 0;
      const low = parseFloat(row.low) || 0;
      const close = parseFloat(row.close) || 0;
      
      // Calculate VWAP (Volume Weighted Average Price)
      // For daily bars, use Typical Price: (High + Low + Close) / 3
      const typicalPrice = (high + low + close) / 3;
      const vwap = typicalPrice; // For daily bars, VWAP = Typical Price
      
      return {
        date: row.date,
        volume: parseFloat(row.volume) || 0,
        open: open,
        high: high,
        low: low,
        close: close,
        vwap: vwap
      };
    });
  } catch (error) {
    console.warn(`Failed to fetch volume history for ${symbol}:`, error.message);
    return [];
  }
}

/**
 * Batch fetch volume history for multiple symbols
 * @param {string[]} symbols - Array of stock symbols
 * @param {number} concurrency - Number of concurrent requests (default: 10)
 * @returns {Promise<Object>} Map of symbol to volume history array
 */
export async function batchFetchVolumeHistory(symbols, concurrency = 10) {
  if (!symbols || symbols.length === 0) {
    return {};
  }
  
  // Remove duplicates and normalize symbols
  const uniqueSymbols = [...new Set(symbols.map(s => s.toUpperCase().trim()))].filter(Boolean);
  
  if (uniqueSymbols.length === 0) {
    return {};
  }
  
  const volumeHistoryMap = {};
  
  // Process in batches to avoid overwhelming the database
  for (let i = 0; i < uniqueSymbols.length; i += concurrency) {
    const batch = uniqueSymbols.slice(i, i + concurrency);
    const batchPromises = batch.map(async (symbol) => {
      const data = await fetchVolumeHistory(symbol);
      return { symbol, data };
    });
    
    const batchResults = await Promise.allSettled(batchPromises);
    
    batchResults.forEach((result) => {
      if (result.status === 'fulfilled') {
        const { symbol, data } = result.value;
        if (data && data.length > 0) {
          volumeHistoryMap[symbol] = data;
        }
      } else {
        console.warn(`Failed to fetch volume history for symbol in batch:`, result.reason);
      }
    });
  }
  
  return volumeHistoryMap;
}

/**
 * Fetch volume history for multiple symbols from database (fallback when Yahoo Finance unavailable)
 * @param {string[]} symbols - Array of stock symbols
 * @returns {Promise<Object>} Map of symbol to volume history array
 */
export async function fetchVolumeHistoryBulk(symbols) {
  if (!symbols || symbols.length === 0) {
    return {};
  }
  
  // Remove duplicates and normalize symbols
  const uniqueSymbols = [...new Set(symbols.map(s => s.toUpperCase().trim()))].filter(Boolean);
  
  if (uniqueSymbols.length === 0) {
    return {};
  }
  
  const volumeHistoryMap = {};
  
  try {
    const query = `
      SELECT 
        UPPER(symbol) as symbol,
        "Date" as date,
        volume,
        open,
        high,
        low,
        close
      FROM public.prices_daily
      WHERE UPPER(symbol) = ANY($1::text[])
        AND "Date" <= CURRENT_DATE
        AND "Date" >= CURRENT_DATE - INTERVAL '5 days'
      ORDER BY symbol, "Date" DESC
    `;
    
    const data = await rawQuery(query, [uniqueSymbols]);
    
    // Group by symbol
    data.forEach(row => {
      const symbol = row.symbol;
      if (!volumeHistoryMap[symbol]) {
        volumeHistoryMap[symbol] = [];
      }
      // Only keep the last 5 days per symbol
      if (volumeHistoryMap[symbol].length < 5) {
        const open = parseFloat(row.open) || 0;
        const high = parseFloat(row.high) || 0;
        const low = parseFloat(row.low) || 0;
        const close = parseFloat(row.close) || 0;
        
        // Calculate VWAP (Volume Weighted Average Price)
        // For daily bars, use Typical Price: (High + Low + Close) / 3
        const typicalPrice = (high + low + close) / 3;
        const vwap = typicalPrice; // For daily bars, VWAP = Typical Price
        
        volumeHistoryMap[symbol].push({
          date: row.date,
          volume: parseFloat(row.volume) || 0,
          open: open,
          high: high,
          low: low,
          close: close,
          vwap: vwap
        });
      }
    });
    
    return volumeHistoryMap;
  } catch (error) {
    console.warn('⚠️ Failed to fetch bulk volume history from database:', error.message);
    return {};
  }
}

