#!/usr/bin/env node

/**
 * Hacker News Scraper
 *
 * Fetches and parses submissions from Hacker News front page.
 * Usage: node browser-hn-scraper.js [--limit <number>]
 */

import { JSDOM } from "jsdom";

/**
 * Scrapes Hacker News front page
 * @param {number} limit - Maximum number of submissions to return (default: 30)
 * @returns {Promise<Array>} Array of submission objects
 */
async function scrapeHackerNews(limit = 30) {
  const url = 'https://news.ycombinator.com';

  try {
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const html = await response.text();
    const dom = new JSDOM(html, { url });
    const document = dom.window.document;
    const submissions = [];

    for (const element of document.querySelectorAll(".athing")) {
      if (submissions.length >= limit) {
        break;
      }

      const id = element.getAttribute("id");
      const titleLink = element.querySelector(".titleline > a");
      const title = titleLink?.textContent?.trim() || "";
      const submissionUrl = titleLink?.getAttribute("href") || "";

      const metadataRow = element.nextElementSibling;
      const subtext = metadataRow?.querySelector(".subtext");
      const score = id ? subtext?.querySelector(`#score_${id}`) : null;
      const pointsText = score?.textContent || "";
      const points = pointsText ? parseInt(pointsText.match(/\d+/)?.[0] || "0", 10) : 0;
      const author = subtext?.querySelector(".hnuser")?.textContent?.trim() || "";
      const age = subtext?.querySelector(".age");
      const time = age?.getAttribute("title") || age?.textContent?.trim() || "";
      const commentLinks = subtext ? Array.from(subtext.querySelectorAll("a")) : [];
      const commentsText = commentLinks.at(-1)?.textContent || "";
      let commentsCount = 0;

      if (commentsText.includes("comment")) {
        const match = commentsText.match(/(\d+)/);
        commentsCount = match ? parseInt(match[0], 10) : 0;
      }

      submissions.push({
        id,
        title,
        url: submissionUrl,
        points,
        author,
        time,
        comments: commentsCount,
        hnUrl: `https://news.ycombinator.com/item?id=${id}`
      });
    }

    return submissions;
  } catch (error) {
    console.error('Error scraping Hacker News:', error.message);
    throw error;
  }
}

// CLI interface
if (import.meta.url === `file://${process.argv[1]}`) {
  const args = process.argv.slice(2);
  let limit = 30;

  // Parse --limit argument
  const limitIndex = args.indexOf('--limit');
  if (limitIndex !== -1 && args[limitIndex + 1]) {
    limit = parseInt(args[limitIndex + 1]);
  }

  scrapeHackerNews(limit)
    .then(submissions => {
      console.log(JSON.stringify(submissions, null, 2));
      console.error(`\n✓ Scraped ${submissions.length} submissions`);
    })
    .catch(error => {
      console.error('Failed to scrape:', error.message);
      process.exit(1);
    });
}

export { scrapeHackerNews };
