import buffer from "@turf/buffer";
import { point } from "@turf/helpers";
import { polygon } from "@turf/helpers";
import disjoint from "@turf/boolean-disjoint";
import bbox from "@turf/bbox";
import GeoJSON from "ol/format/GeoJSON";
import { transformExtent, transform, fromLonLat } from "ol/proj";
import async from "async";

const geoJSON = new GeoJSON();
// TODO Layer list should be checked like identify-arcgis-rest.js
function formatUrl(options) {
  let url = `${options.root}/identify?`;
  const params = [];
  for (var key in options) {
    if (key !== "root") params.push(key + "=" + options[key].toString());
  }
  url += params.join("&");
  return url;
}

export default {
  name: "arcGisRestIdent",

  getReducer() {
    const initialData = {
      shouldRegister: true,
    };

    return (state = initialData, { type, payload }) => {
      switch (type) {
        case "ARCGIS_IDENT_REGISTERED":
          return Object.assign({}, state, payload);
        default:
          return state;
      }
    };
  },

  doArcGisRestIdentRegister:
    () =>
    ({ dispatch, store }) => {
      dispatch({
        type: "ARCGIS_IDENT_REGISTERED",
        payload: { shouldRegister: false },
      });
      store.doIdentifyAddCollection({
        onIdentify: store.doArcGisRestIdentFire,
      });
    },

  doArcGisRestIdentFire:
    (callback) =>
    ({ store, anonGet }) => {
      const map = store.selectMap();
      const coords = store.selectIdentifyCoordinates();
      const visibleLayers = store.selectVisibleLayers();
      const resolution = store.selectResolution();
      const c = fromLonLat(coords);
      const pixel = map.getPixelFromCoordinate(c);

      if (!visibleLayers.length) return callback(null, []);

      const params = {
        sr: 4326,
        tolerance: 2,
        returnGeometry: true,
        mapExtent: store.selectMapExtent(),
        imageDisplay: store.selectMapImageDisplay(),
        f: "json",
      };

      if (typeof coords[0] === "number") {
        params.geometry = coords.join(",");
        params.geometryType = "esriGeometryPoint";
      } else {
        params.geometryType = "esriGeometryPolygon";
        params.geometry = coords.join(",");
      }

      const queries = [];

      map.forEachLayerAtPixel(pixel, (layer, px) => {
        if (px) {
          visibleLayers.forEach((visibleLayer) => {
            if (visibleLayer.mapLayer === layer) {
              if (visibleLayer.identifyType === "arcgisrest") {
                const type = visibleLayer.mapLayer.getType();
                const src = visibleLayer.mapLayer.getSource();
                const root = type === "IMAGE" ? src.getUrl() : src.getUrls()[0];
                const p = Object.assign({}, params, { root: root });
                const url = formatUrl(p);
                queries.push((cb) => {
                  anonGet(url, (err, response, body) => {
                    if (err || response.statusCode !== 200) {
                      callback({ err: err, response: response });
                    } else {
                      const data = JSON.parse(body);
                      console.log(data);
                      cb(null, {
                        dataset: visibleLayer.uid,
                        err: null,
                        result: {
                          [visibleLayer.uid]: {
                            type: "FeatureCollection",
                            features: data.results.map((feat) => {
                              return {
                                type: "Feature",
                                geometry: {
                                  type: "Point",
                                  coordinates: coords,
                                },
                                properties: feat.attributes,
                              };
                            }),
                          },
                        },
                      });
                    }
                  });
                });
              }
            }
          });
        }
      });

      async.parallel(queries, (err, results) => {
        if (err) return console.log(err);
        callback(null, results);
      });
    },

  reactArcGisRestIdentShouldRegister: (state) => {
    if (state.arcGisRestIdent.shouldRegister)
      return { actionCreator: "doArcGisRestIdentRegister" };
  },
};
