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

export class PlayerAuctionsScraper extends BaseScraper {
  getVendorName(): 'playerauctions' {
    return 'playerauctions';
  }

  getTargetUrl(): string {
    return 'https://www.playerauctions.com/star-citizen-auec/';
  }

  async extractListings(page: Page): Promise<VendorListing[]> {
    await page.waitForTimeout(3000);

    // Close cookie popup if it exists
    try {
      const cookieClose = page.locator('[id*="cookie"] button, [class*="cookie"] button, button:has-text("Accept"), button:has-text("Close")').first();
      if (await cookieClose.isVisible({ timeout: 2000 }).catch(() => false)) {
        await cookieClose.click();
        await page.waitForTimeout(500);
      }
    } catch (e) {
      // No cookie popup or already closed
    }

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

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

      const blockedSellerTerms = new Set([
        'main server',
        'offer details',
        'buy now',
        'm',
        'go',
        'price',
        'server',
        'rating',
        'delivery',
        'new seller',
      ]);

      const seenListings = new Set<string>();

      for (let i = 0; i < lines.length; i++) {
        const line = lines[i];
        const pricePerMillionMatch = line.match(/^\$\s*([\d,]+(?:\.\d+)?)\s*\/\s*M\b/i);

        if (!pricePerMillionMatch) {
          continue;
        }

        const pricePerMillion = parseFloat(pricePerMillionMatch[1].replace(/,/g, ''));
        let totalPriceUSD = 0;

        for (let j = i + 1; j <= Math.min(lines.length - 1, i + 3); j++) {
          const totalMatch = lines[j].match(/^\$\s*([\d,]+(?:\.\d{2})?)$/);
          if (totalMatch) {
            totalPriceUSD = parseFloat(totalMatch[1].replace(/,/g, ''));
            break;
          }
        }

        if (!totalPriceUSD || !pricePerMillion) {
          continue;
        }

        const amountInMillions = totalPriceUSD / pricePerMillion;
        const amountAUEC = Math.round(amountInMillions * 1_000_000);
        let seller: string | undefined;
        for (let j = i - 1; j >= Math.max(0, i - 10); j--) {
          const candidate = lines[j];
          const normalized = candidate.toLowerCase();

          if (
            blockedSellerTerms.has(normalized) ||
            candidate.includes('$') ||
            /\(\d+\)/.test(candidate) ||
            /\bminutes?\b|\bhours?\b|\bdays?\b/i.test(candidate) ||
            /\bmember since\b|\btotal orders\b/i.test(candidate) ||
            /^\d+(\.\d+)?$/.test(candidate) ||
            candidate.length < 3 ||
            candidate.length > 24
          ) {
            continue;
          }

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

        let deliveryTime: string | undefined;
        for (let j = Math.max(0, i - 6); j < i; j++) {
          if (/\d+\s*(Minutes?|Hours?|Days?)/i.test(lines[j])) {
            deliveryTime = lines[j];
            break;
          }
        }

        const key = `${seller || 'unknown'}-${pricePerMillion}-${totalPriceUSD}`;
        if (seenListings.has(key)) {
          continue;
        }
        seenListings.add(key);

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

      return results;
    });

    if (listings.length === 0) {
      return this.extractListingsAlternative(page);
    }

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

  private async extractListingsAlternative(page: Page): Promise<VendorListing[]> {

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

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

      const seenPrices = new Set<number>();

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

        // Look for "$1 = X M aUEC" pattern and convert
        const exchangeMatch = line.match(/\$1\s*=\s*([\d,]+(?:\.\d+)?)\s*M\s*(?:aUEC)?/i);
        
        if (exchangeMatch) {
          const millionsPerDollar = parseFloat(exchangeMatch[1].replace(/,/g, ''));
          const pricePerMillion = 1 / millionsPerDollar;

          if (seenPrices.has(pricePerMillion)) continue;
          seenPrices.add(pricePerMillion);

          const targetQuantityM = 1000000;
          const amountAUEC = targetQuantityM * 1_000_000;
          const priceUSD = pricePerMillion * targetQuantityM;

          results.push({
            amountAUEC,
            priceUSD,
            pricePerMillion,
            seller: 'Unknown',
          });
        }
      }

      return results;
    });

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

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