import type { BaseHandler } from '@stock-bot/handlers';
import type { DataIngestionServices } from '../../../types';
import { EOD_CONFIG } from '../shared';

export async function fetchSymbolChangeHistory(
  this: BaseHandler<DataIngestionServices>
): Promise<{ success: boolean; changesCount: number }> {
  const logger = this.logger;
  
  try {
    logger.info('Fetching symbol change history');
    
    // Get API key
    const apiKey = EOD_CONFIG.API_TOKEN;
    if (!apiKey) {
      throw new Error('EOD API key not configured');
    }
    
    // Build URL
    const url = new URL('https://eodhd.com/api/symbol-change-history');
    url.searchParams.append('api_token', apiKey);
    url.searchParams.append('fmt', 'json');
    
    // Fetch data
    const response = await fetch(url.toString());
    
    if (!response.ok) {
      throw new Error(`EOD Symbol Change API returned ${response.status}: ${response.statusText}`);
    }
    
    const data = await response.json();
    
    // EOD returns an array of symbol changes
    if (!Array.isArray(data)) {
      throw new Error('Invalid response format from EOD API - expected array');
    }
    
    logger.info(`Fetched ${data.length} symbol change records`);
    
    if (data.length === 0) {
      logger.info('No symbol changes found');
      return { success: true, changesCount: 0 };
    }
    
    // Log some sample changes
    logger.debug('Sample symbol changes:', {
      count: data.length,
      samples: data.slice(0, 5).map(c => ({
        oldSymbol: c.oldSymbol,
        newSymbol: c.newSymbol,
        exchange: c.exchange,
        date: c.date,
        note: c.note
      }))
    });
    
    // Add metadata to each record
    const changesWithMetadata = data.map(change => ({
      ...change,
      updatedAt: new Date(),
      source: 'eod'
    }));
    
    // Clear existing data and insert new (symbol changes are a complete dataset)
    await this.mongodb.collection('eodSymbolChange').deleteMany({});
    const result = await this.mongodb.collection('eodSymbolChange').insertMany(changesWithMetadata);
    
    logger.info(`Successfully saved ${result.insertedCount} symbol change records`);
    
    // Process symbol changes to update affected symbols in eodSymbols collection
    let updatedSymbols = 0;
    for (const change of data) {
      if (change.oldSymbol && change.newSymbol && change.exchange) {
        // Update the symbol if it exists
        const updateResult = await this.mongodb.collection('eodSymbols').updateOne(
          { Code: change.oldSymbol, Exchange: change.exchange },
          { 
            $set: { 
              Code: change.newSymbol,
              previousCode: change.oldSymbol,
              symbolChangeDate: change.date,
              symbolChangeNote: change.note || 'Symbol changed'
            } 
          }
        );
        
        if (updateResult.modifiedCount > 0) {
          updatedSymbols++;
          logger.info(`Updated symbol ${change.oldSymbol} to ${change.newSymbol} on ${change.exchange}`, {
            date: change.date,
            note: change.note
          });
        }
      }
    }
    
    if (updatedSymbols > 0) {
      logger.info(`Updated ${updatedSymbols} symbols based on change history`);
    }
    
    return {
      success: true,
      changesCount: result.insertedCount
    };
  } catch (error) {
    logger.error('Failed to fetch symbol change history', { error });
    throw error;
  }
}