import axios from 'axios'
import humps from 'humps'

class HttpRequest {
  axiosInstance;

  constructor (url = process.env.VUE_APP_API) {
    this.axiosInstance = axios.create({
      baseURL: url,
      withCredentials: process.env.VUE_APP_MODE !== 'LOCAL',
      xsrfCookieName: 'CSRF-TOKEN',
      xsrfHeaderName: 'X-CSRF-Token',
      headers: {
        'Content-Type': 'application/json'
      }
    })

    this.axiosInstance.interceptors.request.use((request) => {
      const config = this.setAuthenticationToken(request)
      return config
    }, (error) => Promise.reject(error))

    this.axiosInstance.interceptors.response.use((response) => {
      const data = humps.camelizeKeys(response.data)
      return data
    }, (error) => Promise.reject(error))
  }

  get = (endpoint, data, config) => {
    const { payload, decamelize = true } = data || {}
    return this.axiosInstance.get(endpoint, { ...config, params: this.decamelize(payload, decamelize) })
  }

  post = async (endpoint, data, config) => {
    const { payload, decamelize = true } = data || {}
    return this.axiosInstance.post(
      endpoint,
      this.decamelize(payload, decamelize),
      this.setXCSRFToken(config)
    )
  }

  put = (endpoint, data, config) => {
    const { payload, decamelize = true } = data || {}
    return this.axiosInstance.put(
      endpoint,
      this.decamelize(payload, decamelize),
      this.setXCSRFToken(config)
    )
  }

  patch = (endpoint, data, config) => {
    const { payload, decamelize = true } = data || {}
    return this.axiosInstance.patch(
      endpoint,
      this.decamelize(payload, decamelize),
      this.setXCSRFToken(config)
    )
  }

  delete = (endpoint, data, config) => {
    const { payload, decamelize = true } = data || {}
    return this.axiosInstance.delete(
      endpoint, {
        ...this.setXCSRFToken(config),
        params: this.decamelize(payload, decamelize)
      }
    )
  }

  delete2 = (endpoint, data, config) => {
    const { payload, decamelize = true } = data || {}
    return this.axiosInstance.request(
      endpoint, {
        ...this.setXCSRFToken(config),
        method: 'DELETE',
        data: this.decamelize(payload, decamelize)
      }
    )
  }

  setAuthenticationToken = (config) => {
    const configWithToken = config || {}
    return configWithToken
  }

  setXCSRFToken = (config) => {
    const configWithXCSRF = config || {}
    if (process.env.VUE_APP_MODE !== 'LOCAL') {
      configWithXCSRF.headers = {
        ...configWithXCSRF.headers
      }
    }
    return configWithXCSRF
  }

  handleError = (exception, message) => {
    console.error(message || `ไม่สามารถเชื่อมต่อกับเซิฟเวอร์ได้ (${exception.response.status})`)
    throw exception
  }

  decamelize = (payload, decamelize) => ((decamelize) ? humps.decamelizeKeys(payload) : payload)
}

export default HttpRequest
