/* @flow */
/* global T $Shape */

import {
  FETCH, FETCH_SUCCESS, FETCH_ERROR,
  FETCH_ONE, FETCH_ONE_SUCCESS, FETCH_ONE_ERROR,
  CREATE, CREATE_SUCCESS, CREATE_ERROR,
  UPDATE, UPDATE_SUCCESS, UPDATE_ERROR,
  DELETE, DELETE_SUCCESS, DELETE_ERROR,
  CLEAR_ACTION_STATUS, API_CALL, CLEAR_MODEL_DATA
} from './actionTypes'

import type {
  Action,
  ClearActionStatus,
  ClearModelDataAction,
  CrudAction,
  ID,
  Method
} from './actionTypes'

type Opts = {
  method?: Method,
}

export function fetchCollection<T>(model: string, path: string, params: Object = {}, opts: Opts = {}
                                  ): CrudAction<T[]> {
  const method = opts.method || 'get'
  return {
    type: FETCH,
    meta: {
      success: FETCH_SUCCESS,
      failure: FETCH_ERROR,
      params,
      model
    },
    payload: {
      method,
      path,
      params
    }
  }
}

export function fetchRecord<T>(model: string, id: ID, path: string,
                               params: Object = {}, opts: Opts = {}
                              ): CrudAction<T> {
  const method = opts.method || 'get'
  return {
    type: FETCH_ONE,
    meta: {
      success: FETCH_ONE_SUCCESS,
      failure: FETCH_ONE_ERROR,
      model,
      id
    },
    payload: {
      method,
      path,
      params
    }
  }
}

export function createRecord<T>(model: string, path: string, data: $Shape<T> = {},
                                params: Object = {}, opts: Opts = {}
                               ): CrudAction<T> {
  const method = opts.method || 'post'
  return {
    type: CREATE,
    meta: {
      success: CREATE_SUCCESS,
      failure: CREATE_ERROR,
      model
    },
    payload: {
      method,
      path,
      data,
      params
    }
  }
}

export function updateRecord<T>(model: string, id: ID, path: string, data: $Shape<T> = {},
                                params: Object = {}, opts: Opts = {}
                               ): CrudAction<T> {
  const method = opts.method || 'put'
  return {
    type: UPDATE,
    meta: {
      success: UPDATE_SUCCESS,
      failure: UPDATE_ERROR,
      model,
      id
    },
    payload: {
      method,
      path,
      data,
      params
    }
  }
}

export function deleteRecord(model: string, id: ID, path: string,
                             params: Object = {}, opts: Opts = {}
                            ): CrudAction<void> {
  const method = opts.method || 'delete'
  return {
    type: DELETE,
    meta: {
      success: DELETE_SUCCESS,
      failure: DELETE_ERROR,
      model,
      id
    },
    payload: {
      method,
      path,
      params
    }
  }
}

export function clearActionStatus(model: string, action: 'create' | 'update' | 'delete'
                                 ): ClearActionStatus {
  return {
    type: CLEAR_ACTION_STATUS,
    payload: { model, action }
  }
}

export function apiCall<T>(success: string, failure: string, method: Method, path: string,
                           params: Object = {}, data: $Shape<T> = undefined, opts: Object = {}
                          ): CrudAction<T> {
  const meta = opts.meta || {}
  return {
    type: API_CALL,
    meta: {
      ...meta,
      success,
      failure
    },
    payload: {
      method,
      path,
      params,
      data
    }
  }
}

export function clearModelData(model: string): ClearModelDataAction {
  return {
    type: CLEAR_MODEL_DATA,
    payload: {
      model
    }
  }
}

@@ -472,16 +472,39 @@
 Method,%0A
+  fetchConfig?: Object%0A
 %7D%0A%0Aexpor
@@ -650,24 +650,76 @@
 tion%3CT%5B%5D%3E %7B%0A
+  const fetchConfig = opts.fetchConfig %7C%7C undefined%0A
   const meth
@@ -736,32 +736,33 @@
 method %7C%7C 'get'%0A
+%0A
   return %7B%0A    t
@@ -883,32 +883,51 @@
 %0A    payload: %7B%0A
+      fetchConfig,%0A
       method,%0A  
@@ -1139,32 +1139,84 @@
 CrudAction%3CT%3E %7B%0A
+  const fetchConfig = opts.fetchConfig %7C%7C undefined%0A
   const method =
@@ -1237,16 +1237,17 @@
 %7C 'get'%0A
+%0A
   return
@@ -1384,32 +1384,51 @@
 %0A    payload: %7B%0A
+      fetchConfig,%0A
       method,%0A  
@@ -1657,32 +1657,84 @@
 CrudAction%3CT%3E %7B%0A
+  const fetchConfig = opts.fetchConfig %7C%7C undefined%0A
   const method =
@@ -1756,16 +1756,17 @@
  'post'%0A
+%0A
   return
@@ -1884,32 +1884,51 @@
 %0A    payload: %7B%0A
+      fetchConfig,%0A
       method,%0A  
@@ -2177,32 +2177,84 @@
 CrudAction%3CT%3E %7B%0A
+  const fetchConfig = opts.fetchConfig %7C%7C undefined%0A
   const method =
@@ -2275,16 +2275,17 @@
 %7C 'put'%0A
+%0A
   return
@@ -2413,32 +2413,51 @@
 %0A    payload: %7B%0A
+      fetchConfig,%0A
       method,%0A  
@@ -2682,24 +2682,76 @@
 ion%3Cvoid%3E %7B%0A
+  const fetchConfig = opts.fetchConfig %7C%7C undefined%0A
   const meth
@@ -2779,16 +2779,17 @@
 delete'%0A
+%0A
   return
@@ -2917,32 +2917,51 @@
 %0A    payload: %7B%0A
+      fetchConfig,%0A
       method,%0A  
@@ -3482,16 +3482,69 @@
 a %7C%7C %7B%7D%0A
+  const fetchConfig = opts.fetchConfig %7C%7C undefined%0A%0A
   return
@@ -3621,32 +3621,32 @@
  failure%0A    %7D,%0A
-
     payload: %7B%0A 
@@ -3640,24 +3640,43 @@
  payload: %7B%0A
+      fetchConfig,%0A
       method

add fetchConfig to actionCreators! fixes #32