const DB_NAME = 'uan-app-icons'
const STORE = 'blobs'
const DB_VERSION = 1

let dbPromise: Promise<IDBDatabase> | null = null

/** 稳定缓存键：`app_id` + 对象存储路径（不含预签名） */
export function getStableKey(appId: string, objectKey: string): string {
  return `${appId}::${objectKey}`
}

export function isBlobDisplayUrl(url: string): boolean {
  return !!url && url.startsWith('blob:')
}

function openDb(): Promise<IDBDatabase> {
  if (typeof indexedDB === 'undefined') {
    return Promise.reject(new Error('indexedDB unsupported'))
  }
  if (!dbPromise) {
    dbPromise = new Promise((resolve, reject) => {
      const req = indexedDB.open(DB_NAME, DB_VERSION)
      req.onerror = () => reject(req.error)
      req.onsuccess = () => resolve(req.result)
      req.onupgradeneeded = () => {
        const db = req.result
        if (!db.objectStoreNames.contains(STORE)) {
          db.createObjectStore(STORE)
        }
      }
    })
  }
  return dbPromise
}

async function getCachedBlob(appId: string, objectKey: string): Promise<Blob | undefined> {
  try {
    const db = await openDb()
    return await new Promise((resolve, reject) => {
      const tx = db.transaction(STORE, 'readonly')
      const req = tx.objectStore(STORE).get(getStableKey(appId, objectKey))
      req.onerror = () => reject(req.error)
      req.onsuccess = () => resolve(req.result as Blob | undefined)
    })
  } catch {
    return undefined
  }
}

async function putCachedBlob(appId: string, objectKey: string, blob: Blob): Promise<void> {
  const db = await openDb()
  await new Promise<void>((resolve, reject) => {
    const tx = db.transaction(STORE, 'readwrite')
    tx.oncomplete = () => resolve()
    tx.onerror = () => reject(tx.error)
    tx.onabort = () => reject(tx.error)
    tx.objectStore(STORE).put(blob, getStableKey(appId, objectKey))
  })
}

/**
 * 返回用于展示的 URL：`https` 直链或可 revoke 的 `blob:` URL（带 object_key 时在 IndexedDB 中复用）。
 */
export async function resolveLogoDisplayUrl(opts: {
  appId: string
  iconObjectKey?: string | null
  iconUrl?: string | null
}): Promise<string> {
  const u = opts.iconUrl?.trim() ?? ''
  if (!u) {
    return ''
  }

  const key = opts.iconObjectKey?.trim()
  if (!key) {
    return u
  }

  const appId = opts.appId?.trim() || '_'

  const cached = await getCachedBlob(appId, key)
  if (cached) {
    return URL.createObjectURL(cached)
  }

  try {
    const res = await fetch(u, { mode: 'cors' })
    if (!res.ok) {
      return u
    }
    const blob = await res.blob()
    try {
      await putCachedBlob(appId, key, blob)
    } catch {
      /* 存储失败仍展示本次下载 */
    }
    return URL.createObjectURL(blob)
  } catch {
    return u
  }
}
