/*
 * Copyright © 2016-2017 European Support Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import UsersActionHelper from './users/UsersActionHelper.js';
import VersionsPageActionHelper from './versionsPage/VersionsPageActionHelper.js';
import PermissionsActionHelper from './permissions/PermissionsActionHelper.js';
import LicenseModelActionHelper from './licenseModel/LicenseModelActionHelper.js';
import LicenseAgreementActionHelper from './licenseModel/licenseAgreement/LicenseAgreementActionHelper.js';
import FeatureGroupsActionHelper from './licenseModel/featureGroups/FeatureGroupsActionHelper.js';
import LicenseKeyGroupsActionHelper from './licenseModel/licenseKeyGroups/LicenseKeyGroupsActionHelper.js';
import EntitlementPoolsActionHelper from './licenseModel/entitlementPools/EntitlementPoolsActionHelper.js';
import SoftwareProductActionHelper from './softwareProduct/SoftwareProductActionHelper.js';
import SoftwareProductProcessesActionHelper from './softwareProduct/processes/SoftwareProductProcessesActionHelper.js';
import SoftwareProductDeploymentActionHelper from './softwareProduct/deployment/SoftwareProductDeploymentActionHelper.js';
import SoftwareProductNetworksActionHelper from './softwareProduct/networks/SoftwareProductNetworksActionHelper.js';
import SoftwareProductComponentsActionHelper from './softwareProduct/components/SoftwareProductComponentsActionHelper.js';
import SoftwareProductComponentProcessesActionHelper from './softwareProduct/components/processes/SoftwareProductComponentProcessesActionHelper.js';
import SoftwareProductComponentsNetworkActionHelper from './softwareProduct/components/network/SoftwareProductComponentsNetworkActionHelper.js';
import SoftwareProductDependenciesActionHelper from './softwareProduct/dependencies/SoftwareProductDependenciesActionHelper.js';
import ComputeFlavorActionHelper from './softwareProduct/components/compute/ComputeFlavorActionHelper.js';
import OnboardActionHelper from './onboard/OnboardActionHelper.js';
import MergeEditorActionHelper from 'sdc-app/common/merge/MergeEditorActionHelper.js';
import SoftwareProductComponentsMonitoringAction from './softwareProduct/components/monitoring/SoftwareProductComponentsMonitoringActionHelper.js';
import { actionTypes, enums } from './OnboardingConstants.js';
import {
    actionTypes as SoftwareProductActionTypes,
    onboardingOriginTypes
} from 'sdc-app/onboarding/softwareProduct/SoftwareProductConstants.js';
import ActivityLogActionHelper from 'sdc-app/common/activity-log/ActivityLogActionHelper.js';
import ItemsHelper from 'sdc-app/common/helpers/ItemsHelper.js';
import SoftwareProductComponentsImageActionHelper from './softwareProduct/components/images/SoftwareProductComponentsImageActionHelper.js';
import licenseModelOverviewActionHelper from 'sdc-app/onboarding/licenseModel/overview/licenseModelOverviewActionHelper.js';
import { tabsMapping as attachmentsTabsMapping } from 'sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsConstants.js';
import SoftwareProductAttachmentsActionHelper from 'sdc-app/onboarding/softwareProduct/attachments/SoftwareProductAttachmentsActionHelper.js';

function setCurrentScreen(dispatch, screen, props = {}) {
    dispatch({
        type: actionTypes.SET_CURRENT_SCREEN,
        currentScreen: {
            screen,
            props,
            forceBreadCrumbsUpdate: true
        }
    });
}

export function updateCurrentScreenProps(dispatch, props = {}) {
    dispatch({
        type: actionTypes.UPDATE_CURRENT_SCREEN_PROPS,
        props
    });
}

const OnboardingActionHelper = {
    loadItemsLists(dispatch) {
        LicenseModelActionHelper.fetchLicenseModels(dispatch);
        LicenseModelActionHelper.fetchFinalizedLicenseModels(dispatch);
        LicenseModelActionHelper.fetchArchivedLicenseModels(dispatch);
        SoftwareProductActionHelper.fetchSoftwareProductList(dispatch);
        SoftwareProductActionHelper.fetchFinalizedSoftwareProductList(dispatch);
        SoftwareProductActionHelper.fetchArchivedSoftwareProductList(dispatch);
    },

    navigateToOnboardingCatalog(dispatch) {
        UsersActionHelper.fetchUsersList(dispatch);
        this.loadItemsLists(dispatch);
        OnboardActionHelper.resetOnboardStore(dispatch);
        setCurrentScreen(dispatch, enums.SCREEN.ONBOARDING_CATALOG);
    },

    autoSaveBeforeNavigate(
        dispatch,
        { softwareProductId, version, vspComponentId, dataToSave }
    ) {
        if (softwareProductId) {
            if (vspComponentId) {
                return SoftwareProductComponentsActionHelper.updateSoftwareProductComponent(
                    dispatch,
                    {
                        softwareProductId,
                        version,
                        vspComponentId,
                        componentData: dataToSave.componentData,
                        qdata: dataToSave.qdata
                    }
                );
            }
            return SoftwareProductActionHelper.updateSoftwareProduct(dispatch, {
                softwareProduct: dataToSave.softwareProduct,
                version,
                qdata: dataToSave.qdata
            });
        }
        return Promise.resolve();
    },

    navigateToLicenseModelOverview(
        dispatch,
        { licenseModelId, version, status }
    ) {
        /**
         * TODO change to specific rest
         */

        LicenseModelActionHelper.fetchLicenseModelById(dispatch, {
            licenseModelId,
            version
        }).then(() => {
            LicenseModelActionHelper.fetchLicenseModelItems(dispatch, {
                licenseModelId,
                version
            }).then(() => {
                setCurrentScreen(
                    dispatch,
                    enums.SCREEN.LICENSE_MODEL_OVERVIEW,
                    { licenseModelId, version, status }
                );
            });
            licenseModelOverviewActionHelper.selectVLMListView(dispatch, {
                buttonTab: null
            });
        });
    },
    navigateToLicenseAgreements(dispatch, { licenseModelId, version, status }) {
        LicenseAgreementActionHelper.fetchLicenseAgreementList(dispatch, {
            licenseModelId,
            version
        });
        LicenseModelActionHelper.fetchLicenseModelById(dispatch, {
            licenseModelId,
            version
        }).then(() => {
            setCurrentScreen(dispatch, enums.SCREEN.LICENSE_AGREEMENTS, {
                licenseModelId,
                version,
                status
            });
        });
    },

    navigateToFeatureGroups(dispatch, { licenseModelId, version, status }) {
        FeatureGroupsActionHelper.fetchFeatureGroupsList(dispatch, {
            licenseModelId,
            version
        });
        setCurrentScreen(dispatch, enums.SCREEN.FEATURE_GROUPS, {
            licenseModelId,
            version,
            status
        });
    },

    navigateToEntitlementPools(dispatch, { licenseModelId, version, status }) {
        EntitlementPoolsActionHelper.fetchEntitlementPoolsList(dispatch, {
            licenseModelId,
            version
        });
        setCurrentScreen(dispatch, enums.SCREEN.ENTITLEMENT_POOLS, {
            licenseModelId,
            version,
            status
        });
    },

    navigateToLicenseKeyGroups(dispatch, { licenseModelId, version, status }) {
        LicenseKeyGroupsActionHelper.fetchLicenseKeyGroupsList(dispatch, {
            licenseModelId,
            version
        });
        setCurrentScreen(dispatch, enums.SCREEN.LICENSE_KEY_GROUPS, {
            licenseModelId,
            version,
            status
        });
    },

    navigateToLicenseModelActivityLog(
        dispatch,
        { licenseModelId, version, status }
    ) {
        ActivityLogActionHelper.fetchActivityLog(dispatch, {
            itemId: licenseModelId,
            versionId: version.id
        });
        setCurrentScreen(dispatch, enums.SCREEN.ACTIVITY_LOG, {
            licenseModelId,
            version,
            status
        });
    },

    navigateToSoftwareProductLandingPage(
        dispatch,
        { softwareProductId, version, status }
    ) {
        SoftwareProductComponentsActionHelper.clearComponentsStore(dispatch);
        SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {
            softwareProductId,
            version
        }).then(response => {
            let { vendorId: licenseModelId, licensingVersion } = response[0];
            SoftwareProductActionHelper.loadSoftwareProductDetailsData(
                dispatch,
                { licenseModelId, licensingVersion }
            );
            SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(
                dispatch,
                { softwareProductId, version: version }
            );
            if (response[0].onboardingOrigin === onboardingOriginTypes.ZIP) {
                SoftwareProductActionHelper.loadSoftwareProductHeatCandidate(
                    dispatch,
                    { softwareProductId, version: version }
                );
            }
            setCurrentScreen(
                dispatch,
                enums.SCREEN.SOFTWARE_PRODUCT_LANDING_PAGE,
                { softwareProductId, licenseModelId, version, status }
            );
        });
    },

    navigateToSoftwareProductDetails(
        dispatch,
        { softwareProductId, version, status }
    ) {
        SoftwareProductActionHelper.fetchSoftwareProduct(dispatch, {
            softwareProductId,
            version
        }).then(response => {
            let { vendorId: licenseModelId, licensingVersion } = response[0];
            SoftwareProductActionHelper.loadLicensingVersionsList(dispatch, {
                licenseModelId
            });
            SoftwareProductActionHelper.loadSoftwareProductDetailsData(
                dispatch,
                { licenseModelId, licensingVersion }
            );
            setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_DETAILS, {
                softwareProductId,
                version,
                status
            });
        });
    },

    navigateToSoftwareProductAttachmentsSetupTab(
        dispatch,
        { softwareProductId, version, status }
    ) {
        SoftwareProductActionHelper.loadSoftwareProductHeatCandidate(dispatch, {
            softwareProductId,
            version
        });
        SoftwareProductAttachmentsActionHelper.setActiveTab(dispatch, {
            activeTab: attachmentsTabsMapping.SETUP
        });
        setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS, {
            softwareProductId,
            version,
            status
        });
    },
    navigateToSoftwareProductAttachmentsValidationTab(
        dispatch,
        { softwareProductId, version, status }
    ) {
        SoftwareProductActionHelper.processAndValidateHeatCandidate(dispatch, {
            softwareProductId,
            version
        }).then(() => {
            SoftwareProductAttachmentsActionHelper.setActiveTab(dispatch, {
                activeTab: attachmentsTabsMapping.VALIDATION
            });
            setCurrentScreen(
                dispatch,
                enums.SCREEN.SOFTWARE_PRODUCT_ATTACHMENTS,
                { softwareProductId, version, status }
            );
        });
    },

    navigateToSoftwareProductProcesses(
        dispatch,
        { softwareProductId, version, status }
    ) {
        if (softwareProductId) {
            SoftwareProductProcessesActionHelper.fetchProcessesList(dispatch, {
                softwareProductId,
                version
            });
        }
        setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_PROCESSES, {
            softwareProductId,
            version,
            status
        });
    },

    navigateToSoftwareProductNetworks(
        dispatch,
        { softwareProductId, version, status }
    ) {
        if (softwareProductId) {
            SoftwareProductNetworksActionHelper.fetchNetworksList(dispatch, {
                softwareProductId,
                version
            });
        }
        setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_NETWORKS, {
            softwareProductId,
            version,
            status
        });
    },

    navigateToSoftwareProductDependencies(
        dispatch,
        { softwareProductId, version, status }
    ) {
        SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(
            dispatch,
            { softwareProductId, version }
        ).then(result => {
            if (result.listCount >= 2) {
                SoftwareProductDependenciesActionHelper.fetchDependencies(
                    dispatch,
                    { softwareProductId, version }
                );
                setCurrentScreen(
                    dispatch,
                    enums.SCREEN.SOFTWARE_PRODUCT_DEPENDENCIES,
                    { softwareProductId, version, status }
                );
            } else {
                this.navigateToSoftwareProductLandingPage(dispatch, {
                    softwareProductId,
                    version,
                    status
                });
            }
        });
    },

    navigateToSoftwareProductComponents(
        dispatch,
        { softwareProductId, version, status }
    ) {
        SoftwareProductComponentsActionHelper.fetchSoftwareProductComponents(
            dispatch,
            { softwareProductId, version }
        );
        setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS, {
            softwareProductId,
            version,
            status
        });
    },
    navigateToSoftwareProductDeployment(
        dispatch,
        { softwareProductId, version, status }
    ) {
        SoftwareProductDeploymentActionHelper.fetchDeploymentFlavorsList(
            dispatch,
            { softwareProductId, version }
        );
        ComputeFlavorActionHelper.fetchComputesListForVSP(dispatch, {
            softwareProductId,
            version
        });
        setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_DEPLOYMENT, {
            softwareProductId,
            version,
            status
        });
    },
    navigateToSoftwareProductActivityLog(
        dispatch,
        { softwareProductId, version, status }
    ) {
        ActivityLogActionHelper.fetchActivityLog(dispatch, {
            itemId: softwareProductId,
            versionId: version.id
        });
        setCurrentScreen(dispatch, enums.SCREEN.SOFTWARE_PRODUCT_ACTIVITY_LOG, {
            softwareProductId,
            version,
            status
        });
    },

    navigateToSoftwareProductComponentProcesses(
        dispatch,
        { softwareProductId, componentId, version, status }
    ) {
        if (componentId && softwareProductId) {
            SoftwareProductComponentProcessesActionHelper.fetchProcessesList(
                dispatch,
                { componentId, softwareProductId, version }
            );
        }
        setCurrentScreen(
            dispatch,
            enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_PROCESSES,
            { softwareProductId, componentId, version, status }
        );
    },

    navigateToSoftwareProductComponentMonitoring(
        dispatch,
        { softwareProductId, version, componentId, status }
    ) {
        if (componentId && softwareProductId && version) {
            SoftwareProductComponentsMonitoringAction.fetchExistingFiles(
                dispatch,
                { componentId, softwareProductId, version }
            );
        }
        setCurrentScreen(
            dispatch,
            enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_MONITORING,
            { softwareProductId, componentId, version, status }
        );
    },

    navigateToComponentStorage(
        dispatch,
        { softwareProductId, componentId, version, status }
    ) {
        SoftwareProductComponentsActionHelper.fetchSoftwareProductComponent(
            dispatch,
            { softwareProductId, vspComponentId: componentId, version }
        );
        setCurrentScreen(
            dispatch,
            enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_STORAGE,
            { softwareProductId, version, componentId, status }
        );
    },

    navigateToComponentCompute(
        dispatch,
        { softwareProductId, componentId, version, status }
    ) {
        SoftwareProductComponentsActionHelper.fetchSoftwareProductComponent(
            dispatch,
            { softwareProductId, vspComponentId: componentId, version }
        );
        if (componentId && softwareProductId) {
            ComputeFlavorActionHelper.fetchComputesList(dispatch, {
                softwareProductId,
                componentId,
                version
            });
        }
        setCurrentScreen(
            dispatch,
            enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_COMPUTE,
            { softwareProductId, version, componentId, status }
        );
    },

    navigateToComponentNetwork(
        dispatch,
        { softwareProductId, componentId, version, status }
    ) {
        SoftwareProductComponentsNetworkActionHelper.fetchNICsList(dispatch, {
            softwareProductId,
            componentId,
            version
        });
        setCurrentScreen(
            dispatch,
            enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_NETWORK,
            { softwareProductId, version, componentId, status }
        );
    },

    navigateToSoftwareProductComponentGeneral(
        dispatch,
        { softwareProductId, componentId, version, status }
    ) {
        if (componentId && softwareProductId) {
            SoftwareProductComponentsActionHelper.fetchSoftwareProductComponent(
                dispatch,
                { softwareProductId, vspComponentId: componentId, version }
            );
        }
        setCurrentScreen(
            dispatch,
            enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_GENERAL,
            { softwareProductId, version, componentId, status }
        );
    },

    navigateToSoftwareProductComponentGeneralAndUpdateLeftPanel(
        dispatch,
        { softwareProductId, componentId, version, status }
    ) {
        this.navigateToSoftwareProductComponentGeneral(dispatch, {
            softwareProductId,
            componentId,
            version,
            status
        });
        dispatch({
            type: SoftwareProductActionTypes.TOGGLE_NAVIGATION_ITEM,
            mapOfExpandedIds: {
                [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS]: true,
                [enums.SCREEN.SOFTWARE_PRODUCT_COMPONENTS +
                '|' +
                componentId]: true
            }
        });
    },

    navigateToComponentLoadBalancing(
        dispatch,
        { softwareProductId, componentId, version, status }
    ) {
        SoftwareProductComponentsActionHelper.fetchSoftwareProductComponent(
            dispatch,
            { softwareProductId, vspComponentId: componentId, version }
        );
        setCurrentScreen(
            dispatch,
            enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_LOAD_BALANCING,
            { softwareProductId, version, componentId, status }
        );
    },

    navigateToComponentImages(
        dispatch,
        { softwareProductId, componentId, version, status }
    ) {
        SoftwareProductComponentsImageActionHelper.fetchImagesList(dispatch, {
            softwareProductId,
            componentId,
            version
        });
        setCurrentScreen(
            dispatch,
            enums.SCREEN.SOFTWARE_PRODUCT_COMPONENT_IMAGES,
            { softwareProductId, version, componentId, status }
        );
    },

    navigateToVersionsPage(
        dispatch,
        { itemType, itemId, itemName, additionalProps, users }
    ) {
        PermissionsActionHelper.fetchItemUsers(dispatch, {
            itemId,
            allUsers: users
        });
        VersionsPageActionHelper.selectNone(dispatch);
        VersionsPageActionHelper.fetchVersions(dispatch, {
            itemType,
            itemId
        }).then(() => {
            ItemsHelper.fetchItem(itemId).then(result => {
                setCurrentScreen(dispatch, enums.SCREEN.VERSIONS_PAGE, {
                    status: result.status,
                    itemType,
                    itemId,
                    itemName,
                    additionalProps
                });
            });
        });
    },

    checkMergeStatus(dispatch, { itemId, versionId, version }) {
        return ItemsHelper.fetchVersion({ itemId, versionId }).then(
            response => {
                let state = (response && response.state) || {};
                let { synchronizationState } = state;
                // let inMerge = synchronizationState === SyncStates.MERGE;
                MergeEditorActionHelper.fetchConflicts(dispatch, {
                    itemId,
                    version
                }).then(data => {
                    dispatch({
                        type: actionTypes.CHECK_MERGE_STATUS,
                        synchronizationState,
                        conflictInfoList: data.conflictInfoList
                    });
                });
            }
        );
    },

    forceBreadCrumbsUpdate(dispatch) {
        dispatch({
            type: actionTypes.SET_CURRENT_SCREEN,
            currentScreen: {
                forceBreadCrumbsUpdate: true
            }
        });
    },

    updateCurrentScreenVersion(dispatch, version) {
        dispatch({
            type: actionTypes.SET_CURRENT_SCREEN_VERSION,
            version
        });
    }
};

export default OnboardingActionHelper;
