import axios from 'axios'
import * as db from '../core/db'
import ReqEvent from '../core/Event'

const store = {}
const geos = []

const getData = (() => {
  let joinKeys = []
  let urlTemplate = 'http://www.4dage.com/4DMap/data/{z}_{x}_{y}.json'
  let subdomains = ['a', 'b', 'c', 'd']
  let index = 0
  let requestings = []
  let event = new ReqEvent()

  async function ajaxGetData(key, url) {
    let index = requestings.indexOf(key)
    if (~index) {
      return new Promise((resolve, reject) => {
        event.once(key, (data, error) => {
          if (error) {
            reject(error)
          } else {
            data.data && (data.data.__once = false)
            resolve(data)
          }
        })
      })
    } else {
      requestings.push(key)

      function result(res, err) {
        if (err) {
          event.emit(key, null, res)
        } else {
          event.emit(key, res)
          res.data && (res.data.__once = true)
        }
        let index = requestings.indexOf(key)
        requestings.splice(index, 1)
        return res
      }

      return axios.get(url).then(res => result(res)).catch(res => result(res, 1))
    }
  }

  function getSubdomain() {
    index === subdomains.length && (index = 0)
    return subdomains[index++]
  }

  function storeCtrl(key, data) {
    db.add({id: key, ...data})
    store[key] = data
  }

  function obtain(key) {
    let index = joinKeys.indexOf(key)
    joinKeys.splice(index, 1)
    joinKeys.push(key)
  }

  async function getData(x, y, z) {
    let key = `${x}-${y}-${z}`
    let url = urlTemplate
      .replace('{s}', getSubdomain())
      .replace('{x}', x)
      .replace('{y}', y)
      .replace('{z}', z)

    let obj = await db.get(key)

    if (obj) {
      return obj
    } else {
      let data = await ajaxGetData(key, url).then(res => res.data)
      if (data && data.__once) {
        storeCtrl(key, data)
      }
      return data
    }
  }

  return getData
})();

function filter(features) {
  let result = []

  features.forEach(item => {
    if (!~geos.indexOf(item.id)) {
      geos.push(item.id)
      result.push(item)
    }
  })

  return result
}

async function getFeatures(x, y, z) {
  
  let data = await getData(x, y, z)
  let features = data && data.features ? filter(data.features) : []

  return features
}

function clearGeos (ids) {
  ids.forEach(id => {
    let index = geos.indexOf(id)
    if (~index) {
      geos.splice(index, 1)
    }
  })
}

export {
  getFeatures,
  clearGeos
}