import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import { AgChartOptions } from "ag-charts-enterprise";
import { getCurrencyData } from "./data";
import { cables, capitals, topology } from "./topology";
import "ag-charts-enterprise";

const currencyLayers: Record<
  string,
  {
    title: string;
    fill: string;
  }
> = {
  euro: { title: "Euro", fill: "#3F51B5" },
  dollar: { title: "Dollar", fill: "#8BC34A" },
  franc: { title: "Franc", fill: "#F44336" },
  pound: { title: "Pound", fill: "#2196F3" },
  dinar: { title: "Dinar", fill: "#9C27B0" },
  peso: { title: "Peso", fill: "#FFC107" },
  rupee: { title: "Rupee", fill: "#FF9800" },
  rial: { title: "Rial", fill: "#009688" },
};

const ChartExample = () => {
  const [options, setOptions] = useState<AgChartOptions>({
    topology,
    series: [
      {
        type: "map-shape-background",
        fillOpacity: 0,
        stroke: "#66879933",
      },
      {
        type: "map-shape",
        legendItemName: "Shapes",
        title: "Other Currency",
        data: topology.features
          .map((t: any) => ({ name: t.properties.name }))
          .filter(({ name }: { name: string }) => currencyLayers[name] == null),
        idKey: "name",
        fill: "#668799",
        fillOpacity: 0.4,
        highlightStyle: {
          item: {
            fillOpacity: 1,
          },
        },
      },
      ...Object.entries(currencyLayers).map(([currency, { title, fill }]) => ({
        type: "map-shape" as const,
        legendItemName: "Shapes",
        showInLegend: false,
        title,
        idKey: "name",
        data: getCurrencyData(currency),
        fill,
        fillOpacity: 0.4,
        highlightStyle: {
          item: {
            fillOpacity: 1,
          },
        },
      })),
      {
        type: "map-line",
        topology: cables,
        legendItemName: "Lines",
        data: cables.features.map((t: any) => {
          return { name: t.properties.name };
        }),
        idKey: "name",
        title: "Submarine Cables",
        stroke: "#546E7A",
        strokeWidth: 0.5,
      },
      {
        type: "map-marker",
        topology: capitals,
        legendItemName: "Markers",
        showInLegend: false,
        data: capitals.features
          .map((t: any) => {
            return { name: t.properties.city };
          })
          .filter(({ name }: any) => name != null),
        idKey: "name",
        title: "Capital City",
        topologyIdKey: "city",
        size: 4,
        fill: "#546E7A",
        fillOpacity: 1,
        strokeWidth: 0,
      },
      {
        type: "map-marker",
        legendItemName: "Markers",
        title: "Stock Exchange",
        data: [
          { name: "New York", lat: 40.707, long: -74.011 },
          { name: "Tokyo", lat: 35.681, long: 139.777 },
          { name: "London", lat: 51.515, long: -0.09 },
          { name: "Hong Kong", lat: 22.32, long: 114.171 },
          { name: "India", lat: 28.624, long: 77.214 },
        ],
        latitudeKey: "lat",
        longitudeKey: "long",
        labelKey: "name",
        labelName: "Name",
        label: { enabled: false },
        shape: "pin",
        size: 40,
        fill: "#EF5452",
        fillOpacity: 1,
        strokeWidth: 0,
      },
    ],
    legend: {
      enabled: true,
      item: {
        showSeriesStroke: true,
      },
    },
  });

  return <AgCharts options={options as any} />;
};

const root = createRoot(document.getElementById("root")!);
root.render(<ChartExample />);

/** DARK MODE START **/
import { AgCharts as __chartAPI } from "ag-charts-community";

let darkmode =
  (localStorage["documentation:darkmode"] ||
    String(matchMedia("(prefers-color-scheme: dark)").matches)) === "true";

const isAgThemeOrUndefined = (theme) => {
  return (
    theme == null || (typeof theme === "string" && theme.startsWith("ag-"))
  );
};

const getDarkmodeTheme = (theme = "ag-default", preset) => {
  const baseTheme =
    preset === "price-volume" ? "ag-financial" : theme.replace(/-dark$/, "");
  return darkmode ? baseTheme + "-dark" : baseTheme;
};

__chartAPI.optionsMutationFn = function update(options, preset) {
  const nextOptions = { ...options };
  const theme = options.theme;
  if (isAgThemeOrUndefined(theme)) {
    nextOptions.theme = getDarkmodeTheme(theme, preset);
  } else if (
    typeof theme === "object" &&
    isAgThemeOrUndefined(theme.baseTheme)
  ) {
    nextOptions.theme = {
      ...options.theme,
      baseTheme: getDarkmodeTheme(theme.baseTheme, preset),
    };
  }
  return nextOptions;
};

const applyDarkmode = () => {
  document.documentElement.setAttribute("data-dark-mode", darkmode);
  const charts = document.querySelectorAll("[data-ag-charts]");
  charts.forEach((element) => {
    const chart = __chartAPI.getInstance(element.parentElement);
    if (chart == null) return;
    // This is just needed to trigger the theme update
    chart.update(chart.getOptions());
  });
  return charts.length !== 0;
};

if (!applyDarkmode()) {
  /* React defers updates. Rather than try and hook into the API, just wait until the darkmode is applied. */
  const observer = new MutationObserver(() => {
    if (applyDarkmode()) {
      observer.disconnect();
    }
  });
  observer.observe(document.body, {
    attributes: true,
    childList: true,
    subtree: true,
  });
}
window.addEventListener("message", (event) => {
  if (event.data && event.data.type === "color-scheme-change") {
    darkmode = event.data.darkmode;
    applyDarkmode();
  }
});
/** DARK MODE END **/
