import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _objectSpread from "@babel/runtime/helpers/objectSpread";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import { requestFetchFile, openFileInEditor } from './connection';
import { ACTIONS as VIEW_SWITCHES_ACTIONS } from '../controlsBus/constants';
import { ACTIONS as NAMESPACE_INTEGRATION_ACTIONS } from '../namespaceIntegration/constants';
import { getCheckedState, getValuesState, getDisabledState } from '../controlsBus/selectors';
import { getFoldersForPaths, downloadObjectAsJsonFile, uploadFileAsObject } from './utils';
import { getTreeLayout, getFilesForCurrentCcFlow, getCodeCrumbsMapForCurrentCcFlow } from './utils/treeLayout';
import { ACTIONS } from './constants';
import { getNamespacesList, getSource, getSourceUserChoice, getCodeCrumbsUserChoice, getDependenciesUserChoice, getProjectMetadata } from './selectors';
export var setInitialSourceData = function setInitialSourceData(payload, namespace) {
  return {
    type: ACTIONS.SET_INITIAL_SOURCE_DATA,
    payload: payload,
    namespace: namespace
  };
};
export var setChangedSourceData = function setChangedSourceData(_ref, namespace) {
  var newlyAddedFlow = _ref.newlyAddedFlow,
      payload = _objectWithoutProperties(_ref, ["newlyAddedFlow"]);

  return function (dispatch) {
    dispatch({
      type: ACTIONS.SET_CHANGED_SOURCE_DATA,
      payload: payload,
      namespace: namespace
    });

    if (newlyAddedFlow) {
      dispatch(selectCodeCrumbedFlow(newlyAddedFlow, namespace));
    }
  };
};
export var selectNode = function selectNode(fileNode, namespace) {
  return function (dispatch) {
    dispatch({
      type: ACTIONS.SELECT_NODE,
      payload: fileNode,
      namespace: namespace
    });

    if (!process.env.LOCAL) {
      return;
    }

    requestFetchFile({
      path: [fileNode.path],
      parseDependencies: true
    }, namespace);
  };
};
export var selectNodeToOpenInEditor = function selectNodeToOpenInEditor(_ref2, namespace) {
  var path = _ref2.path,
      line = _ref2.line;
  return function () {
    if (!process.env.LOCAL) {
      return;
    }

    openFileInEditor({
      path: path,
      line: line
    }, namespace);
  };
};
export var updateFiles = function updateFiles(_ref3, namespace) {
  var files = _ref3.files;
  return {
    type: ACTIONS.UPDATE_FILES,
    payload: files,
    namespace: namespace
  };
};
export var toggleFolder = function toggleFolder(folderNode, namespace) {
  return {
    type: ACTIONS.TOGGLE_FOLDER,
    payload: folderNode,
    namespace: namespace
  };
};
export var openAllFolders = function openAllFolders(namespace) {
  return {
    type: ACTIONS.OPEN_ALL_FOLDERS,
    namespace: namespace
  };
};
export var closeAllFolders = function closeAllFolders(namespace) {
  return {
    type: ACTIONS.CLOSE_ALL_FOLDERS,
    namespace: namespace
  };
};
export var selectCodeCrumb = function selectCodeCrumb(payload, namespace) {
  return {
    type: ACTIONS.SELECT_CODE_CRUMB,
    payload: payload,
    namespace: namespace
  };
};
export var setDependenciesEntryPoint = function setDependenciesEntryPoint(fileNode, namespace) {
  return function (dispatch, getState) {
    var state = getState();

    var _getCheckedState = getCheckedState(state),
        dependenciesShowDirectOnly = _getCheckedState.dependenciesShowDirectOnly;

    return dispatch({
      type: ACTIONS.SET_DEPENDENCIES_ENTRY_POINT,
      payload: {
        fileNode: fileNode,
        dependenciesShowDirectOnly: dependenciesShowDirectOnly
      },
      namespace: namespace
    });
  };
};
export var selectDependencyEdge = function selectDependencyEdge(options, namespace) {
  return function (dispatch) {
    var _ref4 = options || {},
        target = _ref4.target,
        sources = _ref4.sources,
        groupName = _ref4.groupName;

    dispatch({
      type: ACTIONS.SELECT_DEPENDENCY_EDGE,
      payload: target ? {
        target: target,
        sources: sources,
        groupName: groupName
      } : null,
      namespace: namespace
    });

    if (target && sources) {
      requestFetchFile({
        path: [target].concat(sources)
      }, namespace);
    }
  };
};
export var selectCodeCrumbedFlow = function selectCodeCrumbedFlow(flow, namespace) {
  return function (dispatch, getState) {
    var state = getState();

    var _getCodeCrumbsUserCho = getCodeCrumbsUserChoice(state, {
      namespace: namespace
    }),
        selectedCrumbedFlowKey = _getCodeCrumbsUserCho.selectedCrumbedFlowKey,
        codeCrumbedFlowsMap = _getCodeCrumbsUserCho.codeCrumbedFlowsMap;

    dispatch({
      type: ACTIONS.SELECT_CODE_CRUMBED_FLOW,
      payload: flow ? flow : selectedCrumbedFlowKey || Object.keys(codeCrumbedFlowsMap || {})[0],
      namespace: namespace
    });
  };
};
export var selectCcFlowEdge = function selectCcFlowEdge(payload, namespace) {
  return function (dispatch) {
    dispatch({
      type: ACTIONS.SELECT_CC_FLOW_EDGE,
      payload: payload,
      namespace: namespace
    });
  };
};
export var calcFilesTreeLayoutNodes = function calcFilesTreeLayoutNodes(namespace) {
  return function (dispatch, getState) {
    var state = getState();
    var namespaceConfig = {
      namespace: namespace
    };

    var _getSource = getSource(state, namespaceConfig),
        sourceTree = _getSource.sourceTree,
        filesMap = _getSource.filesMap;

    var _getSourceUserChoice = getSourceUserChoice(state, namespaceConfig),
        openedFolders = _getSourceUserChoice.openedFolders,
        activeItemsMap = _getSourceUserChoice.activeItemsMap;

    var _getCodeCrumbsUserCho2 = getCodeCrumbsUserChoice(state, namespaceConfig),
        codeCrumbedFlowsMap = _getCodeCrumbsUserCho2.codeCrumbedFlowsMap,
        selectedCrumbedFlowKey = _getCodeCrumbsUserCho2.selectedCrumbedFlowKey;

    var _getCheckedState2 = getCheckedState(state),
        codeCrumbsDiagramOn = _getCheckedState2.codeCrumbsDiagramOn,
        codeCrumbsMinimize = _getCheckedState2.codeCrumbsMinimize,
        codeCrumbsDetails = _getCheckedState2.codeCrumbsDetails,
        codeCrumbsCodePreview = _getCheckedState2.codeCrumbsCodePreview;

    if (!sourceTree) return;
    var activeCodeCrumbs = undefined;

    if (codeCrumbedFlowsMap[selectedCrumbedFlowKey]) {
      activeCodeCrumbs = getCodeCrumbsMapForCurrentCcFlow({
        codeCrumbedFlowsMap: codeCrumbedFlowsMap,
        selectedCrumbedFlowKey: selectedCrumbedFlowKey,
        filesMap: filesMap
      });
    }

    return dispatch({
      type: ACTIONS.UPDATE_FILES_TREE_LAYOUT_NODES,
      payload: getTreeLayout(sourceTree, {
        includeFileChildren: codeCrumbsDiagramOn && !codeCrumbsMinimize,
        extraSpaceForDetails: codeCrumbsDetails,
        extraSpaceForCodePreview: codeCrumbsCodePreview,
        openedFolders: openedFolders,
        activeItemsMap: activeItemsMap,
        activeCodeCrumbs: activeCodeCrumbs
      }),
      namespace: namespace
    });
  };
};
export var setActiveItems = function setActiveItems(_ref5, namespace) {
  var filesList = _ref5.filesList,
      _ref5$foldersMap = _ref5.foldersMap,
      foldersMap = _ref5$foldersMap === void 0 ? {} : _ref5$foldersMap;
  return function (dispatch, getState) {
    var state = getState();

    var _getSourceUserChoice2 = getSourceUserChoice(state, {
      namespace: namespace
    }),
        activeItemsMap = _getSourceUserChoice2.activeItemsMap;

    var _getCheckedState3 = getCheckedState(state),
        sourceKeepOnlyActiveItems = _getCheckedState3.sourceKeepOnlyActiveItems;

    return dispatch({
      type: ACTIONS.SET_ACTIVE_ITEMS,
      payload: _objectSpread({}, !sourceKeepOnlyActiveItems ? activeItemsMap : {}, filesList.reduce(function (acc, item) {
        //TODO:move this to util!
        acc[item] = true;
        return acc;
      }, {}), foldersMap),
      namespace: namespace
    });
  };
}; // TODO: refactor too long does too much

export var updateFoldersByActiveChildren = function updateFoldersByActiveChildren(namespace) {
  return function (dispatch, getState) {
    var state = getState();
    var namespaceConfig = {
      namespace: namespace
    };

    var _getSource2 = getSource(state, namespaceConfig),
        filesMap = _getSource2.filesMap;

    var _getSourceUserChoice3 = getSourceUserChoice(state, namespaceConfig),
        openedFolders = _getSourceUserChoice3.openedFolders,
        selectedNode = _getSourceUserChoice3.selectedNode;

    var _getCodeCrumbsUserCho3 = getCodeCrumbsUserChoice(state, namespaceConfig),
        codeCrumbedFlowsMap = _getCodeCrumbsUserCho3.codeCrumbedFlowsMap,
        selectedCrumbedFlowKey = _getCodeCrumbsUserCho3.selectedCrumbedFlowKey;

    var _getProjectMetadata = getProjectMetadata(state, namespaceConfig),
        platformPathSeparator = _getProjectMetadata.platformPathSeparator;

    var _getCheckedState4 = getCheckedState(state),
        dependenciesDiagramOn = _getCheckedState4.dependenciesDiagramOn,
        codeCrumbsDiagramOn = _getCheckedState4.codeCrumbsDiagramOn,
        sourceKeepOnlyActiveItems = _getCheckedState4.sourceKeepOnlyActiveItems;

    var depFilePaths = dependenciesDiagramOn ? Object.keys(selectedNode.dependencies || {}) : [];
    var ccFilePaths = codeCrumbsDiagramOn ? Object.keys(filesMap).filter(function (path) {
      return filesMap[path].hasCodecrumbs;
    }) : [];

    if (codeCrumbedFlowsMap[selectedCrumbedFlowKey]) {
      var currentFlowFiles = getFilesForCurrentCcFlow({
        codeCrumbedFlowsMap: codeCrumbedFlowsMap,
        selectedCrumbedFlowKey: selectedCrumbedFlowKey,
        filesMap: filesMap
      });
      ccFilePaths = ccFilePaths.filter(function (path) {
        return currentFlowFiles.includes(path);
      });
    }

    var filesList = [selectedNode.path].concat(depFilePaths, ccFilePaths);

    if (!filesList.length) {
      sourceKeepOnlyActiveItems && dispatch(setActiveItems({
        filesList: filesList
      }, namespace));
      return sourceKeepOnlyActiveItems ? dispatch(closeAllFolders(namespace)) : undefined;
    }

    var foldersMap = getFoldersForPaths(filesList, openedFolders, sourceKeepOnlyActiveItems, platformPathSeparator);
    dispatch(setActiveItems({
      filesList: filesList,
      foldersMap: foldersMap
    }, namespace));
    dispatch({
      type: ACTIONS.SET_FOLDERS_STATE,
      payload: foldersMap,
      namespace: namespace
    });
  };
}; // TODO: group and move actions to different files

export var downloadStore = function downloadStore() {
  return function (dispatch, getState) {
    var state = getState();
    var namespacesList = getNamespacesList(state);
    var partialStateToSave = namespacesList.reduce(function (acc, namespace) {
      var namespaceConfig = {
        namespace: namespace
      };

      var _getSource3 = getSource(state, namespaceConfig),
          sourceTree = _getSource3.sourceTree,
          filesMap = _getSource3.filesMap,
          foldersMap = _getSource3.foldersMap;

      var _getDependenciesUserC = getDependenciesUserChoice(state, namespaceConfig),
          dependenciesEntryName = _getDependenciesUserC.dependenciesEntryName;

      var _getCodeCrumbsUserCho4 = getCodeCrumbsUserChoice(state, namespaceConfig),
          codeCrumbedFlowsMap = _getCodeCrumbsUserCho4.codeCrumbedFlowsMap,
          selectedCrumbedFlowKey = _getCodeCrumbsUserCho4.selectedCrumbedFlowKey;

      var _getProjectMetadata2 = getProjectMetadata(state, namespaceConfig),
          projectName = _getProjectMetadata2.projectName,
          language = _getProjectMetadata2.language,
          platformPathSeparator = _getProjectMetadata2.platformPathSeparator;

      return _objectSpread({}, acc, {
        dataBus: _objectSpread({}, acc.dataBus, _defineProperty({}, namespace, {
          sourceTree: sourceTree,
          filesMap: filesMap,
          foldersMap: foldersMap,
          codeCrumbedFlowsMap: codeCrumbedFlowsMap,
          selectedCrumbedFlowKey: selectedCrumbedFlowKey,
          dependenciesEntryName: dependenciesEntryName,
          projectName: projectName,
          language: language,
          platformPathSeparator: platformPathSeparator
        }))
      });
    }, {
      controlsBus: {
        checkedState: getCheckedState(state),
        valuesState: getValuesState(state),
        disabledState: getDisabledState(state)
      },
      dataBus: {}
    });
    downloadObjectAsJsonFile(partialStateToSave);
  };
};
export var uploadStore = function uploadStore(file) {
  return function (dispatch) {
    uploadFileAsObject(file).then(function (object) {
      return dispatch(setPredefinedState(object.data));
    });
  };
};
export var setPredefinedState = function setPredefinedState(predefinedState) {
  return function (dispatch) {
    dispatch({
      type: VIEW_SWITCHES_ACTIONS.SET_FULL_STATE,
      payload: predefinedState.controlsBus
    }); //TODO: add flag on UI to not reset previous state

    dispatch({
      type: NAMESPACE_INTEGRATION_ACTIONS.RESET_ALL
    });
    dispatch({
      type: ACTIONS.RESET_ALL
    });
    Object.keys(predefinedState.dataBus).forEach(function (namespace, i) {
      // TODO: test  performance here
      setTimeout(function () {
        dispatch(setInitialSourceData(predefinedState.dataBus[namespace], namespace));
      }, 100 * i);
    });
  };
};
export var setFullState = function setFullState(payload) {
  return {
    type: ACTIONS.SET_FULL_STATE,
    payload: payload
  };
};
export var setNamespaceState = function setNamespaceState(payload) {
  return {
    type: ACTIONS.SET_NAMESPACE_STATE,
    payload: payload
  };
};