import { createStore, combineReducers, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { authReducer } from './auth_reducer';
import history from "../history";
import { networkErrorReducer } from './network_reducer';

const LOGIN = 'LOGIN';
const LOGOUT = 'LOGOUT';
const PROMISE = 'PROMISE';
const PENDING = 'PENDING';
const RESOLVED = 'RESOLVED';
const REJECTED = 'REJECTED';
 
const promiseReducer = (state={}, action) => {
    switch(action.type) {
        case LOGIN:
            return {};
        case LOGOUT:
            return {};
        case PROMISE:
            return{
                ...state,
                [action.name]: {
                    status: action.status, 
                    payload: (action.status === PENDING && state[action.name] && state[action.name].payload) || action.payload, // зачем эта проверка?
                    error: action.error
                }
            }
        default: 
            return state;
    }
}

export const actionPromise = (name, promise) => {

    const actionPending = () => ({ type: PROMISE, name, status: PENDING, payload: null, error: null })
    const actionResolved = (payload) => ({ type: PROMISE, name, status: RESOLVED, payload, error: null })
    const actionRejected = (error) => ({ type: PROMISE, name, status: REJECTED, payload: null, error })

    return async (dispatch) => {
        dispatch(actionPending())
        let result;
        try {
            result = await promise
            dispatch(actionResolved(result))   // { type: PROMISE, name, status: RESOLVED, payload: result, error: null }
        }
        catch (e) {
            history.push("/404")
            dispatch(actionRejected(e))   // { type: PROMISE, name, status: REJECTED, payload: null, error: e }
        }
        return result
    }
}

export const store = createStore(combineReducers({
    auth: authReducer,
    promise: promiseReducer,
    networkError: networkErrorReducer
}), applyMiddleware(thunk));

store.subscribe(() => console.log('STORE', store.getState()))

window.store = store;