function normalizePreviewText(value) {
  return String(value ?? '').replace(/\s+/g, ' ').trim()
}

function normalizePreviewKind(value) {
  const normalized = normalizePreviewText(value).toLowerCase()
  return ['image', 'pdf', 'file', 'unsupported'].includes(normalized) ? normalized : ''
}

export function inferPreviewKindFromUrl(url) {
  const normalized = normalizePreviewText(url).toLowerCase()
  if (!normalized) return ''
  if (normalized.startsWith('data:image/') || /\.(png|jpe?g|webp|gif|bmp|svg)(?:[?#].*)?$/i.test(normalized)) {
    return 'image'
  }
  if (normalized.startsWith('data:application/pdf') || /\.pdf(?:[?#].*)?$/i.test(normalized)) {
    return 'pdf'
  }
  return ''
}

export function inferPreviewKindFromBlob(blob) {
  const mediaType = normalizePreviewText(blob?.type).toLowerCase()
  if (mediaType.startsWith('image/')) return 'image'
  if (mediaType === 'application/pdf') return 'pdf'
  return ''
}

export function inferPreviewKindFromFile(file) {
  const mediaType = normalizePreviewText(file?.type).toLowerCase()
  const filename = normalizePreviewText(file?.name).toLowerCase()
  if (mediaType.startsWith('image/') || /\.(png|jpe?g|webp|gif|bmp|svg|heic)$/i.test(filename)) {
    return 'image'
  }
  if (mediaType.includes('pdf') || /\.pdf$/i.test(filename)) {
    return 'pdf'
  }
  return 'file'
}

export function isInlinePreviewUrl(url) {
  return normalizePreviewText(url).toLowerCase().startsWith('data:')
}

export function isTemporaryPreviewUrl(url) {
  return normalizePreviewText(url).toLowerCase().startsWith('blob:')
}

export function resolveDocumentPreviewKind(item = {}, fallback = '') {
  const explicit = normalizePreviewKind(item?.preview_kind || item?.previewKind)
  if (explicit) {
    return explicit
  }
  return inferPreviewKindFromUrl(resolveDocumentPreviewUrl(item)) || normalizePreviewKind(fallback)
}

export function resolveDocumentPreviewUrl(item = {}) {
  return normalizePreviewText(
    item?.preview_data_url ||
      item?.previewDataUrl ||
      item?.preview_url ||
      item?.previewUrl ||
      item?.receipt_preview_url ||
      item?.receiptPreviewUrl
  )
}

export function resolveDocumentPreviewAsset(item = {}, options = {}) {
  const sourceCandidates = [
    {
      source: 'inline',
      url: normalizePreviewText(item?.preview_data_url || item?.previewDataUrl)
    },
    {
      source: 'remote',
      url: normalizePreviewText(item?.preview_url || item?.previewUrl)
    },
    {
      source: 'receipt',
      url: normalizePreviewText(item?.receipt_preview_url || item?.receiptPreviewUrl)
    }
  ]
  const explicitKind = normalizePreviewKind(item?.preview_kind || item?.previewKind)

  for (const candidate of sourceCandidates) {
    if (!candidate.url) continue
    const kind = explicitKind || inferPreviewKindFromUrl(candidate.url)
    if (!['image', 'pdf'].includes(kind)) continue
    return {
      kind,
      url: candidate.url,
      source: candidate.source
    }
  }

  const fallbackUrl = normalizePreviewText(options.fallbackUrl)
  if (fallbackUrl) {
    const kind = inferPreviewKindFromUrl(fallbackUrl) || inferPreviewKindFromFile(options.fallbackFile)
    if (['image', 'pdf'].includes(kind)) {
      return {
        kind,
        url: fallbackUrl,
        source: 'file'
      }
    }
  }

  const fallbackKind = inferPreviewKindFromFile(options.fallbackFile)
  if (fallbackKind) {
    return {
      kind: fallbackKind,
      url: '',
      source: 'file'
    }
  }

  return null
}
