import { Map, fromJS } from 'immutable'
import axios from 'axios'
import jwtDecode from 'jwt-decode'

import { apiUrl } from '../../config'
import { dialogClose } from './state'
import { getUser } from './data/user'

const api = axios.create({
	baseURL: apiUrl + 'auth/',
	timeout: 5000
})

// Constants

const MODULE = 'auth/'

const LOGIN_REQUEST = MODULE + 'LOGIN_REQUEST'
const LOGIN_SUCCESS = MODULE + 'LOGIN_SUCCESS'
const LOGIN_FAILURE = MODULE + 'LOGIN_FAILURE'

const VERIFY = MODULE + 'VERIFY'
const LOGOUT = MODULE + 'LOGOUT'

// Action Creators

const loadUserToken = () => {
	const token = localStorage.getItem('token')
	const user = jwtDecode(token)
	return user
}

const login = user => async dispatch => {
	dispatch({ type: LOGIN_REQUEST })

	try {
		const response = await api.post('login?group=Prototype_Orders', user)
		localStorage.setItem('token', response.data.token)
		const userToken = fromJS(loadUserToken())

		dispatch(dialogClose())
		dispatch(getUser(userToken))
		dispatch({ type: LOGIN_SUCCESS })
	} catch (error) {
		console.log(error)
		dispatch({ type: LOGIN_FAILURE, error: error.response.data })
	}
}

const verify = () => async dispatch => {
	try {
		if (!localStorage.getItem('token')) {
			return
		}
		const token = localStorage.getItem('token')
		const response = await api.post('verify', { token })
		localStorage.setItem('token', response.data.token)
		const user = fromJS(loadUserToken())

		dispatch(getUser(user))
		dispatch({ type: VERIFY })
	} catch (error) {
		console.log(error)
	}
}

const logout = () => {
	localStorage.removeItem('token')
	return { type: LOGOUT }
}

// Default state

const defaultState = Map({
	loggingIn: false,
	loggedIn: undefined,
	error: undefined
})

const actionMap = {
	[LOGIN_REQUEST]: state => state.set('loggingIn', true),
	[LOGIN_SUCCESS]: state => {
		state = state.set('loggingIn', false)
		return state.set('loggedIn', true)
	},
	[LOGIN_FAILURE]: (state, { error }) => {
		state = state.set('loggingIn', false)
		return state.set('error', error)
	},
	[VERIFY]: state => state.set('loggedIn', true),
	[LOGOUT]: state => state.set('loggedIn', false)
}

export { login, verify, logout }

export default (state = defaultState, action) => {
	const actionHandler = actionMap[action.type]
	return actionHandler ? actionHandler(state, action) : state
}
