import {
    addNotifiedUser,
    createCase,
    ICasePayload,
    INotifiedUserPayload,
    INotifiedUsers,
    IRecommendation,
    IStrataAccountResponse
} from '@rh-support/api';
import { IAction } from '@rh-support/types';
import { IContact } from 'hydrajs/types/src/models/contact';
import filter from 'lodash/filter';
import map from 'lodash/map';
import { createCasePayload, getCaseRecommendations } from './CreateCaseHelpers';

// Constants
export enum KtQuestionConstant {
    issue = 'What problem/issue/behavior are you having trouble with?  What do you expect to see?',
    environment = 'Where are you experiencing the behavior? What environment?',
    periodicityOfIssue = 'When does the behavior occur? Frequency? Repeatedly? At certain times?',
    timeFramesAndUrgency = 'What information can you provide around timeframes and the business impact?'
}

export const enum SupportLevelsInternal {
    SELF_SUPPORT = 'selfSupport',
    STANDARD = 'standard',
    PREMIUM = 'premium'
}
export const enum SeverityLevelsInternal {
    SEV_1 = '1 (Urgent)',
    SEV_2 = '2 (High)',
    SEV_3 = '3 (Normal)',
    SEV_4 = '4 (Low)'
}

export const ITRForSLASeverity = {
    [SupportLevelsInternal.SELF_SUPPORT]: {
        [SeverityLevelsInternal.SEV_1]: {initial: '', ongoing: ''},
        [SeverityLevelsInternal.SEV_2]: {initial: '', ongoing: ''},
        [SeverityLevelsInternal.SEV_3]: {initial: '', ongoing: ''},
        [SeverityLevelsInternal.SEV_4]: {initial: '', ongoing: ''}
    },
    [SupportLevelsInternal.STANDARD]: {
        [SeverityLevelsInternal.SEV_1]: {initialAndOngoing: '1 business hour'},
        [SeverityLevelsInternal.SEV_2]: {initialAndOngoing: '4 business hours'},
        [SeverityLevelsInternal.SEV_3]: {initialAndOngoing: '1 business day'} ,
        [SeverityLevelsInternal.SEV_4]: {initialAndOngoing: '2 business days'}
    },
    [SupportLevelsInternal.PREMIUM]: {
        [SeverityLevelsInternal.SEV_1]: {initial: '1 hour', ongoing: '1 hour or as agreed'},
        [SeverityLevelsInternal.SEV_2]: {initial: '2 hours', ongoing: '4 hours or as agreed'},
        [SeverityLevelsInternal.SEV_3]: {initial: '4 business hours', ongoing: '8 business hours or as agreed'},
        [SeverityLevelsInternal.SEV_4]: {initial: '8 business hours', ongoing: '2 business days or as agreed'}
    }
};

export const LargeDescriptionErrorMessage = 'Cumulative case description cannot be more than 32000 characters';

export enum CreateCaseReducerConstants {
    caseDetailsChanged = 'caseDetailsChanged',
    caseCreated = 'caseCreated',
    resetAppState = 'reset',
    setSelectedNotificationContacts = 'setSelectedNotificationContacts',
    isCreatingCase = 'isCreatingCase',
    setCaseCreationError = 'setCaseCreationError',
    setCaseRecommendations = 'setCaseRecommendations',
    setAddNotifiedUserError = 'setAddNotifiedUserError'
}

export const initialCreateCaseState: ICreateCaseState = {
    product: undefined,
    version: undefined,
    description: '',
    issue: '',
    environment: '',
    periodicityOfIssue: '',
    timeFramesAndUrgency: '',
    summary: '',
    type: '',
    severity: '',
    entitlement: undefined,
    folderNumber: undefined,
    accountNumber: '',
    fts: undefined,
    contactInfo24X7: undefined,
    contactSsoUsername: undefined,
    enhancedSLA: undefined,
    language: undefined,
    recommendations: {recommendation: []},
    caseNumber: undefined,
    isCreatingCase: false,
    caseCreationError: false,
    caseCreationErrorMessage: '',
    notifiedUsers: { user: [] },
    selectedNotificationContacts: [],
    addNotifiedUserError: false,
    hasLargeCaseDescription: false
};

export interface ICreateCaseState extends ICasePayload, INotifiedUserPayload {
    caseNumber: string;
    selectedNotificationContacts: IContact[];
    isCreatingCase: boolean;
    caseCreationError: boolean;
    caseCreationErrorMessage: string;
    addNotifiedUserError: boolean;
    hasLargeCaseDescription: boolean;
}

export interface ICreateCasePayloadType extends ICreateCaseState { }
type IActionType = IAction<CreateCaseReducerConstants, ICreateCasePayloadType>;
export type CreateCaseReducerDispatchType = (value: IActionType) => void;

export const createCaseReducer = (pState: ICreateCaseState, action: IActionType): ICreateCaseState => {
    switch (action.type) {
        case CreateCaseReducerConstants.caseDetailsChanged: {
            if (action.payload && action.payload.hasOwnProperty('description')) {
              action.payload.hasLargeCaseDescription = action.payload.description.length > 32000;
            }
            return { ...pState, ...action.payload };
        }
        case CreateCaseReducerConstants.setSelectedNotificationContacts: {
            const selectedNotificationContacts = action.payload.selectedNotificationContacts || [];
            const notifiedUsers = {
                user: map(selectedNotificationContacts, (contact) => ({ ssoUsername: contact.ssoUsername }))
            };
            return { ...pState, selectedNotificationContacts, notifiedUsers };
        }
        case CreateCaseReducerConstants.resetAppState: {
            return { ...pState, ...initialCreateCaseState };
        }
        case CreateCaseReducerConstants.isCreatingCase: {
            return {...pState, caseNumber: null, isCreatingCase: true, caseCreationError: false, caseCreationErrorMessage: ''};
        }
        case CreateCaseReducerConstants.caseCreated: {
            return { ...pState, caseNumber: action.payload.caseNumber, isCreatingCase: false, caseCreationError: false, caseCreationErrorMessage: '' };
        }
        case CreateCaseReducerConstants.setCaseCreationError: {
            return {...pState, isCreatingCase: false, caseCreationError: true, caseCreationErrorMessage: action.payload.caseCreationErrorMessage };
        }
        // Recommendation docs track
        case CreateCaseReducerConstants.setCaseRecommendations: {
            return { ...pState, recommendations: action.payload.recommendations };
        }
        case CreateCaseReducerConstants.setAddNotifiedUserError: {
            return {...pState, addNotifiedUserError: action.payload.addNotifiedUserError};
        }
        default: {
            return pState;
        }
    }
};

// actions
export const setCaseCreationDetails = (dispatch: CreateCaseReducerDispatchType, caseDetails: Partial<ICreateCaseState>) => {
    dispatch({ type: CreateCaseReducerConstants.caseDetailsChanged, payload: { ...caseDetails } });
};
export const setNotifiedUser = (dispatch: CreateCaseReducerDispatchType, selectedNotificationContacts: IContact[]) => {
    dispatch({ type: CreateCaseReducerConstants.setSelectedNotificationContacts, payload: { selectedNotificationContacts } });
};

export const submitCase = async (dispatch: CreateCaseReducerDispatchType, caseDetails: ICreateCaseState, loggedInUsersAccount: Partial<IStrataAccountResponse>) => {
    dispatch({type: CreateCaseReducerConstants.isCreatingCase});
    try {
        const casePayload = createCasePayload(caseDetails, loggedInUsersAccount);
        const caseNumber = await createCase(casePayload);
        if (caseDetails.notifiedUsers.user.length > 0) {
           await submitNotifiedUser(dispatch, caseNumber, caseDetails);
        }
        dispatch({ type: CreateCaseReducerConstants.caseCreated, payload: { caseNumber } });
    } catch (error) {
        dispatch({type: CreateCaseReducerConstants.setCaseCreationError, payload: { caseCreationErrorMessage: error.message}});
    }
};
export const setCaseRecommendations = (dispatch: CreateCaseReducerDispatchType, docs: IRecommendation[], oldRecommendations: any) => {
    const recommendations = getCaseRecommendations(docs, oldRecommendations.recommendation);
    dispatch({ type: CreateCaseReducerConstants.setCaseRecommendations, payload: {
        recommendations: {recommendation: recommendations}
    }});
};

const submitNotifiedUser = async (
    dispatch: CreateCaseReducerDispatchType,
    caseNumber: string,
    caseDetails: ICreateCaseState
) => {
    dispatch({type: CreateCaseReducerConstants.setAddNotifiedUserError, payload: {addNotifiedUserError: false}});
    try {
        const user: INotifiedUsers = {user: (filter(caseDetails.notifiedUsers.user, (o) => (o.ssoUsername)) as any)};
        await addNotifiedUser(user, caseNumber);
        dispatch({type: CreateCaseReducerConstants.setAddNotifiedUserError, payload: {addNotifiedUserError: false}});
    } catch (error) {
        dispatch({type: CreateCaseReducerConstants.setAddNotifiedUserError, payload: {addNotifiedUserError: true}});
    }
};
