import { createEntityAdapter, EntityAdapter, EntityState, Update } from '@ngrx/entity';

import * as actions from './search-multiple.action';
import { DataByDataset, DatasetCount } from './model';


export interface State extends EntityState<DataByDataset> {
    pristine: boolean;
    currentStep: string;
    positionStepChecked: boolean;
    datasetsStepChecked: boolean;
    resultStepChecked: boolean;
    selectedDatasets: string[];
    datasetsCountIsLoading: boolean;
    datasetsCountIsLoaded: boolean;
    datasetsCount: DatasetCount[];
    selectedData: { dname: string, data: (string | number)[] }[];
}

export function selectDataByDatasetId(d: DataByDataset): string {
    return d.datasetName;
}

export const adapter: EntityAdapter<DataByDataset> = createEntityAdapter<DataByDataset>({
    selectId: selectDataByDatasetId
});

export const initialState: State = adapter.getInitialState({
    pristine: true,
    currentStep: null,
    positionStepChecked: false,
    datasetsStepChecked: false,
    resultStepChecked: false,
    selectedDatasets: [],
    datasetsCountIsLoading: false,
    datasetsCountIsLoaded: false,
    datasetsCount: [],
    selectedData: []
});

export function reducer(state: State = initialState, action: actions.Actions): State {
    switch (action.type) {
        case actions.INIT_SELECTED_DATASETS:
            return {
                ...state,
                selectedDatasets: action.payload
            };

        case actions.CHANGE_STEP:
            return {
                ...state,
                currentStep: action.payload
            };

        case actions.POSITION_CHECKED:
            return {
                ...state,
                pristine: false,
                positionStepChecked: true
            };

        case actions.DATASETS_CHECKED:
            return {
                ...state,
                datasetsStepChecked: true
            };

        case actions.RESULTS_CHECKED:
            return {
                ...state,
                resultStepChecked: true
            };

        case actions.UPDATE_SELECTED_DATASETS:
            return {
                ...state,
                selectedDatasets: action.payload
            };

        case actions.RETRIEVE_DATASETS_COUNT:
            return {
                ...state,
                datasetsCountIsLoading: true
            };

        case actions.RETRIEVE_DATASETS_COUNT_SUCCESS:
            return {
                ...state,
                datasetsCountIsLoading: false,
                datasetsCountIsLoaded: true,
                datasetsCount: action.payload
            };

        case actions.RETRIEVE_DATASETS_COUNT_FAIL:
            return {
                ...state,
                datasetsCountIsLoading: false
            };

        case actions.RETRIEVE_DATA:
            return adapter.upsertOne({
                datasetName: action.payload.dname,
                isLoading: true,
                isLoaded: false,
                data: []
            }, state);

        case actions.RETRIEVE_DATA_SUCCESS:
            return adapter.updateOne({
                id: action.payload.datasetName,
                changes: {
                    isLoading: false,
                    isLoaded: true,
                    data: action.payload.data
                }
            } as Update<DataByDataset>, state);

        case actions.RETRIEVE_DATA_FAIL:
            return adapter.updateOne({
                id: action.payload,
                changes: {
                    isLoading: false
                }
            } as Update<DataByDataset>, state);

        case actions.UPDATE_SELECTED_DATA:
            return {
                ...state,
                selectedData: action.payload
            };

        case actions.DESTROY_RESULTS:
            return adapter.removeAll({
                ...state,
                datasetsCountIsLoaded: false,
                datasetsCount: [],
                selectedData: []
            });

        case actions.RESET_SEARCH:
            return { ...initialState };

        default:
            return state;
    }
}
export const {
    selectAll,
    selectEntities,
    selectIds,
    selectTotal
} = adapter.getSelectors();
export const getCurrentStep = (state: State) => state.currentStep;
export const getPositionStepChecked = (state: State) => state.positionStepChecked;
export const getDatasetsStepChecked = (state: State) => state.datasetsStepChecked;
export const getResultStepChecked = (state: State) => state.resultStepChecked;
export const getSelectedDatasets = (state: State) => state.selectedDatasets;
export const getDatasetsCountIsLoading = (state: State) => state.datasetsCountIsLoading;
export const getDatasetsCountIsLoaded = (state: State) => state.datasetsCountIsLoaded;
export const getDatasetsCount = (state: State) => state.datasetsCount;
export const getSelectedData = (state: State) => state.selectedData;