import { httpFetch } from '../../request'
import { decodeLyric } from './util'
import { decodeName } from '../..'

const headExp = /^.*\[id:\$\w+\]\n/

const parseLyric = str => {
  str = str.replace(/\r/g, '')
  if (headExp.test(str)) str = str.replace(headExp, '')
  let trans = str.match(/\[language:([\w=\\/+]+)\]/)
  let lyric
  let tlyric
  if (trans) {
    str = str.replace(/\[language:[\w=\\/+]+\]\n/, '')
    let json = JSON.parse(Buffer.from(trans[1], 'base64').toString())
    for (const item of json.content) {
      if (item.type == 1) {
        tlyric = item.lyricContent
        break
      }
    }
  }
  let i = 0
  let lxlyric = str.replace(/\[((\d+),\d+)\].*/g, str => {
    let result = str.match(/\[((\d+),\d+)\].*/)
    let time = parseInt(result[2])
    let ms = time % 1000
    time /= 1000
    let m = parseInt(time / 60).toString().padStart(2, '0')
    time %= 60
    let s = parseInt(time).toString().padStart(2, '0')
    time = `${m}:${s}.${ms}`
    if (tlyric) tlyric[i] = `[${time}]${tlyric[i++][0]}`
    return str.replace(result[1], time)
  })
  tlyric = tlyric ? tlyric.join('\n') : ''
  lxlyric = lxlyric.replace(/<(\d+,\d+),\d+>/g, '<$1>')
  lxlyric = decodeName(lxlyric)
  lyric = lxlyric.replace(/<\d+,\d+>/g, '')
  tlyric = decodeName(tlyric)
  return {
    lyric,
    tlyric,
    lxlyric,
  }
}

export default {
  getIntv(interval) {
    let intvArr = interval.split(':')
    let intv = 0
    let unit = 1
    while (intvArr.length) {
      intv += (intvArr.pop()) * unit
      unit *= 60
    }
    return parseInt(intv)
  },
  // getLyric(songInfo, tryNum = 0) {
  //   let requestObj = httpFetch(`http://m.kugou.com/app/i/krc.php?cmd=100&keyword=${encodeURIComponent(songInfo.name)}&hash=${songInfo.hash}&timelength=${songInfo._interval || this.getIntv(songInfo.interval)}&d=0.38664927426725626`, {
  //     headers: {
  //       'KG-RC': 1,
  //       'KG-THash': 'expand_search_manager.cpp:852736169:451',
  //       'User-Agent': 'KuGou2012-9020-ExpandSearchManager',
  //     },
  //   })
  //   requestObj.promise = requestObj.promise.then(({ body, statusCode }) => {
  //     if (statusCode !== 200) {
  //       if (tryNum > 5) return Promise.reject('歌词获取失败')
  //       let tryRequestObj = this.getLyric(songInfo, ++tryNum)
  //       requestObj.cancelHttp = tryRequestObj.cancelHttp.bind(tryRequestObj)
  //       return tryRequestObj.promise
  //     }
  //     return {
  //       lyric: body,
  //       tlyric: '',
  //     }
  //   })
  //   return requestObj
  // },
  searchLyric(name, hash, time, tryNum = 0) {
    let requestObj = httpFetch(`http://lyrics.kugou.com/search?ver=1&man=yes&client=pc&keyword=${encodeURIComponent(name)}&hash=${hash}&timelength=${time}`, {
      headers: {
        'KG-RC': 1,
        'KG-THash': 'expand_search_manager.cpp:852736169:451',
        'User-Agent': 'KuGou2012-9020-ExpandSearchManager',
      },
    })
    requestObj.promise = requestObj.promise.then(({ body, statusCode }) => {
      if (statusCode !== 200) {
        if (tryNum > 5) return Promise.reject('歌词获取失败')
        let tryRequestObj = this.searchLyric(name, hash, time, ++tryNum)
        requestObj.cancelHttp = tryRequestObj.cancelHttp.bind(tryRequestObj)
        return tryRequestObj.promise
      }
      if (body.candidates.length) {
        let info = body.candidates[0]
        return { id: info.id, accessKey: info.accesskey }
      }
      return null
    })
    return requestObj
  },
  getLyricDownload(id, accessKey, tryNum = 0) {
    let requestObj = httpFetch(`http://lyrics.kugou.com/download?ver=1&client=pc&id=${id}&accesskey=${accessKey}&fmt=krc&charset=utf8`, {
      headers: {
        'KG-RC': 1,
        'KG-THash': 'expand_search_manager.cpp:852736169:451',
        'User-Agent': 'KuGou2012-9020-ExpandSearchManager',
      },
    })
    requestObj.promise = requestObj.promise.then(({ body, statusCode }) => {
      if (statusCode !== 200) {
        if (tryNum > 5) return Promise.reject('歌词获取失败')
        let tryRequestObj = this.getLyric(id, accessKey, ++tryNum)
        requestObj.cancelHttp = tryRequestObj.cancelHttp.bind(tryRequestObj)
        return tryRequestObj.promise
      }

      return decodeLyric(body.content).then(result => parseLyric(result))
    })
    return requestObj
  },
  getLyric(songInfo, tryNum = 0) {
    let requestObj = this.searchLyric(songInfo.name, songInfo.hash, songInfo._interval || this.getIntv(songInfo.interval))

    requestObj.promise = requestObj.promise.then(result => {
      if (!result) return Promise.reject(new Error('Get lyric failed'))

      let requestObj2 = this.getLyricDownload(result.id, result.accessKey)

      requestObj.cancelHttp = requestObj2.cancelHttp.bind(requestObj2)

      return requestObj2.promise
    })
    return requestObj
  },
}
