import {toUint8Array} from 'js-base64'
import {thumbHashToDataURL} from 'thumbhash'

/**
 * Converts a thumbhash string to a data URL for use as an image placeholder
 * @param thumbhash Base64 encoded thumbhash string
 * @returns Data URL that can be used as image source or undefined if conversion fails
 */
export function getThumbhashDataURL(thumbhash?: string): string | undefined {
  if (!thumbhash) return

  try {
    const thumbhashArray = toUint8Array(thumbhash)
    return thumbHashToDataURL(thumbhashArray)
  } catch (error) {
    console.warn('Failed to decode thumbhash to data URL', error)
    return undefined
  }
}

/** Converts a file to a data URI
 * @param file The file to convert
 * @returns A promise that resolves to the data URI string
 */
export function fileToDataUri(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onloadend = () => resolve(reader.result as string)
    reader.onerror = reject
    reader.readAsDataURL(file)
  })
}

const ImageSizes = {
  xxsUrl: 32,
  xsUrl: 64,
  sUrl: 128,
  xxsmUrl: 256,
  xsmUrl: 384,
  smUrl: 512,
  mUrl: 640,
  lUrl: 1080,
  xlUrl: 2048,
} as const

type Key = keyof typeof ImageSizes

/**
 * Acceptable offset for image sizes. An image could use the size that is within this offset.
 */
const offsetPercentage = 0.05

const sortedImageSizes = Object.entries(ImageSizes).sort(
  ([, firstSize], [, secondSize]) => firstSize - secondSize
)

const getImageSizeKeyWithSize = (size: number): Key => {
  for (const [key, imgSize] of sortedImageSizes) {
    const upperBoundSize = imgSize + imgSize * offsetPercentage
    if (size <= upperBoundSize) return key as Key
  }

  return 'xlUrl'
}

const resizeImage = (imageUrl: string, width: number) => {
  const pattern = new RegExp(/\?+/g)
  const delimiter = pattern.test(imageUrl) ? '&' : '?'
  return `${imageUrl}${delimiter}width=${width}`
}

/**
 * Optimizes Shopify CDN image URLs by adding a width parameter based on screen size
 * @param url The image URL to optimize
 * @returns The optimized URL with width parameter if it's a Shopify CDN image, otherwise returns the original URL
 */

export const getResizedImageUrl = (url?: string): string => {
  if (!url) return ''

  // Only process Shopify CDN images
  if (!url.startsWith('https://cdn.shopify.com')) {
    return url
  }

  const width = window.innerWidth ?? screen.width

  const key = getImageSizeKeyWithSize(width)

  return resizeImage(url, ImageSizes[key])
}
