import { Page } from 'playwright';
import { BaseScraper } from './base-scraper';
import { VendorListing } from './types';

export class EldoradoScraper extends BaseScraper {
  getVendorName(): 'eldorado' {
    return 'eldorado';
  }

  getTargetUrl(): string {
    return 'https://www.eldorado.gg/star-citizen-auec/g/141-0-0';
  }

  async extractListings(page: Page): Promise<VendorListing[]> {
    // Wait for page readiness
    await page.waitForSelector('text=Star Citizen aUEC', { timeout: 15000 }).catch(() => {});
    
    // Wait for price elements to appear
    await page.waitForTimeout(3000);

    const listings = await page.evaluate(() => {
      const results: Array<{
        amountAUEC: number;
        priceUSD: number;
        pricePerMillion: number;
        seller?: string;
        deliveryTime?: string;
      }> = [];

      const bodyText = document.body.innerText;
      const lines = bodyText.split('\n').map(l => l.trim()).filter(l => l.length > 0);

      // Track seen combinations to avoid duplicates
      const seenListings = new Set<string>();

      const blockedSellerTerms = new Set([
        'price',
        'delivery time',
        'delivery instructions',
        'current offer',
        'in stock',
        'min. qty.',
        'min. qty',
        'min qty',
        'recommended',
        'cheapest first',
        'lowest min. quantity',
        'other sellers',
        'star citizen',
        'auec',
        'items',
        'accounts',
        'top ups',
        'boosting',
        'gift cards',
      ]);

      for (let i = 0; i < lines.length; i++) {
        const line = lines[i];

        // Eldorado currently exposes unit pricing as either /K or /M.
        const unitPriceMatch = line.match(/\$\s*([\d.]+)\s*\/\s*([KM])/i);

        if (unitPriceMatch) {
          const unitPrice = parseFloat(unitPriceMatch[1]);
          const priceUnit = unitPriceMatch[2].toUpperCase();
          const pricePerMillion = priceUnit === 'K' ? unitPrice * 1000 : unitPrice;

          // Look for the minimum quantity nearby and normalize it to aUEC.
          let amountAUEC = 1_000_000;
          for (let j = Math.max(0, i - 5); j < Math.min(lines.length, i + 5); j++) {
            const qtyLine = lines[j];
            const qtyMatch = qtyLine.match(/Min\.?\s*qty\.?\s*:?\s*([\d,]+)\s*([KM])/i);
            if (qtyMatch) {
              const quantity = parseFloat(qtyMatch[1].replace(/,/g, ''));
              const quantityUnit = qtyMatch[2].toUpperCase();
              amountAUEC = quantity * (quantityUnit === 'K' ? 1_000 : 1_000_000);
              break;
            }
          }

          const priceUSD = (amountAUEC / 1_000_000) * pricePerMillion;

          let seller: string | undefined;
          for (let j = i - 1; j >= Math.max(0, i - 13); j--) {
            const candidate = lines[j];
            const normalized = candidate.toLowerCase();

            if (
              !candidate ||
              candidate.includes('$') ||
              candidate.includes('%') ||
              /\breviews?\b/i.test(candidate) ||
              /\borders?\b/i.test(candidate) ||
              /\bmember since\b/i.test(candidate) ||
              /\bminutes?\b|\bhours?\b|\bdays?\b/i.test(candidate) ||
              /\d,\d{3}/.test(candidate) ||
              blockedSellerTerms.has(normalized) ||
              normalized.startsWith('other sellers') ||
              candidate.length < 3 ||
              candidate.length > 30
            ) {
              continue;
            }

            if (/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(candidate)) {
              seller = candidate;
              break;
            }
          }

          // Find delivery time
          let deliveryTime: string | undefined;
          for (let j = Math.max(0, i - 5); j < Math.min(lines.length, i + 5); j++) {
            const deliveryLine = lines[j];
            if (
              deliveryLine.match(/\d+\s*min/i) ||
              deliveryLine.match(/\d+\s*hour/i) ||
              deliveryLine.toLowerCase().includes('instant')
            ) {
              deliveryTime = deliveryLine;
              break;
            }
          }

          // Create unique key to avoid duplicates
          const key = `${seller || 'unknown'}-${pricePerMillion}-${amountAUEC}`;
          if (seenListings.has(key)) continue;
          seenListings.add(key);

          results.push({
            amountAUEC,
            priceUSD,
            pricePerMillion,
            seller,
            deliveryTime,
          });
        }
      }

      return results;
    });

    const scrapedAt = new Date();
    const url = this.getTargetUrl();

    return listings.map(listing => ({
      vendor: 'eldorado' as const,
      amountAUEC: listing.amountAUEC,
      priceUSD: listing.priceUSD,
      pricePerMillion: listing.pricePerMillion,
      seller: listing.seller,
      deliveryTime: listing.deliveryTime,
      scrapedAt,
      url,
    }));
  }
}
