import Taro from '@tarojs/taro'

const TEMP_URL_TTL_MS = 50 * 60 * 1000
const TEMP_URL_CACHE_MAX = 500

interface TempUrlCacheEntry {
  url: string
  expiresAt: number
  lastAccess: number
}

const tempUrlCache = new Map<string, TempUrlCacheEntry>()

function pruneTempUrlCache(now = Date.now()) {
  tempUrlCache.forEach((entry, key) => {
    if (entry.expiresAt <= now) tempUrlCache.delete(key)
  })

  if (tempUrlCache.size <= TEMP_URL_CACHE_MAX) return

  const overflow = tempUrlCache.size - TEMP_URL_CACHE_MAX
  ;[...tempUrlCache.entries()]
    .sort((a, b) => a[1].lastAccess - b[1].lastAccess)
    .slice(0, overflow)
    .forEach(([key]) => tempUrlCache.delete(key))
}

function readCachedTempUrl(fileId: string): string {
  const entry = tempUrlCache.get(fileId)
  if (!entry) return ''

  const now = Date.now()
  if (entry.expiresAt <= now) {
    tempUrlCache.delete(fileId)
    return ''
  }

  entry.lastAccess = now
  return entry.url
}

function writeCachedTempUrl(fileId: string, url: string) {
  const now = Date.now()
  tempUrlCache.set(fileId, {
    url,
    expiresAt: now + TEMP_URL_TTL_MS,
    lastAccess: now
  })
  pruneTempUrlCache(now)
}

export function isCloudFileId(value?: string): boolean {
  return Boolean(value && value.startsWith('cloud://'))
}

export async function resolveCloudFileUrls(urls: string[]): Promise<string[]> {
  pruneTempUrlCache()
  const cloud = Taro.cloud as any
  const unresolvedIds = [...new Set(urls.filter(isCloudFileId).filter(url => !readCachedTempUrl(url)))]

  if (unresolvedIds.length && cloud && typeof cloud.getTempFileURL === 'function') {
    try {
      const result = await cloud.getTempFileURL({ fileList: unresolvedIds })
      const fileList = Array.isArray(result?.fileList) ? result.fileList : []
      fileList.forEach((file: any) => {
        const fileId = file.fileID || file.fileId
        const tempUrl = file.tempFileURL || file.tempFileUrl
        if (fileId && tempUrl) writeCachedTempUrl(fileId, tempUrl)
      })
    } catch {
      // Leave unresolved cloud IDs blank so the renderer does not treat them as
      // page-relative local resources like /pages/plaza/cloud://...
    }
  }

  return urls.map(url => {
    if (!isCloudFileId(url)) return url
    return readCachedTempUrl(url) || ''
  })
}

export async function resolveCloudFileUrl(url?: string): Promise<string> {
  if (!url) return ''
  const [resolved] = await resolveCloudFileUrls([url])
  return resolved || ''
}

export async function resolveCloudFileUrlMap(urls: string[]): Promise<Map<string, string>> {
  const uniqueUrls = [...new Set(urls.filter(Boolean))]
  const resolvedUrls = await resolveCloudFileUrls(uniqueUrls)
  return new Map(uniqueUrls.map((url, index) => [url, resolvedUrls[index] || '']))
}
