// From https://www.sitepoint.com/cache-fetched-ajax-requests/
// All credits to: Peter Bengtsson
// Added Content-type to headers so it can go to traditional validation like fetch does
// Add some debugging messages: activate with { verbose: true }
// Add a request to be able to add headers instead of just calling URL

const CachedFetch = (url, options) => {

  let expiry = options.seconds || 5 * 60 // 5 min default
  let logger = (options.verbose) ? console.log : function(){};
  // logger( url, expiry, options);
  // Use the URL as the cache key to sessionStorage
  let cacheKey = url
  let cached = localStorage.getItem(cacheKey)
  let whenCached = localStorage.getItem(cacheKey + ':ts')
  if (cached !== null && whenCached !== null) {
    // it was in sessionStorage! Yay!
    // Even though 'whenCached' is a string, this operation
    // works because the minus sign converts the
    // string to an integer and it will work.
    let age = (Date.now() - whenCached) / 1000
    if (age < expiry) {
      let response = new Response(new Blob([cached]))
      response.headers.set("Content-Type","application/json; charset=utf-8")
      logger("[cachedFetch] Returning cached result");
      return Promise.resolve(response)
    } else {
      // We need to clean up this old key
      localStorage.removeItem(cacheKey)
      localStorage.removeItem(cacheKey + ':ts')
    }
  }

  let request = new Request(url, options.headers)
  logger("[cachedFetch] loading data", url);
  return fetch(
      request
  ).then(response => {
      logger('[cachedFetch] Response: ', response.headers.get('Content-Type'));
    // let's only store in cache if the content-type is
    // JSON or something non-binary
    if (response.status === 200) {
      let ct = response.headers.get('Content-Type')
      if (ct && (ct.match(/application\/json/i) || ct.match(/text\//i))) {
        // There is a .json() instead of .text() but
        // we're going to store it in sessionStorage as
        // string anyway.
        // If we don't clone the response, it will be
        // consumed by the time it's returned. This
        // way we're being un-intrusive.
        response.clone().text().then(content => {
        logger('[cachedFetch] Caching ');
          localStorage.setItem(cacheKey, content)
          localStorage.setItem(cacheKey+':ts', Date.now())
        })
      }
    }

    logger('[cachedFetch] Returning server response');
    return response
  })
}

export default CachedFetch;