/*
 * 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';
import { actionTypes as filterActionTypes } from './onboard/filter/FilterConstants.js';
import FeaturesActionHelper from 'sdc-app/features/FeaturesActionHelper.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);
    },

    async navigateToOnboardingCatalog(dispatch) {
        await FeaturesActionHelper.getFeaturesList(dispatch);
        UsersActionHelper.fetchUsersList(dispatch);
        this.loadItemsLists(dispatch);
        OnboardActionHelper.resetOnboardStore(dispatch);
        setCurrentScreen(dispatch, enums.SCREEN.ONBOARDING_CATALOG);
        dispatch({
            type: filterActionTypes.FILTER_DATA_CHANGED,
            deltaData: {}
        });
    },

    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);
        LicenseModelActionHelper.fetchFinalizedLicenseModels(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 }
        );
    },

    async navigateToVersionsPage(
        dispatch,
        { itemType, itemId, itemName, additionalProps, users }
    ) {
        PermissionsActionHelper.fetchItemUsers(dispatch, {
            itemId,
            allUsers: users
        });
        VersionsPageActionHelper.selectNone(dispatch);
        await VersionsPageActionHelper.fetchVersions(dispatch, {
            itemType,
            itemId
        });
        const items = await ItemsHelper.fetchItem(itemId);
        setCurrentScreen(dispatch, enums.SCREEN.VERSIONS_PAGE, {
            status: items.status,
            itemType,
            itemId,
            itemName,
            vendorName: items.properties.vendorName,
            vendorId: items.properties.vendorId,
            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;
