import { IAction } from '@rh-support/types';
import difference from 'lodash/difference';
import forEach from 'lodash/forEach';
import intersection from 'lodash/intersection';
import uniq from 'lodash/uniq';
import RouteUtils from '../utils/routeUtils';
// Interfaces
export  interface  ISectionInfo {
    previousSection: AppRouteSections;
    nextSection: AppRouteSections;
    futureSections: AppRouteSections[];
}
export interface ISectionConfiguration  extends ISectionInfo {
    title: string;
    disableOtherSections: boolean;
    nextButtonLabel: string;
    previousButtonLabel: string;
    skipToSubmitLabel: string;
    showSkipToSubmit: boolean;
    hideAside: boolean;
}
export interface ISectionConfigurations {
    [key: string]: ISectionConfiguration;
}
export interface IRouteQueryParams {
    product?: string;
    version?: string;
}
export interface IRouteUrlParams { }
export interface IRouteState {
    completedSections: AppRouteSections[];
    activeSection: AppRouteSections;
    isSectionValid: boolean;
    sectionsToHide: AppRouteSections[];
    appRouteConfugurations: ISectionConfigurations;
    appRouteSectionsSequence: AppRouteSections[];
}
export interface IRoutePayloadType extends IRouteState { }
type IActionType = IAction<RouteReducerConstants, IRoutePayloadType>;
export type RouteReducerDispatchType = (value: IActionType) => void;

// Constants
export enum RouteReducerConstants {
    activeSectionChanged = 'activeSectionChanged',
    setIsSectionValid = 'setIsSectionValid',
    updateSectionsToHide = 'updateSectionsToHide'
}

export enum AppRouteSections {
    PRODUCT_SELECTOR = 'productSelector',
    SUGGESTIONS = 'suggestions',
    ISSUE = 'issue',
    RESULTS = 'results',
    OPEN_CASE = 'openCase',
    IMPROVE_CASE = 'improveCase',
    CASE_MGM = 'caseMgm',
    REVIEW = 'review',
    SUBMIT_CASE = 'submitCase'
}

const defaultRouteSectionsSequence: AppRouteSections[] = [
    AppRouteSections.PRODUCT_SELECTOR,
    AppRouteSections.SUGGESTIONS,
    AppRouteSections.ISSUE,
    AppRouteSections.RESULTS,
    AppRouteSections.OPEN_CASE,
    AppRouteSections.IMPROVE_CASE,
    AppRouteSections.CASE_MGM,
    AppRouteSections.REVIEW,
    AppRouteSections.SUBMIT_CASE
];
export function getAppRouteSectionsSequence(sectionsToHide: AppRouteSections[]): AppRouteSections[] {
    return difference(defaultRouteSectionsSequence, sectionsToHide);
}

const defaultRouteConfiguration: ISectionConfiguration = {
    title: '',
    previousSection: null,
    nextSection: null,
    futureSections: [],
    disableOtherSections: false,
    nextButtonLabel: 'Next',
    previousButtonLabel: 'Back',
    skipToSubmitLabel: 'Skip to submit',
    showSkipToSubmit: false,
    hideAside: false
};

export function getAppRouteConfugurations(appRouteSectionsSequence: AppRouteSections[]): ISectionConfigurations {
    function getSectionInfo(currentSection: AppRouteSections, futureSections: AppRouteSections[] = []): ISectionInfo {
        const currentSectionIndex  =  appRouteSectionsSequence.indexOf(currentSection);
        if (currentSectionIndex === -1) { return; }
        return {
            nextSection: appRouteSectionsSequence[currentSectionIndex + 1],
            previousSection: appRouteSectionsSequence[currentSectionIndex - 1],
            futureSections: difference(intersection(futureSections, appRouteSectionsSequence), [appRouteSectionsSequence[currentSectionIndex + 1]])
        };
    }
    const appRouteConfugurations: ISectionConfigurations = {
        [AppRouteSections.PRODUCT_SELECTOR]: {
            ...defaultRouteConfiguration,
            title: 'Environment',
            ...getSectionInfo(AppRouteSections.PRODUCT_SELECTOR, [AppRouteSections.ISSUE, AppRouteSections.RESULTS])
        },
        [AppRouteSections.SUGGESTIONS]: {
            ...defaultRouteConfiguration,
            title: 'Fixes for common issues',
            ...getSectionInfo(AppRouteSections.SUGGESTIONS, [AppRouteSections.RESULTS])
        },
        [AppRouteSections.ISSUE]: {
            ...defaultRouteConfiguration,
            title: 'Describe the issue',
            ...getSectionInfo(AppRouteSections.ISSUE)
        },
        [AppRouteSections.RESULTS]: {
            ...defaultRouteConfiguration,
            title: 'Results',
            nextButtonLabel: 'Open a support case',
            previousButtonLabel: 'Revise search',
            ...getSectionInfo(AppRouteSections.RESULTS)
        },
        [AppRouteSections.OPEN_CASE]: {
            ...defaultRouteConfiguration,
            title: 'Open a support case',
            showSkipToSubmit: true,
            ...getSectionInfo(AppRouteSections.OPEN_CASE, [AppRouteSections.CASE_MGM, AppRouteSections.REVIEW]),
        },
        [AppRouteSections.IMPROVE_CASE]: {
            ...defaultRouteConfiguration,
            title: 'Resolve your case faster',
            ...getSectionInfo(AppRouteSections.IMPROVE_CASE, [AppRouteSections.REVIEW]),
            showSkipToSubmit: true
        },
        [AppRouteSections.CASE_MGM]: {
            ...defaultRouteConfiguration,
            title: 'Manage case',
            ...getSectionInfo(AppRouteSections.CASE_MGM)
        },
        [AppRouteSections.REVIEW]: {
            ...defaultRouteConfiguration,
            title: 'Review',
            nextButtonLabel: 'Submit',
            ...getSectionInfo(AppRouteSections.REVIEW)
        },
        [AppRouteSections.SUBMIT_CASE]: {
            ...defaultRouteConfiguration,
            title: 'Case Submitted',
            disableOtherSections: true,
            hideAside: false,
            ...getSectionInfo(AppRouteSections.SUBMIT_CASE)
        }
    };
    return appRouteConfugurations;
}

// Reducer
export const initialRouteReducerState: IRouteState = {
    activeSection: getAppRouteSectionsSequence([])[0],
    completedSections: [],
    isSectionValid: true,
    sectionsToHide: [],
    appRouteSectionsSequence: getAppRouteSectionsSequence([]),
    appRouteConfugurations: getAppRouteConfugurations(getAppRouteSectionsSequence([])),
};
export const routeReducer = (pState: IRouteState, action: IActionType): IRouteState => {
    switch (action.type) {
        case RouteReducerConstants.activeSectionChanged: {
            const activeSection = action.payload.activeSection;
            const completedSections = RouteUtils.getCompletedSectionsForActiveSection(activeSection, pState.appRouteSectionsSequence);
            const appRouteConfugurations =  getAppRouteConfugurations(getAppRouteSectionsSequence(pState.sectionsToHide));
            return { ...pState, completedSections, activeSection, appRouteConfugurations };
        }
        case RouteReducerConstants.setIsSectionValid: {
            return { ...pState, isSectionValid: action.payload.isSectionValid };
        }
        case RouteReducerConstants.updateSectionsToHide: {
            const updatedSectionsToHide = uniq(action.payload.sectionsToHide);
            const appRouteSectionsSequence = getAppRouteSectionsSequence(updatedSectionsToHide);
            const appRouteConfugurations =  getAppRouteConfugurations(appRouteSectionsSequence);
            forEach(updatedSectionsToHide, (hiddenSection) => {
                appRouteConfugurations[hiddenSection] = pState.appRouteConfugurations[hiddenSection];
            });
            return { ...pState, sectionsToHide: updatedSectionsToHide, appRouteConfugurations, appRouteSectionsSequence };
        }
        default: {
            return pState;
        }
    }
};
