/**
 * POST /api/offers/website-screenshot
 * Body: { url } — captures the first page of the given (public) website via the
 * free WordPress mShots service (no API key; it renders the page for us, so our
 * server never fetches the target URL itself), then crops the top into a wide
 * hero banner with sharp and returns it as a JPEG data URL. Used by the quote
 * modal to embed the customer's website into the Angebot PDF.
 *
 * mShots returns a placeholder GIF (307 → default.gif) while the screenshot is
 * still being generated — poll until a real JPEG/PNG arrives.
 */
import refreshTokenHelper from '../../utils/refreshTokenHelper'
import errorHandlingHelper from '../../utils/errorHandlingHelper'
import forceLogoutHelper from '../../utils/forceLogoutHelper'

// Matches the PDF hero: full content width (515 pt) at ~2.4:1.
const BANNER_WIDTH = 1200
const BANNER_HEIGHT = 500

const normalizeUrl = (raw: any): string | null => {
  let u = String(raw || '').trim()
  if (!u) return null
  if (!/^https?:\/\//i.test(u)) u = 'https://' + u
  try {
    const parsed = new URL(u)
    if (!/^https?:$/.test(parsed.protocol)) return null
    if (!parsed.hostname.includes('.')) return null
    return parsed.toString()
  } catch {
    return null
  }
}

const captureWebsite = async (url: string): Promise<Buffer> => {
  const endpoint = 'https://s0.wp.com/mshots/v1/' + encodeURIComponent(url) + '?w=1280&vpw=1280&vph=1024'
  let lastType = ''
  for (let attempt = 0; attempt < 8; attempt++) {
    if (attempt > 0) await new Promise((resolve) => setTimeout(resolve, 1500))
    const res: any = await $fetch.raw(endpoint, { responseType: 'arrayBuffer', timeout: 15000 })
    lastType = String(res.headers.get('content-type') || '')
    if (/image\/(jpe?g|png)/i.test(lastType) && res._data) {
      return Buffer.from(res._data)
    }
  }
  throw new Error(`screenshot service returned no image (last content-type: ${lastType})`)
}

const handleFunc = async (event: any, authToken: string | null = null) => {
  // Auth gate only — the capture itself needs no iDempiere call.
  const token = authToken ?? await getTokenHelper(event)
  if (!token) return { status: 401, message: 'Not authenticated' }

  const body = await readBody(event)
  const url = normalizeUrl(body?.url)
  if (!url) return { status: 400, message: 'A valid website URL is required' }

  try {
    const raw = await captureWebsite(url)
    const sharp = (await import('sharp')).default
    const banner = await sharp(raw)
      .resize(BANNER_WIDTH, BANNER_HEIGHT, { fit: 'cover', position: 'top' })
      .jpeg({ quality: 80 })
      .toBuffer()
    return { status: 200, dataUrl: 'data:image/jpeg;base64,' + banner.toString('base64'), url }
  } catch (err: any) {
    console.error('Website screenshot error:', err?.message || err)
    return { status: 502, message: 'Screenshot could not be captured' }
  }
}

export default defineEventHandler(async (event) => {
  let data: any = {}
  try {
    data = await handleFunc(event)
  } catch (err: any) {
    try {
      let authToken: any = await refreshTokenHelper(event)
      data = await handleFunc(event, authToken)
    } catch (error: any) {
      data = errorHandlingHelper(err?.data ?? err, error?.data ?? error)
      forceLogoutHelper(event, data)
    }
  }
  return data
})
