import { getRandomUserAgent } from '@stock-bot/utils';
import * as cheerio from 'cheerio';
import { TE_CONFIG } from '../shared/config';
import type { TeCountry } from '../shared/types';
import type { TeHandler } from '../te.handler';

export async function fetchCountries(this: TeHandler): Promise<TeCountry[] | null> {
  const { logger, mongodb } = this;
  
  try {
    // 1. Fetch the HTML page
    const reqInfo = {
      proxy: this.proxy.getProxy(),
      headers: {
        'User-Agent': getRandomUserAgent(),
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
        'Accept-Language': 'en-US,en;q=0.5',
        'Accept-Encoding': 'gzip, deflate, br',
      },
    }
    const response = await fetch(TE_CONFIG.COUNTRIES_URL, reqInfo);
    
    logger.debug('Response status:', { 
      status: response.status, 
      statusText: response.statusText,
      url: response.url 
    });
    
    if (!response.ok) {
      throw new Error(`Failed to fetch: ${response.status} ${response.statusText}`);
    }
    
    const html = await response.text();
    
    logger.info('Fetched HTML length:', { length: html.length });
  
    
    // 2. Parse HTML to extract country data
    const $ = cheerio.load(html);
    const countries: TeCountry[] = [];
    
    // Look for country links - they typically have a pattern like /country-name
    // Trading Economics groups countries by region in the page
    $('.list-group-item, a[href^="/"]').each((_, element) => {
      const $el = $(element);
      
      // Try to extract country information
      let name: string | undefined;
      let url: string | undefined;
      let region: string | undefined;
      
      // Check if it's a direct link
      if ($el.is('a')) {
        const href = $el.attr('href');
        const text = $el.text().trim();
        console.log(href)
        // Filter for country URLs (they don't contain special paths like /indicators, /calendar, etc.)
        if (href && href.startsWith('/') && !href.includes('/') && text) {
          name = text;
          url = href;
        }
      } else {
        // Check for links within table rows
        const $link = $el.find('a[href^="/"]').first();
        if ($link.length) {
          const href = $link.attr('href');
          const text = $link.text().trim();
          
          if (href && text && !href.includes('/indicators') && !href.includes('/calendar')) {
            name = text;
            url = href;
            
            // Try to get region from parent elements
            const $regionHeader = $el.closest('.region-section, .country-group').find('h2, h3, .region-title').first();
            if ($regionHeader.length) {
              region = $regionHeader.text().trim();
            }
          }
        }
      }
      
      // Add to countries array if we found valid data
      if (name && url) {
        // Extract country code from URL if possible (e.g., /united-states -> US)
        const code = extractCountryCode(url, name);
        
        countries.push({
          name,
          code,
          url: `https://tradingeconomics.com${url}`,
          region,
          updated_at: new Date(),
        });
      }
    });
    
    // Remove duplicates based on name
    const uniqueCountries = Array.from(
      new Map(countries.map(c => [c.name, c])).values()
    );
    
    if (uniqueCountries.length === 0) {
      throw new Error('No countries found in HTML');
    }
    
    logger.info('Extracted countries from HTML', { 
      count: uniqueCountries.length,
      byRegion: groupCountriesByRegion(uniqueCountries),
    });
    
    // 3. Save to MongoDB
    try {
      console.log( uniqueCountries)
      if (uniqueCountries.length > 0) {
        const result = await mongodb?.batchUpsert('teCountries', uniqueCountries, ['code']);
        logger.info('Countries saved to MongoDB', {
          matched: result.matchedCount,
          modified: result.modifiedCount,
          upserted: result.upsertedCount,
        });
      }
    } catch (dbError) {
      logger.error('Failed to save countries to MongoDB', { error: dbError });
      throw dbError;
    }
    
    return uniqueCountries;
  } catch (error) {
    logger.error('Failed to fetch Trading Economics countries', { 
      error: error instanceof Error ? error.message : String(error),
      stack: error instanceof Error ? error.stack : undefined,
    });
    return null;
  }
}

function extractCountryCode(url: string, name: string): string | undefined {
  // Common country code mappings
  const countryCodeMap: Record<string, string> = {
    'united-states': 'US',
    'united-kingdom': 'GB',
    'euro-area': 'EU',
    'china': 'CN',
    'japan': 'JP',
    'germany': 'DE',
    'france': 'FR',
    'italy': 'IT',
    'spain': 'ES',
    'canada': 'CA',
    'australia': 'AU',
    'south-korea': 'KR',
    'india': 'IN',
    'brazil': 'BR',
    'russia': 'RU',
    'mexico': 'MX',
    'indonesia': 'ID',
    'netherlands': 'NL',
    'saudi-arabia': 'SA',
    'turkey': 'TR',
    'switzerland': 'CH',
    'poland': 'PL',
    'sweden': 'SE',
    'belgium': 'BE',
    'argentina': 'AR',
    'ireland': 'IE',
    'austria': 'AT',
    'norway': 'NO',
    'israel': 'IL',
    'singapore': 'SG',
    'denmark': 'DK',
    'egypt': 'EG',
    'philippines': 'PH',
    'finland': 'FI',
    'chile': 'CL',
    'pakistan': 'PK',
    'romania': 'RO',
    'new-zealand': 'NZ',
    'greece': 'GR',
    'iraq': 'IQ',
    'portugal': 'PT',
    'czech-republic': 'CZ',
    'vietnam': 'VN',
    'peru': 'PE',
    'colombia': 'CO',
    'malaysia': 'MY',
    'ukraine': 'UA',
    'hungary': 'HU',
    'kuwait': 'KW',
    'morocco': 'MA',
    'slovakia': 'SK',
    'kenya': 'KE',
    'puerto-rico': 'PR',
    'ecuador': 'EC',
    'ethiopia': 'ET',
    'dominican-republic': 'DO',
    'luxembourg': 'LU',
    'oman': 'OM',
    'guatemala': 'GT',
    'bulgaria': 'BG',
    'ghana': 'GH',
    'tanzania': 'TZ',
    'turkmenistan': 'TM',
    'croatia': 'HR',
    'costa-rica': 'CR',
    'lebanon': 'LB',
    'slovenia': 'SI',
    'lithuania': 'LT',
    'serbia': 'RS',
    'panama': 'PA',
  };
  
  // Clean URL to get country slug
  const slug = url.replace(/^\//, '').toLowerCase();
  
  return countryCodeMap[slug];
}

function groupCountriesByRegion(countries: TeCountry[]): Record<string, number> {
  const groups: Record<string, number> = {};
  
  for (const country of countries) {
    const region = country.region || 'Unknown';
    groups[region] = (groups[region] || 0) + 1;
  }
  
  return groups;
}