import buffer from "@turf/buffer";
import { point } from "@turf/helpers";
import { polygon } from "@turf/helpers";
import disjoint from "@turf/boolean-disjoint";
import { join } from "path";

export default {
  name: "geojsonIdent",

  getReducer() {
    const initialData = {
      shouldRegister: false,
      shouldHandleRemove: false,
      removedUid: null,
      data: {},
    };

    return (state = initialData, { type, payload }) => {
      switch (type) {
        case "GEOJSON_IDENT_REGISTERED":
        case "GEOJSON_IDENT_ADDED_FEATURES":
        case "GEOJSON_IDENT_REMOVED_FEATURES":
        case "GEOJSON_IDENT_HANDLED_REMOVE":
          return Object.assign({}, state, payload);
        case "LAYER_REMOVED":
          return Object.assign({}, state, {
            removedUid: payload.uid,
            shouldHandleRemove: true,
          });
        default:
          return state;
      }
    };
  },

  doGeojsonIdentRegister: () => ({ dispatch, store }) => {
    dispatch({
      type: "GEOJSON_IDENT_REGISTERED",
      payload: { shouldRegister: false },
    });
    store.doIdentifyAddCollection({
      onIdentify: store.doGeojsonIdentFire,
    });
  },

  doGeojsonIdentRemoveFeatures: (uid) => ({ dispatch, store }) => {
    dispatch({
      type: "GEOJSON_IDENT_HANDLED_REMOVE",
      payload: { shouldHandleRemove: false },
    });
    const uid = store.selectGeojsonRemovedUid();
    const data = store.selectGeojsonIdentFeatures();
    delete data[uid];
    dispatch({
      type: "GEOJSON_IDENT_REMOVED_FEATURES",
      payload: { data: Object.assign({}, data), removedUid: null },
    });
  },

  doGeojsonIdentAddFeatures: (uid, geojson, mapLayer) => ({
    dispatch,
    store,
  }) => {
    const data = store.selectGeojsonIdentFeatures();

    if (!data[uid])
      data[uid] = {
        features: [],
        maplayer: null,
      };

    if (geojson) {
      let newFeatures = [];
      if (geojson.length) {
        newFeatures = geojson;
      } else if (geojson.features) {
        newFeatures = geojson.features;
      } else {
        newFeatures = [geojson];
      }
      data[uid].features = [...data[uid].features, ...newFeatures];
    }

    if (mapLayer) {
      data[uid].mapLayer = mapLayer;
    }

    dispatch({
      type: "GEOJSON_IDENT_ADDED_FEATURES",
      payload: { data: Object.assign({}, data) },
    });
  },

  doGeojsonIdentFire: (callback) => ({ dispatch, store }) => {
    const coords = store.selectIdentifyCoordinates();
    const resolution = store.selectResolution();
    const data = store.selectGeojsonIdentFeatures();
    let identifyFeature = null;

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

    try {
      const out = [];

      Object.keys(data).forEach((key) => {
        const outFeatures = [];
        const inFeatures = data[key].features;
        const mapLayer = data[key].mapLayer;
        if (mapLayer.getVisible()) {
          inFeatures.forEach((feature) => {
            if (!disjoint(identifyFeature, feature)) outFeatures.push(feature);
          });
          out.push({
            dataset: key,
            err: null,
            result: {
              [key]: {
                type: "FeatureCollection",
                features: outFeatures,
              },
            },
          });
        }
      });

      callback(null, out);
    } catch (err) {
      console.log(err);
      callback(err);
    }
  },

  selectGeojsonIdentFeatures: (state) => {
    return state.geojsonIdent.data;
  },

  selectGeojsonRemovedUid: (state) => {
    return state.geojsonIdent.removedUid;
  },

  reactGeojsonIdentShouldRegister: (state) => {
    if (state.geojsonIdent.shouldRegister)
      return { actionCreator: "doGeojsonIdentRegister" };
  },

  reactGeojsonIdentShouldHandleRemove: (state) => {
    if (state.geojsonIdent.shouldHandleRemove)
      return { actionCreator: "doGeojsonIdentRemoveFeatures" };
  },
};
