import querystring from 'querystring'
import _ from 'lodash'
import _fetch from 'isomorphic-fetch'

import _package from '../package.json'


const defaultCtx = {
  // env: 'development' | 'production',
  env: process.env.NODE_ENV,
  apiUrl: process.env.BALANC_API || 'https://balanc.eddyy.com/v1',
  libVersion: _package.version,

  domain: typeof window !== 'undefined' ? window.location.hostname : undefined,
  domainEmail: undefined,

  // NOTE individual customer or pos controller
  // NOTE set permission
  userJwt: undefined,

  // currency: 'HKD',
  currency: undefined,
}

const ctxFields = Object.keys(defaultCtx)


export class Balanc {
  constructor(context) {
    this._context = defaultCtx
    this.setContext(context)
  }

  setContext(context) {
    _.assign(this._context, _.pick(context, ctxFields))
    return this
  }

  transfer({from, amount, to, text, ...data} = {}, context) {
    const body = {
      from,
      amount,
      to,
      text,
      data,
    }
    return this.fetch('transfer', body, {method: 'POST'}, context)
  }

  getAccount(body, context) {
    return this.fetch('account', body, {method: 'GET'}, context)
  }

  fetch(pathname, body, option, context) {
    const {env, apiUrl, ...apiFields} = {...this._context, ...context}
    const {method} = option

    const _opt = _.merge({
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
    }, option)

    let query = ''
    const json = {
      ...body,
      ...apiFields,
    }
    if (method === 'GET') {
      query = '?' + querystring.stringify(json)
    } else {
      _opt.body = JSON.stringify(json)
    }

    if (env === 'production') {
      // console.warn()
    }

    return _fetch(`${apiUrl}/${pathname}${query}`, _opt)
    .then(response => {
      if (response.status >= 200 && response.status < 400) {
        const contentType = response.headers.get('Content-Type')
        return _.startsWith(contentType, 'application/json') ? response.json() : response
      } else {
        var error = new Error(response.statusText)
        error.response = response
        throw error
      }
    })
  }
}


export default new Balanc()

@@ -836,327 +836,8 @@
  %7D%0A%0A
-  transfer(%7Bfrom, amount, to, text, ...data%7D = %7B%7D, context) %7B%0A    const body = %7B%0A      from,%0A      amount,%0A      to,%0A      text,%0A      data,%0A    %7D%0A    return this.fetch('transfer', body, %7Bmethod: 'POST'%7D, context)%0A  %7D%0A%0A  getAccount(body, context) %7B%0A    return this.fetch('account', body, %7Bmethod: 'GET'%7D, context)%0A  %7D%0A%0A
   fe
@@ -1842,16 +1842,330 @@
 %0A  %7D%0A%7D%0A%0A
+function addMethod(funcName, httpUrl, httpMethod) %7B%0A  Balanc.prototype%5BfuncName%5D = function(body, context) %7B%0A    return this.fetch(httpUrl, body, %7Bmethod: httpMethod%7D, context)%0A  %7D%0A%7D%0A%0AaddMethod('transfer', 'transfer', 'POST')%0AaddMethod('getTransfers', 'transfer', 'GET')%0AaddMethod('getAccount', 'account', 'GET')%0A%0A
 %0Aexport 

simplify the calls