'use strict'

/**
 * render-nova-card.cjs
 *
 * Headless Playwright screenshot renderer for Nova Cards.
 * Visits the signed render-frame URL, waits for React + fonts to finish,
 * then screenshots the [data-card-canvas] element and writes a PNG to disk.
 *
 * Usage:
 *   node scripts/render-nova-card.cjs \
 *     --url=<signed-render-frame-url> \
 *     --out=<absolute-path-to-output.png> \
 *     [--width=1080] [--height=1080]
 *
 * Exit codes: 0 = success, 1 = error (message on stderr).
 * On success writes JSON to stdout: { "success": true, "out": "...", "width": N, "height": N }
 */

const { chromium } = require('@playwright/test')
const fs = require('fs')
const path = require('path')

// ── Parse CLI args ────────────────────────────────────────────────────────────
const argv = Object.fromEntries(
  process.argv.slice(2)
    .filter((a) => a.startsWith('--'))
    .map((a) => {
      const eq = a.indexOf('=')
      return eq === -1 ? [a.slice(2), true] : [a.slice(2, eq), a.slice(eq + 1)]
    }),
)

const { url, out } = argv
const width  = parseInt(argv.width  || '1080', 10)
const height = parseInt(argv.height || '1080', 10)

if (!url || !out) {
  process.stderr.write(
    'Usage: render-nova-card.cjs --url=<url> --out=<png-path> [--width=1080] [--height=1080]\n',
  )
  process.exit(1)
}

// ── Render ────────────────────────────────────────────────────────────────────
;(async () => {
  const browser = await chromium.launch({ headless: true })

  try {
    const page = await browser.newPage({
      viewport: { width, height },
      deviceScaleFactor: 1,
    })

    // Navigate and wait for network to settle (background images, fonts).
    await page.goto(url, { waitUntil: 'networkidle', timeout: 30_000 })

    // Wait for React to finish painting the canvas element.
    const canvas = page.locator('[data-card-canvas]').first()
    await canvas.waitFor({ state: 'visible', timeout: 15_000 })

    // Wait for all web fonts to finish loading before we capture layout.
    await page.evaluate(async () => {
      const requiredFonts = [
        'Anton',
        'Caveat',
        'Cormorant Garamond',
        'Inter',
        'Libre Franklin',
        'Playfair Display',
      ]

      await Promise.all(requiredFonts.map((family) => document.fonts?.load?.(`16px "${family}"`) || Promise.resolve()))

      if (document.fonts?.ready) {
        await document.fonts.ready
      }
    })

    // One extra frame so CSS transforms / container queries resolve fully.
    await page.waitForTimeout(300)

    // Screenshot only the canvas element; Playwright clips to the element bounding box.
    const png = await canvas.screenshot({ type: 'png' })

    fs.mkdirSync(path.dirname(out), { recursive: true })
    fs.writeFileSync(out, png)

    process.stdout.write(JSON.stringify({ success: true, out, width, height }) + '\n')
  } finally {
    await browser.close()
  }
})().catch((err) => {
  process.stderr.write((err?.message ?? String(err)) + '\n')
  process.exit(1)
})
