import { useEffect, useState } from 'react'

/**
 * Detect whether a remote logo image is light-content or dark-content by
 * sampling the opaque pixels' luminance. Cached per URL so each logo is
 * sampled at most once. Used to pick a contrasting pad color so neither
 * white-on-white nor black-on-black happens.
 */

export type LogoTone = 'light' | 'dark' | 'unknown'

const cache = new Map<string, LogoTone>()
const inflight = new Map<string, Promise<LogoTone>>()

export function useLogoTone(url: string | null | undefined): LogoTone {
  const initial = url ? cache.get(url) : undefined
  const [tone, setTone] = useState<LogoTone>(initial ?? 'unknown')

  useEffect(() => {
    if (!url) return
    const cached = cache.get(url)
    if (cached) {
      setTone(cached)
      return
    }
    let cancelled = false
    sampleLogoTone(url).then(t => {
      cache.set(url, t)
      if (!cancelled) setTone(t)
    })
    return () => { cancelled = true }
  }, [url])

  return tone
}

function sampleLogoTone(url: string): Promise<LogoTone> {
  const existing = inflight.get(url)
  if (existing) return existing

  const promise = new Promise<LogoTone>(resolve => {
    const img = new Image()
    img.crossOrigin = 'anonymous'
    img.onload = () => {
      try {
        const maxSide = 64
        const ratio = Math.min(maxSide / img.naturalWidth, maxSide / img.naturalHeight, 1)
        const w = Math.max(1, Math.round(img.naturalWidth * ratio))
        const h = Math.max(1, Math.round(img.naturalHeight * ratio))
        const canvas = document.createElement('canvas')
        canvas.width = w
        canvas.height = h
        const ctx = canvas.getContext('2d')
        if (!ctx) return resolve('unknown')
        ctx.drawImage(img, 0, 0, w, h)
        const { data } = ctx.getImageData(0, 0, w, h)
        let lumWeighted = 0
        let alphaSum = 0
        for (let i = 0; i < data.length; i += 4) {
          const a = data[i + 3]
          if (a < 16) continue
          const l = 0.299 * data[i] + 0.587 * data[i + 1] + 0.114 * data[i + 2]
          lumWeighted += l * a
          alphaSum += a
        }
        if (alphaSum === 0) return resolve('unknown')
        const avg = lumWeighted / alphaSum
        resolve(avg > 128 ? 'light' : 'dark')
      } catch {
        // CORS or other read failure
        resolve('unknown')
      } finally {
        inflight.delete(url)
      }
    }
    img.onerror = () => {
      inflight.delete(url)
      resolve('unknown')
    }
    img.src = url
  })

  inflight.set(url, promise)
  return promise
}
