import { getRecommendations, IRecommendation, IRecommendationsBody } from '@rh-support/api';
import { IAction } from '@rh-support/types';

type IActionType = IAction<RecommendationsConstants, IRecommendationsState>;
export type RecommendationsReducerDispatchType = (value: IActionType) => void;

export interface IRecommendationsState {
    isLoadingRecommendations: boolean;
    isLoadingRecommendationsError: boolean;
    allDocs: IRecommendation[];
    visibleDocs: IRecommendation[];
    numFound?: number;
    currentPage?: number;
    sideRecommendationError?: boolean;
    sideRecommendation?: IRecommendation[];
}

export const initialRecommendationsState: IRecommendationsState = {
    isLoadingRecommendations: true,
    isLoadingRecommendationsError: false,
    allDocs: [],
    visibleDocs: [],
    numFound: 0,
    currentPage: 1,
    sideRecommendationError: false,
    sideRecommendation: []
};

export enum RecommendationsConstants {
    requestRecommendations = 'requestRecommendations',
    receivedRecommendations = 'receivedRecommendations',
    receivedRecommendationsError = 'receivedRecommendationsError',
    setVisibleDocs = 'setVisibleDocs',
    setCurrentPage = 'setCurrentPage',
    requestSidebarRecommendation = 'requestSidebarRecommendation',
    receiveSidebarRecommendation = 'receiveSidebarRecommendation'
}

// Resucers
export const recommandationsReducer = (state: IRecommendationsState, action: IActionType): IRecommendationsState => {
    switch (action.type) {
        case RecommendationsConstants.requestRecommendations: {
            return { ...state, allDocs: [], isLoadingRecommendations: true, isLoadingRecommendationsError: false };
        }
        case RecommendationsConstants.receivedRecommendations: {
            return { ...state, ...action.payload, isLoadingRecommendations: false, isLoadingRecommendationsError: false };
        }
        case RecommendationsConstants.receivedRecommendationsError: {
            return { ...state, allDocs: [], isLoadingRecommendations: false, isLoadingRecommendationsError: true };
        }
        case RecommendationsConstants.setVisibleDocs: {
            return { ...state, visibleDocs: action.payload.visibleDocs};
        }
        case RecommendationsConstants.setCurrentPage: {
            return { ...state, currentPage: action.payload.currentPage};
        }
        case RecommendationsConstants.requestSidebarRecommendation: {
            return { ...state, sideRecommendationError: false };
        }
        case RecommendationsConstants.receiveSidebarRecommendation: {
            return {
                ...state,
                sideRecommendation: action.payload.sideRecommendation,
                sideRecommendationError: action.payload.sideRecommendationError
            };
        }
        default: {
            return state;
        }
    }
};

// Actions
export const fetchRecommendations = async (dispatch: RecommendationsReducerDispatchType, body: IRecommendationsBody, max_rows: number, page_size: number) => {
    dispatch({ type: RecommendationsConstants.requestRecommendations });
    try {
        const response = await getRecommendations(body, max_rows);

        dispatch({ type: RecommendationsConstants.receivedRecommendations, payload: {
            allDocs: response.response.docs,
            visibleDocs: response.response.docs.slice(0, page_size),
            numFound: response.response.numFound
        } });
    } catch (error) {
        dispatch({ type: RecommendationsConstants.receivedRecommendationsError });
    }
};

export const setVisibleDocs = (dispatch: RecommendationsReducerDispatchType, visDocs: IRecommendation[]) => {
    dispatch({ type: RecommendationsConstants.setVisibleDocs, payload: { visibleDocs: visDocs }});
};

export const setCurrentPage = (dispatch: RecommendationsReducerDispatchType, pageNum: number) => {
    dispatch({ type: RecommendationsConstants.setCurrentPage, payload: { currentPage: pageNum } });
};
