import { createSelector } from 'reselect';
import { NETWORK_KINDS } from 'constants/network';
import { prop, pipe } from 'ramda';
import {
  combAllLinkagesBySubnetwork,
  combLinkagesBySubnetwork,
  combLinkagesByTwoSubnetwork,
  combNodesAndBeliefs,
  combNodesAndBeliefsMSBN,
  combNodesWithPositions,
  combNodesWithSizes,
  combSubnetworksById,
  combSubnetworksColorById,
  combNodesIsSelected,
  combNetworkMSBNDescription,
} from './combiners';

export const getNetwork = state => state.network;
export const getNodes = state => state.network.nodes || state.nodes || [];
export const getPositions = state => state.network.positions || state.positions || [];
export const getBeliefs = state => state.network.beliefs;
export const getSubnetworks = state => state.network.subnetworks || [];
export const getSelectedNodes = pipe(getNetwork, prop('selectedNodes'));
export const getNetworkKind = state => state.network.kind || NETWORK_KINDS.BN;
export const getPanelVisibility = state => state.network.propertiesPanelVisible;
export const getLinkages = state => state.network.linkages;
export const getInferenceEnabled = (state) => {
  const { inferenceEnabled } = getNetwork(state);

  return inferenceEnabled === undefined ? true : inferenceEnabled;
};

export const getStateToSave = createSelector(
  getNetwork,
  getNodes,
  getPositions,
  getSubnetworks,
  (network, nodes, positions, subnetworks) => ({
    version: 2,
    network: {
      ...network,
      selectedNodes: [],
      beliefs: {},
      subnetworks: subnetworks.map(sub => ({
        ...sub,
        beliefs: {},
      })),
    },
    nodes,
    positions,
  }),
);

export const getSelectedNode = createSelector(
  getNetwork,
  getNodes,
  (network, nodes) => {
    if (network.selectedNodes.length !== 1) {
      return null;
    }

    return nodes.find(x => x.id === network.selectedNodes[0]);
  },
);

export const getSelectedSubnetwork = createSelector(
  getNetwork,
  getSubnetworks,
  (network, subnetworks) => {
    if (network.selectedNodes.length !== 1) {
      return null;
    }

    return subnetworks.find(sub => sub.id === network.selectedNodes[0]);
  },
);

export const getNodesWithPositionsAndSizes = createSelector(
  getNodes,
  getPositions,
  getSelectedNodes,
  (nodes, position, selectedNodes) =>
    combNodesWithSizes(
      combNodesIsSelected(
        combNodesWithPositions(nodes, position),
        selectedNodes,
      ),
    ),
);

export const getSubnetworksWithPositionAndSizes = createSelector(
  getSubnetworks,
  getPositions,
  getSelectedNodes,
  (subnetworks, positions, selectedNodes) => combNodesWithSizes(
    combNetworkMSBNDescription(
      combNodesIsSelected(
        combNodesWithPositions(subnetworks, positions),
        selectedNodes,
      ),
    ),
  ),
);

export const getInferenceResults = createSelector(
  getNodes,
  getBeliefs,
  getInferenceEnabled,
  combNodesAndBeliefs,
);

export const getInferenceResultsMSBN = createSelector(
  getSubnetworks,
  getLinkages,
  getBeliefs,
  getInferenceEnabled,
  combNodesAndBeliefsMSBN,
);

export const getLinkagesBySubnetwork = createSelector(
  getLinkages,
  getSubnetworks,
  combLinkagesBySubnetwork,
);

export const getAllLinkagesBySubnetworkWithoutId = createSelector(
  getLinkages,
  getSubnetworks,
  combAllLinkagesBySubnetwork,
);


export const getLinkagesByTwoSubnetwork = createSelector(
  getLinkages,
  combLinkagesByTwoSubnetwork,
);

export const getSubnetworksById = createSelector(
  getSubnetworks,
  combSubnetworksById,
);

export const getSubnetworksColorById = createSelector(
  getSubnetworks,
  combSubnetworksColorById,
);

@@ -103,19 +103,27 @@
  prop, p
-ipe
+ath, pathOr
  %7D from 
@@ -481,38 +481,31 @@
 twork = 
-state =%3E state.
+prop('
 network
+')
 ;%0Aexport
@@ -690,38 +690,36 @@
 s = 
-state =%3E state.
+path(%5B'
 network
-.
+', '
 beliefs
+'%5D)
 ;%0Aex
@@ -737,133 +737,126 @@
 getS
-ubnetworks = state =%3E state.network.subnetworks %7C%7C %5B%5D;%0Aexport const getSelectedNodes = pipe(getN
+electedNodes = path(%5B'network', 'selectedNodes'%5D);%0Aexport const getSubnetworks = pathOr(%5B%5D, %5B'n
 etwork
+'
 , 
-prop('selectedNodes')
+'subnetworks'%5D
 );%0Ae
@@ -888,55 +888,53 @@
 d = 
-state =%3E state.network.kind %7C%7C NETWORK_KINDS.BN
+pathOr(NETWORK_KINDS.BN, %5B'network', 'kind'%5D)
 ;%0Aex
@@ -965,39 +965,34 @@
 ility = 
-state =%3E state.
+path(%5B'
 network
-.
+', '
 properti
@@ -1005,16 +1005,19 @@
 lVisible
+'%5D)
 ;%0Aexport
@@ -1041,39 +1041,34 @@
 s = 
-state =%3E state.
+path(%5B'
 network
-.
+', '
 linkages
 ;%0Aex
@@ -1063,17 +1063,21 @@
 linkages
-;
+'%5D);%0A
 %0Aexport 

Refactor `main` selectors