// website-analyzer.service.ts
import { Injectable } from '@nestjs/common';
import axios from 'axios';
import * as cheerio from 'cheerio';
import * as tldts from 'tldts';

@Injectable()
export class WebsiteAnalyzerService {
  private readonly stopwords = new Set([
    'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to',
    'for', 'of', 'with', 'by', 'as', 'is', 'was', 'are', 'were',
    'be', 'been', 'being', 'have', 'has', 'had', 'do', 'does', 'did',
    'will', 'would', 'should', 'can', 'could', 'may', 'might', 'must'
  ]);

  async analyzeWebsite(url: string): Promise<{ domain: string; companyName: string; keywords: string[] }> {
    try {
      const parsedUrl = new URL(url);
      let domain = parsedUrl.hostname;
      
      // Extract root domain using tldts
      const domainParts = tldts.parse(domain);
      const rootDomain = domainParts.domain || domain;
      const baseDomain = domainParts.domainWithoutSuffix || domain;
      
      const response = await axios.get(url, {
        timeout: 10000,
        headers: {
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
        }
      });
      
      const $ = cheerio.load(response.data);
      const companyName = this.extractCompanyName($, rootDomain);
      
      // Remove script and style elements
      $('script, style, noscript, iframe').remove();
      
      return {
        domain: rootDomain,
        companyName,
        keywords: this.generateKeywords(rootDomain, baseDomain, companyName, $)
      };
    } catch (error) {
      const domain = new URL(url).hostname.replace(/^www\./, '');
      const baseDomain = domain.split('.')[0];
      return {
        domain,
        companyName: this.capitalize(baseDomain),
        keywords: this.generateFallbackKeywords(domain, baseDomain)
      };
    }
  }

  private extractCompanyName($: cheerio.CheerioAPI, domain: string): string {
    const candidates = [
      $('meta[property="og:site_name"]').attr('content'),
      $('meta[name="application-name"]').attr('content'),
      $('meta[property="og:title"]').attr('content'),
      $('title').first().text(),
      $('h1').first().text()
    ];

    for (const candidate of candidates) {
      if (candidate && candidate.trim().length > 0) {
        const cleanName = candidate
          .replace(/[\n\t]/g, ' ')
          .replace(/\s{2,}/g, ' ')
          .trim()
          .split(/[-|>–—]| \| | :: /)[0]
          .trim();
        
        if (cleanName.length > 2 && cleanName.length < 50) {
          return this.capitalize(cleanName);
        }
      }
    }

    return this.capitalize(domain.split('.')[0]);
  }

  private generateKeywords(
    domain: string,
    baseDomain: string,
    companyName: string,
    $: cheerio.CheerioAPI
  ): string[] {
    const keywords = new Set<string>();
    const leakTerms = ['leak', 'breach', 'dump', 'database', 'credentials', 'password', 'hack', 'exposed', 'compromised'];
    const emailPatterns = ['admin', 'support', 'contact', 'info', 'security', 'help'];
    
    // Add domain variations
    keywords.add(domain);
    keywords.add(baseDomain);
    keywords.add(domain.replace(/\./g, ''));
    keywords.add(domain.replace(/\./g, '-'));
    keywords.add(domain.replace(/\./g, '_'));
    
    // Add company name variations
    const cleanCompany = companyName.replace(/[^\w\s]/gi, '');
    keywords.add(cleanCompany);
    keywords.add(cleanCompany.replace(/\s+/g, ''));
    keywords.add(cleanCompany.replace(/\s+/g, '-'));
    keywords.add(cleanCompany.replace(/\s+/g, '_'));
    
    // Add leak-related combinations
    leakTerms.forEach(term => {
      keywords.add(`${baseDomain}${term}`);
      keywords.add(`${cleanCompany}${term}`);
      keywords.add(`${baseDomain}_${term}`);
      keywords.add(`${cleanCompany}_${term}`);
    });
    
    // Generate email patterns
    emailPatterns.forEach(pattern => {
      keywords.add(`${pattern}@${domain}`);
    });
    
    // Extract from meta tags
    const metaKeywords = $('meta[name="keywords"]').attr('content') || '';
    metaKeywords.split(/[,;]/).forEach(kw => {
      const clean = kw.trim().toLowerCase();
      if (clean.length > 2 && !this.stopwords.has(clean)) {
        keywords.add(clean);
      }
    });
    
    // Extract from headings
    $('h1, h2, h3').each((i, el) => {
      const text = $(el).text().toLowerCase();
      text.split(/\W+/).forEach(word => {
        if (word.length > 3 && !this.stopwords.has(word)) {
          keywords.add(word);
        }
      });
    });
    
    return Array.from(keywords).slice(0, 25);
  }

  private generateFallbackKeywords(domain: string, baseDomain: string): string[] {
    return [
      domain,
      baseDomain,
      `${baseDomain}.com`,
      `${baseDomain}leak`,
      `${baseDomain}breach`,
      `admin@${domain}`,
      `support@${domain}`
    ];
  }

  private capitalize(str: string): string {
    return str.replace(/\b\w/g, char => char.toUpperCase());
  }
}