import { chromium, type BrowserContext } from 'playwright'

// A simple singleton manager for a persistent Chromium context with ref-counting.
// Prevents concurrent tasks from closing the shared window prematurely.

let contextPromise: Promise<BrowserContext> | null = null
let context: BrowserContext | null = null
let refCount = 0
let idleCloseTimer: NodeJS.Timeout | null = null

const USER_DATA_DIR = 'chrome-profile/douyin'
const DEFAULT_OPTIONS = { headless: true } as const

async function launchContext(): Promise<BrowserContext> {
  const ctx = await chromium.launchPersistentContext(USER_DATA_DIR, DEFAULT_OPTIONS)
  // When the context is closed externally, reset manager state
  ctx.on('close', () => {
    context = null
    contextPromise = null
    refCount = 0
    if (idleCloseTimer) {
      clearTimeout(idleCloseTimer)
      idleCloseTimer = null
    }
  })
  return ctx
}

export async function acquireBrowserContext(): Promise<BrowserContext> {
  // Cancel any pending idle close if a new consumer arrives
  if (idleCloseTimer) {
    clearTimeout(idleCloseTimer)
    idleCloseTimer = null
  }

  if (context) {
    refCount += 1
    return context
  }

  if (!contextPromise) {
    contextPromise = launchContext()
  }
  context = await contextPromise
  refCount += 1
  return context
}

export async function releaseBrowserContext(options?: { idleMillis?: number }): Promise<void> {
  const idleMillis = options?.idleMillis ?? 15_000
  refCount = Math.max(0, refCount - 1)

  if (refCount > 0 || !context) return

  // Delay the close to allow bursty workloads to reuse the context
  if (idleCloseTimer) {
    clearTimeout(idleCloseTimer)
    idleCloseTimer = null
  }
  idleCloseTimer = setTimeout(async () => {
    try {
      if (context && refCount === 0) {
        await context.close()
      }
    } finally {
      context = null
      contextPromise = null
      idleCloseTimer = null
    }
  }, idleMillis)
}
