text: import axios from 'axios'
  import Dexie from 'dexie'
  import store from '@render/store'
  
  const db = new Dexie('EstherMusic')
  
  db.version(4).stores({
      trackDetail: '&id, updateTime',
      lyric: '&id, updateTime',
      album: '&id, updateTime',
  })
  
  db.version(3)
      .stores({
          trackSources: '&id, createTime',
      })
      .upgrade((tx) =>
          tx
              .table('trackSources')
              .toCollection()
              .modify((track) => !track.createTime && (track.createTime = new Date().getTime())),
      )
  
  db.version(1).stores({
      trackSources: '&id',
  })
  
  let tracksCacheBytes = 0
  
  async function deleteExcessCache() {
      if (
          store.state.settings.cacheLimit === false ||
          tracksCacheBytes < store.state.settings.cacheLimit * Math.pow(1024, 2)
      ) {
          return
      }
      try {
          const delCache = await db.trackSources.orderBy('createTime').first()
          await db.trackSources.delete(delCache.id)
          tracksCacheBytes -= delCache.source.byteLength
          console.debug(
              `[debug][db.js] deleteExcessCacheSucces, track: ${delCache.name}, size: ${delCache.source.byteLength}, cacheSize:${tracksCacheBytes}`,
          )
          deleteExcessCache()
      } catch (error) {
          console.debug('[debug][db.js] deleteExcessCacheFailed', error)
      }
  }
  
  export function cacheTrackSource(trackInfo, url, bitRate, from = 'netease') {
      const name = trackInfo.name
      let artist
      if (trackInfo.ar[0]?.name) {
          artist = trackInfo.ar[0]?.name
      } else if (trackInfo.artists) {
          artist = trackInfo.artists[0]?.name
      } else {
          artist = trackInfo.pc.ar
      }
      let cover = trackInfo.al.picUrl
      if (cover.slice(0, 5) !== 'https') {
          cover = 'https' + cover.slice(4)
      }
      axios.get(`${cover}?param=512y512`)
      axios.get(`${cover}?param=224y224`)
      axios.get(`${cover}?param=1024y1024`)
      return axios
          .get(url, {
              responseType: 'arraybuffer',
          })
          .then((response) => {
              db.trackSources.put({
                  id: trackInfo.id,
                  source: response.data,
                  bitRate,
                  from,
                  name,
                  artist,
                  createTime: new Date().getTime(),
              })
              console.debug(`[debug][db.js] cached track 👉 ${name} by ${artist}`)
              tracksCacheBytes += response.data.byteLength
              deleteExcessCache()
              return {
                  trackID: trackInfo.id,
                  source: response.data,
                  bitRate,
              }
          })
  }
  
  export function getTrackSource(id) {
      return db.trackSources.get(Number(id)).then((track) => {
          if (!track) {
              return null
          }
          console.debug(`[debug][db.js] get track from cache 👉 ${track.name} by ${track.artist}`)
          return track
      })
  }
  
  export function cacheTrackDetail(track, privileges) {
      db.trackDetail.put({
          id: track.id,
          detail: track,
          privileges: privileges,
          updateTime: new Date().getTime(),
      })
  }
  
  export function getTrackDetailFromCache(ids) {
      return db.trackDetail
          .filter((track) => {
              return ids.includes(String(track.id))
          })
          .toArray()
          .then((tracks) => {
              const result = { songs: [], privileges: [] }
              ids.map((id) => {
                  const one = tracks.find((t) => String(t.id) === id)
                  result.songs.push(one?.detail)
                  result.privileges.push(one?.privileges)
              })
              if (result.songs.includes(undefined)) {
                  return undefined
              }
              return result
          })
  }
  
  export function cacheLyric(id, lyrics) {
      db.lyric.put({
          id,
          lyrics,
          updateTime: new Date().getTime(),
      })
  }
  
  export function getLyricFromCache(id) {
      return db.lyric.get(Number(id)).then((result) => {
          if (!result) return undefined
          return result.lyrics
      })
  }
  
  export function cacheAlbum(id, album) {
      db.album.put({
          id: Number(id),
          album,
          updateTime: new Date().getTime(),
      })
  }
  
  export function getAlbumFromCache(id) {
      return db.album.get(Number(id)).then((result) => {
          if (!result) return undefined
          return result.album
      })
  }
  
  export function countDBSize() {
      const trackSizes = []
      return db.trackSources
          .each((track) => {
              trackSizes.push(track.source.byteLength)
          })
          .then(() => {
              const res = {
                  bytes: trackSizes.reduce((s1, s2) => s1 + s2, 0),
                  length: trackSizes.length,
              }
              tracksCacheBytes = res.bytes
              console.debug(`[debug][db.js] load tracksCacheBytes: ${tracksCacheBytes}`)
              return res
          })
  }
  
  export function clearDB() {
      return new Promise((resolve) => {
          db.tables.forEach(function (table) {
              table.clear()
          })
          resolve()
      })
  }
  