import React, { Component } from "react";
import * as am5 from "@amcharts/amcharts5";
import * as am5map from "@amcharts/amcharts5/map";
import am5geodata_gunwi from "../map";
import am5themes_Animated from "@amcharts/amcharts5/themes/Animated";
import am4geodata_continentsLow from "@amcharts/amcharts4-geodata/continentsLow";

class Map extends Component {
  componentDidMount() {
    const props = this.props;
    let root = am5.Root.new("Map");
    root.setThemes([am5themes_Animated.new(root)]);

    // remove logo
    root._logo.dispose();

    let chart = root.container.children.push(
      am5map.MapChart.new(root, {
        panX: "rotateX",
        // projection: am5map.geoAlbersUsa(),
      })
    );

    // Create polygon series
    let polygonSeries = chart.series.push(
      am5map.MapPolygonSeries.new(root, {
        geoJSON: am5geodata_gunwi,
      })
    );

    polygonSeries.mapPolygons.template.setAll({
      tooltipText: "{name}",
    });

    polygonSeries.mapPolygons.template.states.create("hover", {
      fill: am5.color(0x297373),
    });

    let zoomOut = root.tooltipContainer.children.push(
      am5.Button.new(root, {
        x: am5.p100,
        y: 0,
        centerX: am5.p100,
        centerY: 0,
        paddingTop: 18,
        paddingBottom: 18,
        paddingLeft: 12,
        paddingRight: 12,
        dx: -20,
        dy: 20,
        themeTags: ["zoom"],
        icon: am5.Graphics.new(root, {
          themeTags: ["button", "icon"],
          strokeOpacity: 0.7,
          draw: function (display) {
            display.moveTo(0, 0);
            display.lineTo(12, 0);
          },
        }),
      })
    );

    zoomOut.get("background").setAll({
      cornerRadiusBL: 40,
      cornerRadiusBR: 40,
      cornerRadiusTL: 40,
      cornerRadiusTR: 40,
    });
    zoomOut.events.on("click", function () {
      if (currentSeries) {
        currentSeries.hide();
      }
      chart.goHome();
      zoomOut.hide();
      currentSeries = regionalSeries.KR.series;
      currentSeries.show();
    });
    zoomOut.hide();

    // =================================
    // Set up point series
    // =================================

    // Load senior data
    am5.net
      .load(
        "https://gist.githubusercontent.com/jlchoi1932/c3673a65fd00efa9192b3aac5bc02a1a/raw/e7bf0bc2320d0baa2f8274f94084a3dd2b098c91/_GunwiRegion.json"
      )
      .then(function (result) {
        let seniors = am5.JSONParser.parse(result.response);
        setupseniors(seniors); 
      });

    let regionalSeries = {};
    let currentSeries;

    // Parses data and creats map point series for domestic and state-level
    function setupseniors(data) {
      console.log(data);

      // Init country-level series
      regionalSeries.KR = {
        markerData: [],
        series: createSeries("seniors"),
      };

      // Set current series
      currentSeries = regionalSeries.KR.series;

      // Process data
      am5.array.each(data.query_results, function (senior) {
        // Get senior data
        senior = {
          state: senior.MAIL_ST_PROV_C,
          long: am5.type.toNumber(senior.LNGTD_I),
          lat: am5.type.toNumber(senior.LATTD_I),
          location: senior.co_loc_n,
          city: senior.mail_city_n,
          count: am5.type.toNumber(senior.count),
        };

        // Process state-level data
        if (regionalSeries[senior.state] == undefined) {
          let statePolygon = getPolygon("KR-" + senior.state);
          if (statePolygon) {
            let centroid = statePolygon.visualCentroid();

            // Add state data
            regionalSeries[senior.state] = {
              target: senior.state,
              type: "state",
              name: statePolygon.dataItem.dataContext.name,
              count: senior.count,
              seniors: senior.count,
              state: senior.state,
              markerData: [],
              geometry: {
                type: "Point",
                coordinates: [centroid.longitude, centroid.latitude],
              },
            };
            regionalSeries.KR.markerData.push(regionalSeries[senior.state]);
          } else {
            // State not found
            return;
          }
        } else {
          regionalSeries[senior.state].seniors++;
          regionalSeries[senior.state].count += senior.count;
        }

        // Process city-level data
        // if (regionalSeries[senior.city] == undefined) {
        //   regionalSeries[senior.city] = {
        //     target: senior.city,
        //     type: "city",
        //     name: senior.city,
        //     count: senior.count,
        //     seniors: 1,
        //     state: senior.state,
        //     markerData: [],
        //     geometry: {
        //       type: "Point",
        //       coordinates: [senior.long, senior.lat],
        //     },
        //   };
        //   regionalSeries[senior.state].markerData.push(
        //     regionalSeries[senior.city]
        //   );
        // } else {
        //   regionalSeries[senior.city].seniors++;
        //   regionalSeries[senior.city].count += senior.count;
        // }

        // // Process individual senior
        // regionalSeries[senior.city].markerData.push({
        //   name: senior.location,
        //   count: senior.count,
        //   seniors: 1,
        //   state: senior.state,
        //   geometry: {
        //     type: "Point",
        //     coordinates: [senior.long, senior.lat],
        //   },
        // });
      });
      console.log(regionalSeries.KR.markerData);
      regionalSeries.KR.series.data.setAll(regionalSeries.KR.markerData);
    }

    // Finds polygon in series by its id
    function getPolygon(id) {
      let found;
      polygonSeries.mapPolygons.each(function (polygon) {
        if (polygon.dataItem.get("id") == id) {
          found = polygon;
        }
      });
      return found;
    }

    // Creates series with heat rules
    function createSeries(heatfield) {
      // Create point series
      let pointSeries = chart.series.push(
        am5map.MapPointSeries.new(root, {
          valueField: heatfield,
          calculateAggregates: true,
        })
      );

      // Add senior bullet
      let circleTemplate = am5.Template.new(root);
      pointSeries.bullets.push(() => {
        let container = am5.Container.new(root, {});

        let circle = container.children.push(
          am5.Circle.new(
            root,
            {
              radius: 12,
              fill: am5.color("#f1de04"),
              fillOpacity: 0.7,
              cursorOverStyle: "pointer",
              tooltipText: "{name}:\n[bold]{seniors} seniors[/]",
            },
            circleTemplate
          )
        );

        let label = container.children.push(
          am5.Label.new(root, {
            text: "{seniors}",
            fill: am5.color(0xffffff),
            populateText: true,
            centerX: am5.p50,
            centerY: am5.p50,
            textAlign: "center",
          })
        );

        // Set up drill-down
        circle.events.on("click", (ev) => {
          // Determine what we've clicked on
          let data = ev.target.dataItem.dataContext;
          console.log({ data });

          // No id? Individual senior - nothing to drill down to further
          if (!data.target) {
            return;
          }

          if (data.type === "state") {
            props.setCityName(data.name);
          }

          // Create actual series if it hasn't been yet created
          if (!regionalSeries[data.target].series) {
            regionalSeries[data.target].series = createSeries("count");
            regionalSeries[data.target].series.data.setAll(data.markerData);
          }

          // Hide current series
          // if (currentSeries) {
          //   currentSeries.hide();
          // }

          // Control zoom
          // if (data.type == "state") {
          //   let statePolygon = getPolygon("KR-" + data.state);
          //   polygonSeries.zoomToDataItem(statePolygon.dataItem);
          // } else if (data.type == "city") {
          //   chart.zoomToGeoPoint(
          //     {
          //       latitude: data.geometry.coordinates[1],
          //       longitude: data.geometry.coordinates[0],
          //     },
          //     64,
          //     true
          //   );
          // }
          // zoomOut.show();

          // Show new targert series
          currentSeries = regionalSeries[data.target].series;
          currentSeries.show();
        });

        return am5.Bullet.new(root, {
          sprite: container,
        });
      });

      // Add heat rule for circles
      pointSeries.set("heatRules", [
        {
          target: circleTemplate,
          dataField: "value",
          min: 10,
          max: 30,
          key: "radius",
        },
      ]);

      // Set up drill-down
      // TODO

      return pointSeries;
    }

    this.root = root;
  }

  componentWillUnmount() {
    if (this.root) {
      this.root.dispose();
    }
  }

  render() {
    return (
      <div
        className="flex80"
        id="Map"
        style={{ width: "100%", height: "42vh", marginBottom: "1rem" }}
      ></div>
    );
  }
}

export default Map;
