/// <reference lib="dom" />

import fs from 'node:fs/promises'

import { buildProofHtml } from './session-proof-html.js'

type BrowserPageLike = {
  evaluate: <T = unknown>(callback: any, arg?: unknown) => Promise<T>
  waitForTimeout: (milliseconds: number) => Promise<void>
  setViewportSize: (viewport: { width: number; height: number }) => Promise<void>
  setContent: (html: string, options?: { waitUntil?: string }) => Promise<unknown>
  screenshot: (options: { path: string; fullPage?: boolean }) => Promise<unknown>
  close: () => Promise<void>
}

type BrowserContextLike = {
  newPage: () => Promise<BrowserPageLike>
}

type ComposeProofScreenshotOptions = {
  outputPath: string
  redeemImagePath: string
  timeImagePath: string
  redeemMessage?: string
  timePageUrl: string
}

export async function showResultDialog(page: BrowserPageLike, message: string): Promise<void> {
  await page.evaluate((text) => {
    document.querySelectorAll('iframe').forEach((element) => element.remove())
    document.querySelectorAll('.pop').forEach((element) => {
      if (element instanceof HTMLElement) {
        element.style.display = 'none'
      }
    })

    let card = document.getElementById('codex-redeem-result')

    if (!card) {
      card = document.createElement('div')
      card.id = 'codex-redeem-result'
      card.innerHTML = `
        <div class="codex-redeem-result__eyebrow">Tencent Browser Session</div>
        <div class="codex-redeem-result__title">兑换结果</div>
        <div class="codex-redeem-result__message"></div>
      `
      document.body.appendChild(card)
    }

    const messageNode = card.querySelector('.codex-redeem-result__message')

    if (messageNode) {
      messageNode.textContent = text
    }

    Object.assign(card.style, {
      position: 'fixed',
      left: '50%',
      top: '50%',
      transform: 'translate(-50%, -50%)',
      zIndex: '99999',
      width: 'min(560px, calc(100vw - 80px))',
      padding: '32px 36px',
      borderRadius: '24px',
      background: 'rgba(10, 18, 28, 0.92)',
      boxShadow: '0 24px 80px rgba(0, 0, 0, 0.35)',
      border: '1px solid rgba(109, 241, 202, 0.25)',
      color: '#f4fbff',
      fontFamily: '"PingFang SC", "Microsoft YaHei", sans-serif',
    })

    const styleId = 'codex-redeem-result-style'

    if (!document.getElementById(styleId)) {
      const style = document.createElement('style')
      style.id = styleId
      style.textContent = `
        #codex-redeem-result .codex-redeem-result__eyebrow {
          font-size: 12px;
          letter-spacing: 0.18em;
          text-transform: uppercase;
          color: #6df1ca;
          margin-bottom: 12px;
        }
        #codex-redeem-result .codex-redeem-result__title {
          font-size: 34px;
          font-weight: 700;
          margin-bottom: 16px;
        }
        #codex-redeem-result .codex-redeem-result__message {
          font-size: 24px;
          line-height: 1.5;
          color: #ffffff;
        }
      `
      document.head.appendChild(style)
    }

    window.scrollTo(0, 0)
  }, message)

  await page.waitForTimeout(600)
}

export async function composeProofScreenshot(
  browserContext: BrowserContextLike,
  { outputPath, redeemImagePath, timeImagePath, redeemMessage, timePageUrl }: ComposeProofScreenshotOptions,
): Promise<void> {
  const [redeemImageBase64, timeImageBase64] = await Promise.all([
    fs.readFile(redeemImagePath, 'base64'),
    fs.readFile(timeImagePath, 'base64'),
  ])

  const composePage = await browserContext.newPage()

  try {
    await composePage.setViewportSize({ width: 1520, height: 1900 })
    await composePage.setContent(
      buildProofHtml({
        redeemImageBase64,
        timeImageBase64,
        redeemMessage,
        timePageUrl,
      }),
      { waitUntil: 'domcontentloaded' },
    )
    await composePage.screenshot({ path: outputPath, fullPage: true })
  } finally {
    await composePage.close().catch(() => null)
  }
}
