_ = require 'lodash'
errors = require '../errors/index'
Request = require './httpHelper'
Promise = require 'bluebird'

class getAccessToken extends Request
  constructor: ->
    super()
    @version = 'token'
    @n = 0

  run: ->
    @action = 'auth'
    @option.method = 'POST'
    @params = {
      action: @action
      appkey: C.api.accessToken.appkey
      appsecret: C.api.accessToken.appsecret
    }
    @make_request()
    @request()
    .then (data) =>
      @dispose_data data

  make_request: ->
    @option = _.assignIn @option, {
      hostname: C.api.accessToken.host,
      port: C.api.accessToken.port,
      path: C.api.accessToken.path
    }

    if C.debug
      @params.isdebug = 1

    @params.timestamp = @getUnixTime()

    signStr = @bubblesort(@params, false).toLowerCase()
    @params.sign = @md5(signStr).toLowerCase()
    delete @params.appsecret;
    @option.data = @params

    super()

  dispose_data: (data) ->
    if data.code is 10000
      @n = 0
      C.api.v4.accessToken = data.data.accessToken
      Promise.resolve()
    else
      if @n < 5 and data.code is 90701
        @n++
        @run()
      else
        @n = 0
        Promise.reject new errors.ApiError 'accessToken请求失失败', data, @version, @action

class API extends Request
  constructor: ->
    super()
    @version = 'v4'
    @getToken = new getAccessToken()
    @already_get_token = false
    @origin_option = null
    @origin_params = null

  @get: ->
    @already_get_token = false
    super()

  @post: ->
    @already_get_token = false
    super()

  make_request: ->
    if @origin_params?
      @params = _.clone @origin_params
      @option = _.clone @origin_option
    else
      @origin_params = _.clone @params
      @origin_option = _.clone @option
    @option = _.assignIn @option, {
      hostname: @get_and_del_key(@params, 'host') or C.api.v4.host,
      port: @get_and_del_key(@params, 'port') or C.api.v4.port,
      path: C.api.v4.path,
    }

    if not @params.appkey
      @params.appkey = C.api.v4.appkey
    if not @params.appsecret
      @params.appsecret = C.api.v4.appsecret

    if C.debug
      @params.isdebug = 1
    @params.accessToken = C.api.v4.accessToken
    @params.timestamp = @getUnixTime()

    signStr = @bubblesort(@params, false).toLowerCase()
    @params.sign = @md5(signStr).toLowerCase()
    delete @params.appsecret
    @option.data = @params

    super()

  errorMessage: (data) ->
    switch data.code
      when 90000 then Promise.resolve {
        status: false
        raw: data
        data: null
        msg: data.msg
      }
      when 90600 then Promise.reject new errors.LoginError '登录会话无效或已掉线'
      when 90601 then Promise.resolve {
        status: false
        raw: data
        data: null
        msg: '用户登录被踢出'
      }
      when 90704 then Promise.resolve {
        status: false
        raw: data
        data: null
        msg: '你不属于该企业员工或企业管理员未通过你的申请！'
      }
      when 10204 then Promise.resolve {
        status: false
        raw: data
        data: null
        msg: '你查找的数据不存在或已被删除'
      }
      else Promise.reject new errors.ApiError data.msg, data, @version, @action

  dispose_data: (data) ->
    if data.code is 10000
      return Promise.resolve {
        status: true
        raw: data
        data: data.data
        msg: data.msg
      }
    if data.code is 90701
      if @already_get_token is on
        return @errorMessage data
      @getToken.run()
      .then =>
        @already_get_token = true
        @make_request()
        @request().then (data) =>
          @dispose_data data
    else
      @errorMessage data

module.exports = API