import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import { AgChartOptions } from "ag-charts-enterprise";
import { londonBoroughData } from "./londonBoroughData";
import { londonBoroughTopology } from "./londonBoroughTopology";
import { otherCountiesData } from "./otherCountiesData";
import { otherCountiesTopology } from "./otherCountiesTopology";
import { tubeData } from "./tubeData";
import { tubeTopology } from "./tubeTopology";
import "ag-charts-enterprise";

const sizeDomain = [0, 141537];
const strokeWidth = 1;
const maxStrokeWidth = 5;

const ChartExample = () => {
  const [options, setOptions] = useState<AgChartOptions>({
    topology: tubeTopology,
    title: {
      text: "London Tube Lines",
    },
    series: [
      {
        type: "map-shape",
        topology: otherCountiesTopology,
        data: otherCountiesData,
        topologyIdKey: "name",
        idKey: "county",
        labelKey: "county",
        fill: "#0000",
        stroke: "#6687990C",
        strokeWidth: 1,
        label: {
          fontSize: 10,
          minimumFontSize: 8,
          color: "#66879933",
          formatter: ({ value }) => {
            return value === "Chiltern" ||
              value === "Three Rivers" ||
              value === "Epping Forest"
              ? value
              : "";
          },
        },
      },
      {
        type: "map-shape",
        topology: londonBoroughTopology,
        data: londonBoroughData,
        idKey: "name",
        topologyIdKey: "name",
        labelKey: "name",
        fill: "#66879933",
        stroke: "#6687990C",
        strokeWidth: 1,
        label: {
          fontSize: 10,
          minimumFontSize: 8,
        },
      },
      {
        type: "map-line",
        title: "Bakerloo",
        data: tubeData["Bakerloo"],
        idKey: "section",
        sizeKey: "passengers",
        stroke: "#B26300",
        sizeDomain,
        strokeWidth,
        maxStrokeWidth,
      },
      {
        type: "map-line",
        title: "Hammersmith & City",
        data: tubeData["Hammersmith & City"],
        idKey: "section",
        sizeKey: "passengers",
        stroke: "#F589A6",
        sizeDomain,
        strokeWidth,
        maxStrokeWidth,
      },
      {
        type: "map-line",
        title: "Jubilee",
        data: tubeData["Jubilee"],
        idKey: "section",
        sizeKey: "passengers",
        stroke: "#838D93",
        sizeDomain,
        strokeWidth,
        maxStrokeWidth,
      },
      {
        type: "map-line",
        title: "Victoria",
        data: tubeData["Victoria"],
        idKey: "section",
        sizeKey: "passengers",
        stroke: "#039BE5",
        sizeDomain,
        strokeWidth,
        maxStrokeWidth,
      },
      {
        type: "map-line",
        title: "District",
        data: tubeData["District"],
        idKey: "section",
        sizeKey: "passengers",
        stroke: "#007D32",
        sizeDomain,
        strokeWidth,
        maxStrokeWidth,
      },
      {
        type: "map-line",
        title: "Metropolitan",
        data: tubeData["Metropolitan"],
        idKey: "section",
        sizeKey: "passengers",
        stroke: "#9B0058",
        sizeDomain,
        strokeWidth,
        maxStrokeWidth,
      },
      {
        type: "map-line",
        title: "Northern",
        data: tubeData["Northern"],
        idKey: "section",
        sizeKey: "passengers",
        stroke: "black",
        sizeDomain,
        strokeWidth,
        maxStrokeWidth,
      },
      {
        type: "map-line",
        title: "Piccadilly",
        data: tubeData["Piccadilly"],
        idKey: "section",
        sizeKey: "passengers",
        stroke: "#0019A8",
        sizeDomain,
        strokeWidth,
        maxStrokeWidth,
      },
      {
        type: "map-line",
        title: "Waterloo & City",
        data: tubeData["Waterloo & City"],
        idKey: "section",
        sizeKey: "passengers",
        stroke: "#76D0BD",
        sizeDomain,
        strokeWidth,
        maxStrokeWidth,
      },
      {
        type: "map-line",
        title: "Circle",
        data: tubeData["Circle"],
        idKey: "section",
        sizeKey: "passengers",
        stroke: "#FFC80A",
        sizeDomain,
        strokeWidth,
        maxStrokeWidth,
      },
      {
        type: "map-line",
        title: "Central",
        data: tubeData["Central"],
        idKey: "section",
        sizeKey: "passengers",
        stroke: "#DC241F",
        sizeDomain,
        strokeWidth,
        maxStrokeWidth,
      },
    ],
  });

  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 **/
