import parallel from "async/parallel";
import flatten from "lodash/flatten";
import buffer from "@turf/buffer";
import { point, polygon } from "@turf/helpers";

export default {
  name: "identify",

  getReducer() {
    const initialData = {
      shouldFire: false,
      coordinates: null,
      listeners: [],
      results: [],
    };

    return (state = initialData, { type, payload }) => {
      switch (type) {
        case "IDENTIFY_COLLECTION_ADDED":
        case "IDENTIFY_SHOULD_FIRE":
        case "IDENTIFY_COORDINATES_SET":
        case "IDENTIFY_STARTED":
        case "IDENTIFY_ERROR":
        case "IDENTIFY_SUCCESS":
          return Object.assign({}, state, payload);
        default:
          return state;
      }
    };
  },

  doIdentifyAddCollection: (options) => ({ dispatch, store }) => {
    const listeners = store.selectIdentifyListeners();
    if (options.onIdentify) listeners.push(options.onIdentify);
    dispatch({
      type: "IDENTIFY_COLLECTION_ADDED",
      payload: { listeners: listeners },
    });
  },

  doIdentifyShouldFire: () => ({ dispatch }) => {
    dispatch({ type: "IDENTIFY_SHOULD_FIRE", payload: { shouldFire: true } });
  },

  doIdentifySetCoords: (geom) => ({ dispatch, store }) => {
    geom.transform("EPSG:3857", "EPSG:4326");
    const coordinates = geom.getCoordinates();
    dispatch({
      type: "IDENTIFY_COORDINATES_SET",
      payload: { coordinates: coordinates, results: [], shouldFire: true },
    });
  },
  doSetIdentifyFeature: () => ({ store }) => {
    const coords = store.selectIdentifyCoordinates();
    const resolution = store.selectResolution();
    const bufferValue = store.selectIdentifyBufferValue();
    let identifyFeature = null;

    if (bufferValue > 0) {
      identifyFeature = store.selectIdentifyBufferFeature();
    } else {
      if (typeof coords[0] === "number") {
        const pt = point(coords);
        const radius = (resolution * 5) / 1000;
        identifyFeature = buffer(pt, radius, {
          units: "kilometers",
        });
      } else {
        identifyFeature = polygon(coords);
      }
    }

    return identifyFeature;
  },

  doIdentifyFire: () => ({ dispatch, store }) => {
    dispatch({ type: "IDENTIFY_STARTED", payload: { shouldFire: false } });
    //store.doBasicToolbarDeactivate();
    store.doSetCursor("wait");
    const listeners = store.selectIdentifyListeners();

    parallel(listeners, (err, r) => {
      if (err) {
        store.doSetCursor("default");
        return dispatch({
          type: "IDENTIFY_ERROR",
          payload: {
            err: err,
            notification: {
              level: "danger",
              title: "Identify Error",
              message: `${JSON.stringify(err)}`,
            },
          },
        });
      } else {
        const results = flatten(r);
        dispatch({ type: "IDENTIFY_SUCCESS", payload: { results: results } });
        store.doSetCursor("default");
      }
    });
  },

  selectIdentifyCoordinates: (state) => {
    return state.identify.coordinates;
  },

  selectIdentifyListeners: (state) => {
    return state.identify.listeners;
  },

  selectIdentifyResults: (state) => {
    return state.identify.results;
  },

  reactIdentifyShouldFire: (state) => {
    if (state.identify.shouldFire) return { actionCreator: "doIdentifyFire" };
  },
};
