import React from 'react';
import { CompositeLayer, HeatmapLayer } from 'deck.gl';
import * as d3 from 'd3';
import { getDistance } from '../../utlis';
import { Edge, LayerProps } from '../../mapvis.types';
import { Node } from '@graphpolaris/shared/lib/data-access';

export class HeatLayer extends CompositeLayer<LayerProps> {
  static type = 'Heatmap';

  updateState({ changeFlags }: { changeFlags: any }) {
    return changeFlags.propsOrDataChanged || changeFlags.somethingChanged;
  }

  createSegments(edges: Edge[]) {
    // Generates a path between source and target nodes
    return edges.map((edge: Edge, index) => {
      const length = getDistance(edge.path[0], edge.path[1]);
      const nSegments = length * this.props.config.nSegments;

      let xscale = d3
        .scaleLinear()
        .domain([0, nSegments + 1])
        .range([edge.path[0][0], edge.path[1][0]]);

      let yscale = d3
        .scaleLinear()
        .domain([0, nSegments + 1])
        .range([edge.path[0][1], edge.path[1][1]]);

      let source = edge.path[0];
      let target = null;
      let local = [source];

      for (let j = 1; j <= nSegments; j++) {
        target = [xscale(j), yscale(j)];
        local.push(target);
        source = target;
      }

      local.push(edge.path.slice(-1)[0]);
      return { ...edge, path: local };
    });
  }

  renderLayers() {
    const { graph, config, getNodeLocation, setLayerIds, metaData } = this.props;

    const layers: any[] = [];
    const layerIds: string[] = [];

    metaData.nodes.labels.forEach((label: string) => {
      const layerId = `${label}-nodes-iconlayer`;
      layerIds.push(layerId);

      layers.push(
        new HeatmapLayer({
          id: `${label}-nodes-iconlayer`,
          data: graph.nodes.filter((node: Node) => node.label === label),
          visible: !config[label]?.hidden,
          getPosition: (d: any) => getNodeLocation(d.id),
          getWeight: (d) => 1,
          aggregation: 'SUM',
        }),
      );
    });

    setLayerIds(layerIds);

    return layers;

    // const layers = [];

    // if (config.type === 'location') {
    //   layers.push(
    //     new HeatmapLayer(
    //       this.getSubLayerProps({
    //         data:
    //           config.location === 'source'
    //             ? graph.getEdges().map((edge: Edge) => graph.getNode(edge.from))
    //             : graph.getEdges().map((edge: Edge) => graph.getNode(edge.to)),
    //         getPosition: (d: any) => [d.attributes.long, d.attributes.lat],
    //         aggregation: 'SUM',
    //       }),
    //     ),
    //   );
    // } else if (config.type === 'distance') {
    //   layers.push(
    //     new HeatmapLayer(
    //       this.getSubLayerProps({
    //         data: graph.getEdges().map((edge: Edge) => {
    //           const from = graph.getNode(edge.from);
    //           const from_coords: [number, number] = [from.attributes.long, from.attributes.lat];
    //           const to = graph.getNode(edge.to);
    //           const to_coords: [number, number] = [to.attributes.long, to.attributes.lat];
    //           const dist = getDistance(from_coords, to_coords);
    //           const node = config.location === 'source' ? from : to;
    //           return { ...node, distance: dist };
    //         }),
    //         threshold: 0.5,
    //         getPosition: (d: any) => [d.attributes.long, d.attributes.lat],
    //         getWeight: (d: any) => d.distance,
    //         aggregation: 'MEAN',
    //       }),
    //     ),
    //   );
    // } else if (config.type === 'attribute') {
    //   console.log('attribute');
    //   layers.push(
    //     new HeatmapLayer(
    //       this.getSubLayerProps({
    //         data: graph.getEdges().map((edge: Edge) => graph.getNode(edge.from)),
    //         getPosition: (d: any) => [d.attributes.long, d.attributes.lat],
    //         getWeight: (d: any) => {
    //           console.log(d, d.attributes[config.attribute]);
    //           return 1;
    //         },
    //         aggregation: 'SUM',
    //       }),
    //     ),
    //   );
    // } else if (config.type === 'path') {
    //   layers.push(
    //     new HeatmapLayer(
    //       this.getSubLayerProps({
    //         data: this.createSegments(
    //           graph.getEdges().map((edge: Edge) => {
    //             return {
    //               ...edge,
    //               path: [this.props.graph.getNodeLocation(edge.from), this.props.graph.getNodeLocation(edge.to)],
    //             };
    //           }),
    //         ).flatMap((edge) => edge.path),
    //         getPosition: (d: any) => d,
    //         aggregation: 'SUM',
    //       }),
    //     ),
    //   );
    // }

    // return [...layers];
  }
}

HeatLayer.layerName = 'Heatmap';