import { Component, PropTypes } from 'react'
import isEqual from 'lodash/isEqual'
import axios from 'axios'

const http = axios.create()

export default class Fetch extends Component {
  static propTypes = {
    method: PropTypes.oneOf(['get', 'post', 'put', 'delete']),
    url: PropTypes.string.isRequired,
    params: PropTypes.object,
    headers: PropTypes.object,
    body: PropTypes.object,
    lazy: PropTypes.bool,
    onResponse: PropTypes.func,
    onData: PropTypes.func,
    onError: PropTypes.func,
    children: PropTypes.func
  }

  // We are passing headers as null because undefined would ignore
  // instance's default headers (we use default headers for Authorization)
  static defaultProps = { method: 'get', headers: null }

  static setBaseUrl = baseUrl => http.defaults.baseURL = baseUrl

  static setAuthorization = authorization => {
    http.defaults.headers.common['Authorization'] = authorization
  }

  state = {
    fetching: false,
    response: null,
    data: null,
    error: null
  }

  componentDidMount() {
    if (!this.props.lazy) {
      this.fetch()
    }
  }

  componentWillReceiveProps(nextProps) {
    if (!this.props.lazy && !isEqual(this.props, nextProps)) {
      this.fetch()
    }
  }

  componentWillUnmount() {
    this.willUnmount = true
  }

  fetch = (body = this.props.body) => {
    this.setState({ fetching: true }, () => {
      http.request({
        method: this.props.method,
        url: this.props.url,
        params: this.props.params,
        headers: this.props.headers,
        data: body
      }).then(response => {
        if (this.willUnmount) {
          return
        }
        this.setState({ fetching: false, response, data: response.data }, () => {
          if (this.props.onResponse) {
            this.props.onResponse(null, response)
          }
          if (this.props.onData) {
            this.props.onData(this.state.data)
          }
        })
      }).catch(error => {
        if (this.willUnmount) {
          return
        }
        this.setState({
          fetching: false,
          response: error.response || error,
          error: error.response.data || error.response || error
        }, () => {
          if (this.props.onResponse) {
            this.props.onResponse(error)
          }
          if (this.props.onError) {
            this.props.onError(this.state.error)
          }
        })
      })
    })
  }

  render() {
    if (!this.props.children) {
      return null
    }
    return this.props.children({
      fetching: this.state.fetching,
      response: this.state.response,
      data: this.state.data,
      error: this.state.error,
      fetch: this.fetch
    })
  }
}

@@ -38,16 +38,42 @@
 'react'%0A
+import axios from 'axios'%0A
 import i
@@ -104,34 +104,8 @@
 ual'
-%0Aimport axios from 'axios'
 %0A%0Aco
@@ -546,386 +546,45 @@
 %0A%0A  
-// We are passing headers as null because undefined would ignore%0A  // instance's default headers (we use default headers for Authorization)%0A  static defaultProps = %7B method: 'get', headers: null %7D%0A%0A  static setBaseUrl = baseUrl =%3E http.defaults.baseURL = baseUrl%0A%0A  static setAuthorization = authorization =%3E %7B%0A    http.defaults.headers.common%5B'Authorization'%5D = authorization%0A 
+static defaultProps = %7B method: 'get'
  %7D%0A%0A
@@ -1313,32 +1313,42 @@
  this.setState(%7B
+%0A         
  fetching: false
@@ -1352,18 +1352,38 @@
 lse,
- response,
+%0A          response,%0A         
  dat
@@ -1398,16 +1398,24 @@
 nse.data
+%0A       
  %7D, () =

remove static methods