import { getNitroOrigin } from "#site-config/server/composables";
import { withQuery } from "ufo";
import { toValue } from "vue";
import { buildOgImageUrl } from "../../../shared.js";
import { useOgImageRuntimeConfig } from "../../utils.js";
function isPlaywrightPage(page) {
  return typeof page.setViewportSize === "function";
}
async function setViewport(page, width, height) {
  if (isPlaywrightPage(page)) {
    await page.setViewportSize({ width, height });
  } else {
    await page.setViewport({ width, height });
  }
}
async function waitForIdle(page) {
  if (isPlaywrightPage(page)) {
    await page.waitForLoadState("networkidle");
  } else {
    await new Promise((resolve) => setTimeout(resolve, 100));
  }
}
async function gotoWithIdle(page, url, timeout) {
  if (isPlaywrightPage(page)) {
    await page.goto(url, { timeout, waitUntil: "networkidle" });
  } else {
    await page.goto(url, { timeout, waitUntil: "networkidle0" });
  }
}
async function waitForDelay(page, ms) {
  if (isPlaywrightPage(page)) {
    await page.waitForTimeout(ms);
  } else {
    await new Promise((resolve) => setTimeout(resolve, ms));
  }
}
async function takeScreenshot(page, selector, options) {
  const puppeteerOptions = { ...options };
  if (!isPlaywrightPage(page)) {
    delete puppeteerOptions.animations;
  }
  if (selector) {
    if (isPlaywrightPage(page)) {
      return await page.locator(selector).screenshot(puppeteerOptions);
    } else {
      const element = await page.$(selector);
      if (!element) {
        throw new Error(`Element not found: ${selector}`);
      }
      return await element.screenshot(puppeteerOptions);
    }
  }
  return await page.screenshot(puppeteerOptions);
}
export async function createScreenshot({ basePath, e, options, extension }, browser) {
  const { colorPreference, defaults } = useOgImageRuntimeConfig();
  const path = options.component === "PageScreenshot" ? basePath : buildOgImageUrl(options, "html", false, defaults).url;
  let page;
  if (typeof browser.newPage === "function" && browser.newPage.length === 0) {
    page = await browser.newPage();
    if (colorPreference) {
      await page.emulateMediaFeatures?.([
        { name: "prefers-color-scheme", value: colorPreference }
      ]);
    }
  } else {
    page = await browser.newPage({
      colorScheme: colorPreference || "no-preference",
      baseURL: getNitroOrigin(e)
    });
  }
  try {
    if (import.meta.prerender && !options.html) {
      options.html = await e.$fetch(path).catch(() => void 0);
    }
    await setViewport(
      page,
      toValue(options.width) || 1200,
      toValue(options.height) || 600
    );
    if (options.html) {
      const html = options.html;
      if (isPlaywrightPage(page)) {
        await page.evaluate((html2) => {
          document.open("text/html");
          document.write(html2);
          document.close();
        }, html);
        await waitForIdle(page);
      } else {
        await page.setContent(html, { waitUntil: "networkidle0" });
      }
    } else {
      const url = isPlaywrightPage(page) ? withQuery(path, options.props || {}) : `${getNitroOrigin(e)}${withQuery(path, options.props || {})}`;
      await gotoWithIdle(page, url, 1e4);
    }
    const screenshotOptions = {
      timeout: 1e4,
      animations: "disabled",
      type: extension === "png" ? "png" : "jpeg"
    };
    const _options = options.screenshot || {};
    if (_options.delay)
      await waitForDelay(page, _options.delay);
    if (_options.mask) {
      await page.evaluate((mask) => {
        for (const el of document.querySelectorAll(mask))
          el.style.display = "none";
      }, _options.mask);
    }
    return await takeScreenshot(page, _options.selector, screenshotOptions);
  } finally {
    await page.close();
  }
}
