import puppeteer from 'puppeteer';
import fs from 'fs';
import path from 'path';
import { pingDailyPuzzleUpdated } from '../services/indexingService';
import { launchBrowser } from "./puppeteer-launcher";
export async function generateBlossomHints() {
    const date = new Date().toISOString().split('T')[0];

    const isProduction = process.env.NODE_ENV === 'production';
    const baseDir = path.join(__dirname, '..', '..', '..');
    const hintsDir = isProduction
        ? path.join(baseDir, 'nytsolvers', 'dist', 'client', 'hints', 'blossom')
        : path.join(baseDir, 'project', 'public', 'hints', 'blossom');

    if (!fs.existsSync(hintsDir)) {
        fs.mkdirSync(hintsDir, { recursive: true });
    }

    const filePath = path.join(hintsDir, `${date}.json`);

    try {
            const browser = await launchBrowser();

        const page = await browser.newPage();
        page.setDefaultNavigationTimeout(90000);

        await page.setBypassCSP(true);
        await page.setJavaScriptEnabled(true);

        await page.setExtraHTTPHeaders({
            "User-Agent":
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
        });

        // ✅ Attempt #1
        try {
            await page.goto("https://ladypuzzle.pro/blossom-answers-hints", {
                waitUntil: "domcontentloaded"
            });
        } catch (e) {
            console.log("Navigation failed, retrying...");
            await new Promise(r => setTimeout(r, 3500));

            // ✅ Attempt #2 (retry)
            await page.goto("https://ladypuzzle.pro/blossom-answers-hints", {
                waitUntil: "domcontentloaded"
            });
        }

        // ✅ Wait for core DOM so scraping doesn't fail
        await page.waitForSelector(".leaf span", { timeout: 60000 });

        // ✅ Load all words
        while (true) {
            const moreWordsButton = await page.$('button.btn-secondary');
            if (!moreWordsButton) break;
            await moreWordsButton.click();
            await new Promise(r => setTimeout(r, 800));
        }

        // ✅ Click the reveal button in the first row
        const firstRowButton = await page.$('table.answers-table tbody tr:first-child button');
        if (firstRowButton) {
            await firstRowButton.click();
            await new Promise(r => setTimeout(r, 1200));
        }

        // ✅ SCRAPE
     const blossomData = await page.evaluate(() => {

    // ✅ Explicit type for txt
    function extractCleanWord(txt: string): string {
    return txt
        .replace(/REVEAL/gi, "")
        .trim()
        .split(/\s+/)[0]   // ✅ KEEP ONLY THE FIRST WORD (e.g. "LUMINOUS")
        .trim();
}


    // ✅ Force Element → HTMLElement
    const characterSpans = Array.from(
        document.querySelectorAll('.leaf span')
    ) as HTMLElement[];

    const characters = characterSpans.map(el => el.innerText);

    const centerLetter = characters[0];
    const outerLetters = characters.slice(1);

    const pangramEl = document.querySelector('.text-accent') as HTMLElement | null;
    const pangram = pangramEl ? pangramEl.innerText : "";

    let solution_word: string = "";

    // ✅ FORCE words typing
    const words: {
        word: string;
        length: number;
        points: number;
        isSolution: boolean;
    }[] = [];

    const rowEls = Array.from(
        document.querySelectorAll("table.answers-table tbody tr")
    ) as HTMLTableRowElement[];

    rowEls.forEach(tr => {
        const tds = tr.querySelectorAll("td") as NodeListOf<HTMLElement>;
        const rawWord = tds[0].innerText;
        const clean = extractCleanWord(rawWord);

        const hasReveal =
            rawWord.toLowerCase().includes("reveal") ||
            tr.querySelector("button") !== null;

        words.push({
            word: clean,
            length: parseInt(tds[1].innerText, 10),
            points: parseInt(tds[2].innerText, 10),
            isSolution: hasReveal
        });
    });

    // Set solution_word to the word in the first row, as it's revealed there
    if (words.length > 0) {
        solution_word = words[0].word;
    }

    const answers = words.map(w => w.word);

    return {
        centerLetter,
        outerLetters,
        pangram,
        solution_word,
        answers,
        words
    };
});


        await browser.close();

        fs.writeFileSync(filePath, JSON.stringify({ date, ...blossomData }, null, 2));
        console.log(`Successfully generated Blossom hints: ${filePath}`);

        // Trigger search engine indexing (Google Indexing API & Bing IndexNow)
        await pingDailyPuzzleUpdated('blossom-hints', date).catch((err: any) =>
          console.error('[Blossom] Error pinging search indexing:', err.message)
        );

    } catch (error) {
        console.error("Error in generateBlossomHints:", error);
    }
};

if (require.main === module) {
    generateBlossomHints();
}
