import { createSelector } from "redux-bundler";
import _ from "lodash";
import TreeviewPanel from "./tree-view-panel";
import LayerSubpanel from "./layer-subpanel/layer-subpanel";

export const treeView = (controls) => {
  return {
    name: "treeview",

    getReducer() {
      const initialData = {
        rootNodeCreated: false,
        configLayersLoaded: false,
        shouldRenderDetails: false,
        selectedItem: null,
        toggleExpanded: true,
        controls: controls,
        hideCounter: false,
        showSelectAll: false,
        toggleFavorites: false,
        toggleUserDefaultLayers: false,
      };

      return (state = initialData, { type, payload }) => {
        switch (type) {
          case "TREEVIEW_ROOT_CREATED":
          case "TREEVIEW_LOADED":
          case "TREEVIEW_DETAILS_PICKED":
          case "TREEVIEW_DETAILS_DISPLAYED":
          case "TREEVIEW_FOLDERS_TOGGLED":
          case "TREEVIEW_TRIGGER_HIDE_COUNTER":
          case "TREEVIEW_TRIGGER_SHOW_SELECT_ALL":
          case "TREEVIEW_TOGGLE_FAVORITES_VIEW":
          case "TREEVIEW_ORM_FAVORITES_ERROR":
          case "TREEVIEW_ORM_FAVORITES_SAVE":
          case "TREEVIEW_ORM_FAVORITES_REMOVE":
          case "TREEVIEW_ORM_REMOVE_FAVORITES_ERROR":
          case "TREEVIEW_TOGGLE_USER_DEFAULT_LAYERS_VIEW":
          case "TREEVIEW_ORM_USER_DEFAULT_LAYERS_ERROR":
          case "TREEVIEW_ORM_USER_DEFAULT_LAYERS_SAVE":
          case "TREEVIEW_ORM_USER_DEFAULT_LAYERS_REMOVE":
          case "TREEVIEW_ORM_REMOVE_USER_DEFAULT_LAYERS_ERROR":
            return Object.assign({}, state, payload);
          default:
            return state;
        }
      };
    },

    doTreeCreateRootNode:
      () =>
      ({ dispatch, store }) => {
        dispatch({
          type: "TREEVIEW_ROOT_CREATED",
          payload: { rootNodeCreated: true },
        });
        store.doAddLayer({
          id: "treeview-root",
          root: true,
          leaf: false,
          teamDatasetId: null,
          collapsed: false,
          visible: false,
          sortOrder: 0,
          displayName: "Root",
          type: "Folder",
        });
      },

    doTreeLoadDefaultLayers:
      () =>
      ({ dispatch, store }) => {
        dispatch({
          type: "TREEVIEW_LOADED",
          payload: { configLayersLoaded: true },
        });
        const params = store.selectWindowLocationParams();
        const turnOn = !params.layers
          ? []
          : params.layers.split(",").map(Number);
        const layers = store.selectDefaultLayers();
        const sortedLayers = _.orderBy(
          layers,
          ["parentId", "layerOrder"],
          ["desc", "asc"]
        );
        sortedLayers.forEach((lyr) => {
          if (lyr.parentId) {
            const idMap = store.selectIdMap();
            lyr.parentUid = idMap[lyr.parentId];
          } else {
            lyr.parentUid = store.selectTreeViewRootId();
          }
          if (lyr.teamDatasetId && turnOn.indexOf(lyr.teamDatasetId) !== -1) {
            lyr.visible = true;
          }
          store.doAddLayer(lyr);
        });
      },

    doRenderTreeView:
      () =>
      ({ dispatch, store }) => {
        store.doPrimaryPanelOpen({
          openedBy: "LayerTree",
          children: [TreeviewPanel],
        });
      },

    doOpenLayerDetails:
      (item) =>
      ({ dispatch, store }) => {
        dispatch({
          type: "TREEVIEW_DETAILS_PICKED",
          payload: { shouldRenderDetails: true, selectedItem: item },
        });
      },

    doRenderLayerDetails:
      () =>
      ({ dispatch, store }) => {
        dispatch({
          type: "TREEVIEW_DETAILS_DISPLAYED",
          payload: { shouldRenderDetails: false },
        });
        store.doPrimaryPanelOpen({
          openedBy: "LayerTree",
          children: [LayerSubpanel],
        });
      },

    doTriggerCounterHide:
      () =>
      ({ dispatch }) => {
        dispatch({
          type: "TREEVIEW_TRIGGER_HIDE_COUNTER",
          payload: { hideCounter: true },
        });
      },

    doTriggerShowSelectAll:
      () =>
      ({ dispatch }) => {
        dispatch({
          type: "TREEVIEW_TRIGGER_SHOW_SELECT_ALL",
          payload: { showSelectAll: true },
        });
      },

    selectTreeRootNode: createSelector(
      "selectLayers",
      "selectTreeViewRootId",
      "selectAppTime",
      (layers, uid, appTime) => {
        return Object.assign({}, layers[uid]);
      }
    ),
    doTreeViewToggleExpand:
      () =>
      ({ dispatch, store }) => {
        const state = store.selectTreeViewToggleExpanded();
        const treeViewRootId = store.selectTreeViewRootId();
        store.doTreeSetCollapsedAll(treeViewRootId, !state);

        dispatch({
          type: "TREEVIEW_FOLDERS_TOGGLED",
          payload: { toggleExpanded: !state },
        });
      },
    doTreeViewAddAll:
      () =>
      ({ dispatch, store }) => {
        const treeViewRootId = store.selectTreeViewRootId();
        store.doTreeSetVisibleAll(treeViewRootId, true);
      },
    doTreeViewRemoveAll:
      () =>
      ({ dispatch, store }) => {
        const treeViewRootId = store.selectTreeViewRootId();
        store.doTreeSetVisibleAll(treeViewRootId, false);
      },

    doToggleFavoritesView:
      () =>
      ({ dispatch, store }) => {
        const showView = store.selectTreeViewToggleFavoritesView();

        dispatch({
          type: "TREEVIEW_TOGGLE_FAVORITES_VIEW",
          payload: { toggleFavorites: !showView, toggleUserDefaultLayers: false },
        });
      },
    doSaveFavoriteLayerToOrm:
      (fLyr, lyr) =>
      ({ dispatch, store }) => {
        const layer = JSON.stringify(fLyr);

        window.CM_FAVORITE_SAVE(encodeURIComponent(layer), (err, response) => {
          const responseItems = response.split(";");
          const status = responseItems[0];
          const msg = decodeURIComponent(responseItems[1]);

          if (err) {
            dispatch({
              type: "TREEVIEW_ORM_FAVORITES_ERROR",
              payload: {
                notification: {
                  title: "Error Saving Layer",
                  message: msg,
                  level: "danger",
                },
              },
            });
          } else {
            if (status === "OK") {
              dispatch({
                type: "TREEVIEW_ORM_FAVORITES_SAVE",
                payload: {
                  notification: {
                    message: msg,
                    level: "success",
                  },
                },
              });

              //update layer tree state, after successful save.
              store.doUpdateFavoriteLayers("add", lyr);
              store.doLayerSetFavorite(lyr.uid, true);
            } else {
              dispatch({
                type: "TREEVIEW_ORM_FAVORITES_ERROR",
                payload: {
                  notification: {
                    title: "Error Saving Layer",
                    message: msg,
                    level: "danger",
                  },
                },
              });
            }
          }
        });
      },
    doRemoveFavoriteLayerFromOrm:
      (fLyr, lyr) =>
      ({ dispatch, store }) => {
        const layer = JSON.stringify(fLyr);

        window.CM_FAVORITE_REMOVE(
          encodeURIComponent(layer),
          (err, response) => {
            const responseItems = response.split(";");
            const status = responseItems[0];
            const msg = decodeURIComponent(responseItems[1]);

            if (err) {
              dispatch({
                type: "TREEVIEW_ORM_REMOVE_FAVORITES_ERROR",
                payload: {
                  notification: {
                    title: "Error Saving Layer",
                    message: msg,
                    level: "danger",
                  },
                },
              });
            } else {
              if (status === "OK") {
                dispatch({
                  type: "TREEVIEW_ORM_FAVORITES_REMOVE",
                  payload: {
                    notification: {
                      message: msg,
                      level: "success",
                    },
                  },
                });

                //update layer tree state, after successful remove.
                store.doUpdateFavoriteLayers("remove", lyr);
                store.doLayerSetFavorite(lyr.uid, false);
              } else {
                dispatch({
                  type: "TREEVIEW_ORM_REMOVE_FAVORITES_ERROR",
                  payload: {
                    notification: {
                      title: "Error Removing Layer from Favorites",
                      message: msg,
                      level: "danger",
                    },
                  },
                });
              }
            }
          }
        );
      },

    doToggleLayerFavoritesAdd:
      (lyr, favorite) =>
      ({ dispatch, store }) => {
        const favoritesDB = store.selectPrimaryPanelFavoritesDB();

        switch (favoritesDB) {
          case "orm":
            const fLayer = {
              id: lyr.id,
              parentId: lyr.parent.id,
              displayName: lyr.displayName,
            };

            if (favorite) {
              store.doSaveFavoriteLayerToOrm(fLayer, lyr);
            } else {
              store.doRemoveFavoriteLayerFromOrm(fLayer, lyr);
            }
          default:
            break;
        }
      },
    doToggleUserDefaultLayersAdd:
      (lyr, userDefaultLayer) =>
      ({ dispatch, store }) => {
        const userDefaultLayersDB = store.selectPrimaryPanelUserDefaultLayersDB();

        switch (userDefaultLayersDB) {
          case "orm":
            const defaultLayer = {
              id: lyr.id,
              parentId: lyr.parent.id,
              displayName: lyr.displayName,
            };

            if (userDefaultLayer) {
              store.doSaveUserDefaultLayerToOrm(defaultLayer, lyr);
            } else {
              store.doRemoveUserDefaultLayerFromOrm(defaultLayer, lyr);
            }
          default:
            break;
        }
      },
    doToggleUserDefaultLayersView:
      () =>
      ({ dispatch, store }) => {
        const showView = store.selectTreeViewToggleUserDefaultLayersView();

        dispatch({
          type: "TREEVIEW_TOGGLE_USER_DEFAULT_LAYERS_VIEW",
          payload: { toggleUserDefaultLayers: !showView, toggleFavorites: false },
        });
      },
    
    doSaveUserDefaultLayerToOrm:
      (fLyr, lyr) =>
      ({ dispatch, store }) => {
        const layer = JSON.stringify(fLyr);

        window.CM_USER_DEFAULT_LAYER_SAVE(encodeURIComponent(layer), (err, response) => {
          const responseItems = response.split(";");
          const status = responseItems[0];
          const msg = decodeURIComponent(responseItems[1]);

          if (err) {
            dispatch({
              type: "TREEVIEW_ORM_USER_DEFAULT_LAYERS_ERROR",
              payload: {
                notification: {
                  title: "Error Saving Layer",
                  message: msg,
                  level: "danger",
                },
              },
            });
          } else {
            if (status === "OK") {
              dispatch({
                type: "TREEVIEW_ORM_USER_DEFAULT_LAYERS_SAVE",
                payload: {
                  notification: {
                    message: msg,
                    level: "success",
                  },
                },
              });

              //update layer tree state, after successful save.
              store.doUpdateUserDefaultLayers("add", lyr);
              store.doLayerSetUserDefaultLayers(lyr.uid, true);
            } else {
              dispatch({
                type: "TREEVIEW_ORM_USER_DEFAULT_LAYERS_ERROR",
                payload: {
                  notification: {
                    title: "Error Saving Layer",
                    message: msg,
                    level: "danger",
                  },
                },
              });
            }
          }
        });
      },
      
    doRemoveUserDefaultLayerFromOrm:
      (fLyr, lyr) =>
      ({ dispatch, store }) => {
        const layer = JSON.stringify(fLyr);

        window.CM_USER_DEFAULT_LAYER_REMOVE(
          encodeURIComponent(layer),
          (err, response) => {
            const responseItems = response.split(";");
            const status = responseItems[0];
            const msg = decodeURIComponent(responseItems[1]);

            if (err) {
              dispatch({
                type: "TREEVIEW_ORM_REMOVE_USER_DEFAULT_LAYERS_ERROR",
                payload: {
                  notification: {
                    title: "Error Saving Layer",
                    message: msg,
                    level: "danger",
                  },
                },
              });
            } else {
              if (status === "OK") {
                dispatch({
                  type: "TREEVIEW_ORM_USER_DEFAULT_LAYERS_REMOVE",
                  payload: {
                    notification: {
                      message: msg,
                      level: "success",
                    },
                  },
                });

                //update layer tree state, after successful remove.
                store.doUpdateUserDefaultLayers("remove", lyr);
                store.doLayerSetUserDefaultLayers(lyr.uid, false);
              } else {
                dispatch({
                  type: "TREEVIEW_ORM_REMOVE_USER_DEFAULT_LAYERS_ERROR",
                  payload: {
                    notification: {
                      title: "Error Removing Layer from Favorites",
                      message: msg,
                      level: "danger",
                    },
                  },
                });
              }
            }
          }
        );
      },
      
    selectTreeViewRootId: createSelector("selectIdMap", (idMap) => {
      return idMap["treeview-root"];
    }),

    selectTreeViewToggleExpanded: (state) => {
      return state.treeview.toggleExpanded;
    },
    selectTreeViewSelectedItem: (state) => {
      return state.treeview.selectedItem;
    },
    selectTreeViewControls: (state) => {
      return state.treeview.controls;
    },
    selectTreeViewHideCounter: (state) => {
      return state.treeview.hideCounter;
    },
    selectTreeViewShowSelectAll: (state) => {
      return state.treeview.showSelectAll;
    },
    selectTreeViewToggleFavoritesView: (state) => {
      return state.treeview.toggleFavorites;
    },
    selectTreeViewToggleUserDefaultLayersView: (state) => {
      return state.treeview.toggleUserDefaultLayers;
    },
    reactCreateRootNode: (state) => {
      if (!state.treeview.rootNodeCreated)
        return { actionCreator: "doTreeCreateRootNode" };
    },

    reactLoadLayersFromConfig: (state) => {
      if (state.treeview.rootNodeCreated && !state.treeview.configLayersLoaded)
        return { actionCreator: "doTreeLoadDefaultLayers" };
    },

    reactShouldRenderLayerDetails: (state) => {
      if (state.treeview.shouldRenderDetails)
        return { actionCreator: "doRenderLayerDetails" };
    },
  };
};
export default treeView;
