import api from '../api'
import { importFetchedAccounts } from './importer'
// import { showAlertForError } from './alerts'
import { me } from '../initial_state'

export const LIST_FETCH_REQUEST = 'LIST_FETCH_REQUEST'
export const LIST_FETCH_SUCCESS = 'LIST_FETCH_SUCCESS'
export const LIST_FETCH_FAIL    = 'LIST_FETCH_FAIL'

export const LISTS_FETCH_REQUEST = 'LISTS_FETCH_REQUEST'
export const LISTS_FETCH_SUCCESS = 'LISTS_FETCH_SUCCESS'
export const LISTS_FETCH_FAIL    = 'LISTS_FETCH_FAIL'

export const LIST_EDITOR_TITLE_CHANGE = 'LIST_EDITOR_TITLE_CHANGE'
export const LIST_EDITOR_RESET        = 'LIST_EDITOR_RESET'
export const LIST_EDITOR_SETUP        = 'LIST_EDITOR_SETUP'

export const LIST_CREATE_REQUEST = 'LIST_CREATE_REQUEST'
export const LIST_CREATE_SUCCESS = 'LIST_CREATE_SUCCESS'
export const LIST_CREATE_FAIL    = 'LIST_CREATE_FAIL'

export const LIST_UPDATE_REQUEST = 'LIST_UPDATE_REQUEST'
export const LIST_UPDATE_SUCCESS = 'LIST_UPDATE_SUCCESS'
export const LIST_UPDATE_FAIL    = 'LIST_UPDATE_FAIL'

export const LIST_DELETE_REQUEST = 'LIST_DELETE_REQUEST'
export const LIST_DELETE_SUCCESS = 'LIST_DELETE_SUCCESS'
export const LIST_DELETE_FAIL    = 'LIST_DELETE_FAIL'

export const LIST_ACCOUNTS_FETCH_REQUEST = 'LIST_ACCOUNTS_FETCH_REQUEST'
export const LIST_ACCOUNTS_FETCH_SUCCESS = 'LIST_ACCOUNTS_FETCH_SUCCESS'
export const LIST_ACCOUNTS_FETCH_FAIL    = 'LIST_ACCOUNTS_FETCH_FAIL'

export const LIST_EDITOR_SUGGESTIONS_CHANGE = 'LIST_EDITOR_SUGGESTIONS_CHANGE'
export const LIST_EDITOR_SUGGESTIONS_READY  = 'LIST_EDITOR_SUGGESTIONS_READY'
export const LIST_EDITOR_SUGGESTIONS_CLEAR  = 'LIST_EDITOR_SUGGESTIONS_CLEAR'

export const LIST_EDITOR_ADD_REQUEST = 'LIST_EDITOR_ADD_REQUEST'
export const LIST_EDITOR_ADD_SUCCESS = 'LIST_EDITOR_ADD_SUCCESS'
export const LIST_EDITOR_ADD_FAIL    = 'LIST_EDITOR_ADD_FAIL'

export const LIST_EDITOR_REMOVE_REQUEST = 'LIST_EDITOR_REMOVE_REQUEST'
export const LIST_EDITOR_REMOVE_SUCCESS = 'LIST_EDITOR_REMOVE_SUCCESS'
export const LIST_EDITOR_REMOVE_FAIL    = 'LIST_EDITOR_REMOVE_FAIL'

export const LIST_ADDER_RESET = 'LIST_ADDER_RESET'
export const LIST_ADDER_SETUP = 'LIST_ADDER_SETUP'

export const LIST_ADDER_LISTS_FETCH_REQUEST = 'LIST_ADDER_LISTS_FETCH_REQUEST'
export const LIST_ADDER_LISTS_FETCH_SUCCESS = 'LIST_ADDER_LISTS_FETCH_SUCCESS'
export const LIST_ADDER_LISTS_FETCH_FAIL    = 'LIST_ADDER_LISTS_FETCH_FAIL'

/**
 *
 */
export const fetchList = (id) => (dispatch, getState) => {
  if (!me) return

  if (getState().getIn(['lists', id])) return

  dispatch(fetchListRequest(id))

  api(getState).get(`/api/v1/lists/${id}`)
    .then(({ data }) => dispatch(fetchListSuccess(data)))
    .catch((err) => dispatch(fetchListFail(id, err)))
}

const fetchListRequest = id => ({
  type: LIST_FETCH_REQUEST,
  id,
})

const fetchListSuccess = list => ({
  type: LIST_FETCH_SUCCESS,
  list,
})

const fetchListFail = (id, error) => ({
  type: LIST_FETCH_FAIL,
  id,
  error,
})

/**
 *
 */
export const fetchLists = () => (dispatch, getState) => {
  return new Promise((resolve, reject) => {
    dispatch(fetchListsRequest())
    if (!me) return reject()
    api(getState).get('/api/v1/lists').then(({ data }) => {
      dispatch(fetchListsSuccess(data))
      return resolve()
    }).catch((err) => {
      dispatch(fetchListsFail(err))
      return reject()
    })
  })
}

const fetchListsRequest = () => ({
  type: LISTS_FETCH_REQUEST,
})

const fetchListsSuccess = (lists) => ({
  type: LISTS_FETCH_SUCCESS,
  lists,
})

const fetchListsFail = (error) => ({
  type: LISTS_FETCH_FAIL,
  showToast: false,
  error,
})

/**
 *
 */
export const submitListEditor = (shouldReset) => (dispatch, getState) => {
  const listId = getState().getIn(['listEditor', 'listId'])
  const title  = getState().getIn(['listEditor', 'title'])

  if (listId === null) {
    dispatch(createList(title, shouldReset))
  } else {
    dispatch(updateList(listId, title, shouldReset))
  }
}

/**
 *
 */
export const setupListEditor = (listId) => (dispatch, getState) => {
  dispatch({
    type: LIST_EDITOR_SETUP,
    list: getState().getIn(['lists', listId]),
  })

  dispatch(fetchListAccounts(listId))
}

/**
 *
 */
export const changeListEditorTitle = (value) => ({
  type: LIST_EDITOR_TITLE_CHANGE,
  value,
})

/**
 *
 */
export const createList = (title, shouldReset) => (dispatch, getState) => {
  if (!me) return

  dispatch(createListRequest())

  api(getState).post('/api/v1/lists', { title }).then(({ data }) => {
    dispatch(createListSuccess(data))

    if (shouldReset) {
      dispatch(resetListEditor())
    }
  }).catch((err) => dispatch(createListFail(err)))
}

export const createListRequest = () => ({
  type: LIST_CREATE_REQUEST,
})

export const createListSuccess = (list) => ({
  type: LIST_CREATE_SUCCESS,
  showToast: true,
  list,
})

export const createListFail = (error) => ({
  type: LIST_CREATE_FAIL,
  showToast: true,
  error,
})

/**
 *
 */
export const updateList = (id, title, shouldReset) => (dispatch, getState) => {
  if (!me) return

  dispatch(updateListRequest(id))

  api(getState).put(`/api/v1/lists/${id}`, { title }).then(({ data }) => {
    dispatch(updateListSuccess(data))

    if (shouldReset) {
      dispatch(resetListEditor())
    }
  }).catch((err) => dispatch(updateListFail(id, err)))
}

export const updateListRequest = id => ({
  type: LIST_UPDATE_REQUEST,
  id,
})

export const updateListSuccess = list => ({
  type: LIST_UPDATE_SUCCESS,
  showToast: true,
  list,
})

export const updateListFail = (id, error) => ({
  type: LIST_UPDATE_FAIL,
  showToast: true,
  id,
  error,
})

export const resetListEditor = () => ({
  type: LIST_EDITOR_RESET,
})

/**
 *
 */
export const deleteList = (id) => (dispatch, getState) => {
  if (!me) return

  dispatch(deleteListRequest(id))

  api(getState).delete(`/api/v1/lists/${id}`)
    .then(() => dispatch(deleteListSuccess(id)))
    .catch((err) => dispatch(deleteListFail(id, err)))
}

export const deleteListRequest = (id) => ({
  type: LIST_DELETE_REQUEST,
  id,
})

export const deleteListSuccess = (id) => ({
  type: LIST_DELETE_SUCCESS,
  showToast: true,
  id,
})

export const deleteListFail = (id, error) => ({
  type: LIST_DELETE_FAIL,
  showToast: true,
  id,
  error,
})

/**
 *
 */
export const fetchListAccounts = (listId) => (dispatch, getState) => {
  if (!me) return

  dispatch(fetchListAccountsRequest(listId))

  api(getState).get(`/api/v1/lists/${listId}/accounts`, { params: { limit: 0 } }).then(({ data }) => {
    dispatch(importFetchedAccounts(data))
    dispatch(fetchListAccountsSuccess(listId, data))
  }).catch((err) => dispatch(fetchListAccountsFail(listId, err)))
}

export const fetchListAccountsRequest = (id) => ({
  type: LIST_ACCOUNTS_FETCH_REQUEST,
  id,
})

export const fetchListAccountsSuccess = (id, accounts, next) => ({
  type: LIST_ACCOUNTS_FETCH_SUCCESS,
  id,
  accounts,
  next,
})

export const fetchListAccountsFail = (id, error) => ({
  type: LIST_ACCOUNTS_FETCH_FAIL,
  showToast: true,
  id,
  error,
})

/**
 *
 */
export const fetchListSuggestions = (q) => (dispatch, getState) => {
  if (!me) return

  const params = {
    q,
    resolve: false,
    limit: 25,
  }

  api(getState).get('/api/v1/accounts/search', { params }).then(({ data }) => {
    dispatch(importFetchedAccounts(data))
    dispatch(fetchListSuggestionsReady(q, data))
  })
  // }).catch(error => dispatch(showAlertForError(error)))
}

/**
 *
 */
const fetchListSuggestionsReady = (query, accounts) => ({
  type: LIST_EDITOR_SUGGESTIONS_READY,
  query,
  accounts,
})

/**
 *
 */
export const clearListSuggestions = () => ({
  type: LIST_EDITOR_SUGGESTIONS_CLEAR,
})

/**
 *
 */
export const changeListSuggestions = (value) => ({
  type: LIST_EDITOR_SUGGESTIONS_CHANGE,
  value,
})

/**
 *
 */
export const addToListEditor = accountId => (dispatch, getState) => {
  dispatch(addToList(getState().getIn(['listEditor', 'listId']), accountId))
}

/**
 *
 */
export const addToList = (listId, accountId) => (dispatch, getState) => {
  if (!me) return

  dispatch(addToListRequest(listId, accountId))

  api(getState).post(`/api/v1/lists/${listId}/accounts`, { account_id: accountId })
    .then(() => dispatch(addToListSuccess(listId, accountId)))
    .catch((err) => dispatch(addToListFail(listId, accountId, err)))
}

const addToListRequest = (listId, accountId) => ({
  type: LIST_EDITOR_ADD_REQUEST,
  listId,
  accountId,
})

const addToListSuccess = (listId, accountId) => ({
  type: LIST_EDITOR_ADD_SUCCESS,
  showToast: true,
  listId,
  accountId,
})

const addToListFail = (listId, accountId, error) => ({
  type: LIST_EDITOR_ADD_FAIL,
  showToast: true,
  listId,
  accountId,
  error,
})

/**
 *
 */
export const removeFromListEditor = accountId => (dispatch, getState) => {
  dispatch(removeFromList(getState().getIn(['listEditor', 'listId']), accountId))
}

/**
 *
 */
export const removeFromList = (listId, accountId) => (dispatch, getState) => {
  if (!me) return

  dispatch(removeFromListRequest(listId, accountId))

  api(getState).delete(`/api/v1/lists/${listId}/accounts`, { params: { account_id: accountId } })
    .then(() => dispatch(removeFromListSuccess(listId, accountId)))
    .catch((err) => dispatch(removeFromListFail(listId, accountId, err)))
}

const removeFromListRequest = (listId, accountId) => ({
  type: LIST_EDITOR_REMOVE_REQUEST,
  listId,
  accountId,
})

const removeFromListSuccess = (listId, accountId) => ({
  type: LIST_EDITOR_REMOVE_SUCCESS,
  showToast: true,
  listId,
  accountId,
})

const removeFromListFail = (listId, accountId, error) => ({
  type: LIST_EDITOR_REMOVE_FAIL,
  showToast: true,
  listId,
  accountId,
  error,
})

/**
 *
 */
export const resetListAdder = () => ({
  type: LIST_ADDER_RESET,
})

/**
 *
 */
export const setupListAdder = accountId => (dispatch, getState) => {
  dispatch({
    type: LIST_ADDER_SETUP,
    account: getState().getIn(['accounts', accountId]),
  })
  dispatch(fetchLists())
  dispatch(fetchAccountLists(accountId))
}

/**
 *
 */
export const fetchAccountLists = (accountId) => (dispatch, getState) => {
  if (!me) return

  dispatch(fetchAccountListsRequest(accountId))

  api(getState).get(`/api/v1/accounts/${accountId}/lists`)
    .then(({ data }) => dispatch(fetchAccountListsSuccess(accountId, data)))
    .catch((err) => dispatch(fetchAccountListsFail(accountId, err)))
}

const fetchAccountListsRequest = (id) => ({
  type:LIST_ADDER_LISTS_FETCH_REQUEST,
  id,
})

const fetchAccountListsSuccess = (id, lists) => ({
  type: LIST_ADDER_LISTS_FETCH_SUCCESS,
  id,
  lists,
})

const fetchAccountListsFail = (id, error) => ({
  type: LIST_ADDER_LISTS_FETCH_FAIL,
  showToast: true,
  id,
  error,
})

/**
 *
 */
export const addToListAdder = (listId) => (dispatch, getState) => {
  dispatch(addToList(listId, getState().getIn(['listAdder', 'accountId'])))
}

/**
 *
 */
export const removeFromListAdder = (listId) => (dispatch, getState) => {
  dispatch(removeFromList(listId, getState().getIn(['listAdder', 'accountId'])))
}
