import * as am5 from "@amcharts/amcharts5";
import * as am5map from "@amcharts/amcharts5/map";
import * as am5geodata_australiaLow from "@amcharts/amcharts5-geodata/australiaLow";
import * as am5geodata_worldLow from "@amcharts/amcharts5-geodata/worldLow";

import am5themes_Animated from "@amcharts/amcharts5/themes/Animated";

export interface City {
    title: any;
    city: string;
    state: any;
    lat: number;
    lng: number;
}

export function createMapChart(containerId: string, cities: City[], routes: { start: [number, number], end: [number, number] }[]): am5.Root {
    // Create root element
    let root = am5.Root.new("chartdiv");

    // Set themes
    // https://www.amcharts.com/docs/v5/concepts/themes/
    root.setThemes([
        am5themes_Animated.new(root)
    ]);

    // Create the map chart
    // https://www.amcharts.com/docs/v5/charts/map-chart/
    let chart = root.container.children.push(am5map.MapChart.new(root, {
        panX: "rotateX",
        panY: "translateY",
        projection: am5map.geoMercator(),
        homeGeoPoint: { latitude: 25.2744, longitude: 133.7751 },
        homeZoomLevel: 1 // Adjust the zoom level here
    }));

    let cont = chart.children.push(am5.Container.new(root, {
        layout: root.horizontalLayout,
        x: 20,
        y: 40
    }));

    // Add labels and controls
    // cont.children.push(am5.Label.new(root, {
    //     centerY: am5.p50,
    //     text: "Map"
    // }));

    // let switchButton = cont.children.push(am5.Button.new(root, {
    //     themeTags: ["switch"],
    //     centerY: am5.p50,
    //     icon: am5.Circle.new(root, {
    //         themeTags: ["icon"]
    //     })
    // }));

    // switchButton.on("active", function () {
    //     if (!switchButton.get("active")) {
    //         chart.set("projection", am5map.geoMercator());
    //         chart.set("panY", "translateY");
    //         chart.set("rotationY", 0);
    //         backgroundSeries.mapPolygons.template.set("fillOpacity", 0);
    //     } else {
    //         chart.set("projection", am5map.geoOrthographic());
    //         chart.set("panY", "rotateY")

    //         backgroundSeries.mapPolygons.template.set("fillOpacity", 0.1);
    //     }
    // });

    // cont.children.push(
    //     am5.Label.new(root, {
    //         centerY: am5.p50,
    //         text: "Globe"
    //     })
    // );

    // Create series for background fill
    // https://www.amcharts.com/docs/v5/charts/map-chart/map-polygon-series/#Background_polygon
    let backgroundSeries = chart.series.push(am5map.MapPolygonSeries.new(root, {}));
    backgroundSeries.mapPolygons.template.setAll({
        fill: root.interfaceColors.get("alternativeBackground"),
        fillOpacity: 0,
        strokeOpacity: 0
    });

    // Add background polygon
    // https://www.amcharts.com/docs/v5/charts/map-chart/map-polygon-series/#Background_polygon
    backgroundSeries.data.push({
        geometry: am5map.getGeoRectangle(90, 180, -90, -180)
    });

    // Create main polygon series for countries
    // https://www.amcharts.com/docs/v5/charts/map-chart/map-polygon-series/
    let polygonSeries = chart.series.push(am5map.MapPolygonSeries.new(root, {
        geoJSON: am5geodata_worldLow.default
    }));

    // Create line series for trajectory lines
    // https://www.amcharts.com/docs/v5/charts/map-chart/map-line-series/
    let lineSeries = chart.series.push(am5map.MapLineSeries.new(root, {}));
    lineSeries.mapLines.template.setAll({
        stroke: root.interfaceColors.get("alternativeBackground"),
        strokeOpacity: 0.3
    });

    // Create point series for markers
    // https://www.amcharts.com/docs/v5/charts/map-chart/map-point-series/
    let pointSeries = chart.series.push(am5map.MapPointSeries.new(root, {}));

    pointSeries.bullets.push(function () {
        let circle = am5.Circle.new(root, {
            radius: 7,
            tooltipText: "{title}",
            cursorOverStyle: "pointer",
            tooltipY: 0,
            fill: am5.color(0xffba00),
            stroke: root.interfaceColors.get("background"),
            strokeWidth: 2,
            // draggable: true
        });

        // circle.events.on("dragged", function (event) {
        //     let dataItem = event.target.dataItem;
        //     let projection = chart.get("projection");
        //     let geoPoint: any = chart.invert({ x: circle.x(), y: circle.y() });

        //     dataItem.setAll({
        //         longitude: geoPoint.longitude,
        //         latitude: geoPoint.latitude
        //     });
        // });

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

    let paris = addCity({ title: 'teta', longitude: 151.209295, latitude: -33.868820, }, "Paris");
    let toronto = addCity({ title: 'tetb', latitude: -37.813629, longitude: 144.963058 }, "Toronto");
    // let la = addCity({ latitude: 34.3, longitude: -118.15 }, "Los Angeles");
    // let havana = addCity({ latitude: 23, longitude: -82 }, "Havana");

    let lineDataItem = lineSeries.pushDataItem({
        pointsToConnect: [paris, toronto]
    });

    let planeSeries = chart.series.push(am5map.MapPointSeries.new(root, {}));

    let plane = am5.Graphics.new(root, {
        svgPath:
            "M17 8h3l3 4.056V18h-2.035a3.5 3.5 0 0 1-6.93 0h-5.07a3.5 3.5 0 0 1-6.93 0H1V6a1 1 0 0 1 1-1h14a1 1 0 0 1 1 1v2zm0 2v3h4v-.285L18.992 10H17z",
        scale: 0.5, // Adjust the scale as needed
        centerY: am5.p50,
        centerX: am5.p50,
        fill: am5.color(0x007BFF) // Color of the truck
    });

    planeSeries.bullets.push(function () {
        let container = am5.Container.new(root, {});
        container.children.push(plane);
        return am5.Bullet.new(root, { sprite: container });
    });


    let planeDataItem = planeSeries.pushDataItem({
        lineDataItem: lineDataItem,
        positionOnLine: 0,
        autoRotate: true
    });
    planeDataItem.dataContext = {};

    planeDataItem.animate({
        key: "positionOnLine",
        to: 1,
        duration: 10000,
        loops: Infinity,
        easing: am5.ease.yoyo(am5.ease.linear)
    });

    planeDataItem.on("positionOnLine", (value) => {
        if (planeDataItem.dataContext.prevPosition < value) {
            plane.set("rotation", 0);
        }

        if (planeDataItem.dataContext.prevPosition > value) {
            plane.set("rotation", -180);
        }
        planeDataItem.dataContext.prevPosition = value;
    });

    function addCity(coords, title) {
        return pointSeries.pushDataItem(coords);
    }

    // Make stuff animate on load
    chart.appear(1000, 100);

    return root;
}
