#!/usr/bin/env python3
"""Render JS-heavy pages (TikTok help/ads) and dump title, headings, links, text."""
import asyncio
import json
import re
import sys

from playwright.async_api import async_playwright

UA = ("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) "
      "Chrome/124.0.0.0 Safari/537.36")


async def run(urls, out):
    hasil = {}
    async with async_playwright() as pw:
        br = await pw.chromium.launch()
        ctx = await br.new_context(user_agent=UA, locale="id-ID")
        page = await ctx.new_page()
        for u in urls:
            entry = {"url": u}
            try:
                await page.goto(u, wait_until="domcontentloaded", timeout=60000)
                await page.wait_for_timeout(4000)
                entry["judul"] = (await page.title())[:160]
                entry["h"] = await page.eval_on_selector_all(
                    "h1,h2,h3",
                    "els => els.slice(0,25).map(e => e.innerText.trim().slice(0,120)).filter(Boolean)")
                entry["teks"] = await page.evaluate(
                    """() => {
                        const sel = ['main', 'article', '[class*="article-body"]', '[class*="articleBody"]', '[id*="article"]'];
                        for (const s of sel) {
                            const el = document.querySelector(s);
                            if (el && el.innerText && el.innerText.trim().length > 200) {
                                return el.innerText.replace(/\\s+/g, ' ').slice(0, 6000);
                            }
                        }
                        return document.body.innerText.replace(/\\s+/g, ' ').slice(0, 6000);
                    }"""
                )
                links = await page.eval_on_selector_all(
                    "a[href]",
                    "els => els.map(e => (e.innerText.trim().replace(/\\s+/g,' ').slice(0,70)) + ' :: ' + e.href)"
                    ".filter(s => s.length > 8)")
                seen, uniq = set(), []
                for l in links:
                    if l not in seen:
                        seen.add(l)
                        uniq.append(l)
                entry["tautan"] = uniq[:120]
            except Exception as exc:  # noqa: BLE001
                entry["error"] = str(exc)[:160]
            hasil[u] = entry
        await br.close()
    with open(out, "w", encoding="utf-8") as fh:
        fh.write(json.dumps(hasil, indent=1, ensure_ascii=False))
    print("->", out)


if __name__ == "__main__":
    sys.exit(asyncio.run(run(sys.argv[2:], sys.argv[1])))
