import browser from 'webextension-polyfill'
import { isLikelyDownloadUrl, normalizeUrl } from '../lib/downloadIntent'

const CAPTURE_TTL_MS = 8000
const captureInFlight = new Map<string, number>()

function pruneCaptureInFlight(): void {
  const now = Date.now()
  for (const [url, expiresAt] of captureInFlight.entries()) {
    if (expiresAt <= now) captureInFlight.delete(url)
  }
}

async function sendCapture(url: string, referer: string): Promise<boolean> {
  const normalized = normalizeUrl(url, window.location.href)
  if (!normalized) return false

  pruneCaptureInFlight()
  if (captureInFlight.has(normalized)) return true
  captureInFlight.set(normalized, Date.now() + CAPTURE_TTL_MS)

  try {
    const result = (await browser.runtime.sendMessage({
      type: 'capture-link-download',
      url: normalized,
      referer: referer || document.referrer || window.location.href,
    })) as { ok?: boolean }
    if (result?.ok) return true
  } catch {
    // ignored
  }

  captureInFlight.delete(normalized)
  return false
}

function findAnchor(target: EventTarget | null): HTMLAnchorElement | null {
  if (!target) return null
  if (target instanceof HTMLAnchorElement) return target
  if (target instanceof Element) return target.closest('a[href]') as HTMLAnchorElement | null
  return null
}

function shouldIgnoreHotkey(event: MouseEvent | KeyboardEvent): boolean {
  return !!(event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)
}

async function interceptAnchorEvent(event: MouseEvent): Promise<void> {
  if (event.defaultPrevented) return
  if (shouldIgnoreHotkey(event)) return

  const anchor = findAnchor(event.target)
  if (!anchor) return
  const href = anchor.href || ''
  if (!href || !isLikelyDownloadUrl(href, window.location.href)) return

  event.preventDefault()
  event.stopImmediatePropagation()
  event.stopPropagation()
  await sendCapture(href, document.referrer || window.location.href)
}

function interceptMouseLike(event: MouseEvent): void {
  const anchor = findAnchor(event.target)
  if (!anchor) return
  const href = anchor.href || ''
  if (!href || !isLikelyDownloadUrl(href, window.location.href)) return
  if (shouldIgnoreHotkey(event)) return

  event.preventDefault()
  event.stopImmediatePropagation()
  event.stopPropagation()
  void sendCapture(href, document.referrer || window.location.href)
}

document.addEventListener('pointerdown', (event: PointerEvent) => {
  if (event.button !== 0) return
  interceptMouseLike(event)
}, true)

document.addEventListener('mousedown', (event: MouseEvent) => {
  if (event.button !== 0) return
  interceptMouseLike(event)
}, true)

document.addEventListener('click', (event: MouseEvent) => {
  if (event.button !== 0) return
  void interceptAnchorEvent(event)
}, true)

document.addEventListener('keydown', (event: KeyboardEvent) => {
  if (event.key !== 'Enter') return
  if (event.defaultPrevented) return
  if (shouldIgnoreHotkey(event)) return

  const anchor = findAnchor(event.target)
  if (!anchor) return
  const href = anchor.href || ''
  if (!href || !isLikelyDownloadUrl(href, window.location.href)) return

  event.preventDefault()
  event.stopImmediatePropagation()
  event.stopPropagation()
  void sendCapture(href, document.referrer || window.location.href)
}, true)

document.addEventListener('auxclick', (event: MouseEvent) => {
  if (event.button !== 1) return
  void interceptAnchorEvent(event)
}, true)

function installProgrammaticInterceptors(): void {
  try {
    const originalOpen = window.open.bind(window)
    window.open = function gomdownInterceptOpen(url?: string | URL, target?: string, features?: string): Window | null {
      const raw = String(url || '').trim()
      if (raw && isLikelyDownloadUrl(raw, window.location.href)) {
        void sendCapture(raw, window.location.href)
        return null
      }
      return originalOpen(url as string, target, features)
    }
  } catch {
    // ignored
  }

  try {
    const originalAnchorClick = HTMLAnchorElement.prototype.click
    HTMLAnchorElement.prototype.click = function gomdownInterceptAnchorClick(): void {
      const href = this.href || this.getAttribute('href') || ''
      if (href && isLikelyDownloadUrl(href, window.location.href)) {
        void sendCapture(href, document.referrer || window.location.href)
        return
      }
      originalAnchorClick.call(this)
    }
  } catch {
    // ignored
  }
}

installProgrammaticInterceptors()
