import React, { useState, useRef, Fragment } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
  AgAreaSeriesOptions,
  AgChartLegendPosition,
  AgChartOptions,
  AgChartTheme,
  AgChartsInstance,
} from "ag-charts-community";
import { getData } from "./data";
import clone from "clone";

function buildSeries(name: string): AgAreaSeriesOptions {
  return {
    type: "area",
    xKey: "year",
    yKey: name.toLowerCase(),
    yName: name,
    fillOpacity: 0.5,
  };
}
const series = [
  buildSeries("IE"),
  buildSeries("Chrome"),
  buildSeries("Firefox"),
  buildSeries("Safari"),
];
const positions: AgChartLegendPosition[] = ["left", "top", "right", "bottom"];
const legend = {
  position: positions[1],
};

const ChartExample = () => {
  const chartRef = useRef<AgChartsInstance>(null);
  const [options, setOptions] = useState<AgChartOptions>({
    title: {
      text: "Browser Usage Statistics",
    },
    subtitle: {
      text: "2009-2019",
    },
    data: getData(),
    series,
    legend,
  });

  const reverseSeries = () => {
    const series = chartRef.current!.getOptions()
      .series as AgAreaSeriesOptions[];
    series!.reverse();
    chartRef.current!.updateDelta({ series });
  };

  const swapTitles = () => {
    const { title, subtitle } = chartRef.current!.getOptions();
    chartRef.current!.updateDelta({ title: subtitle, subtitle: title });
  };

  const rotateLegend = () => {
    const position = chartRef.current!.getOptions().legend!.position;
    const currentIdx = positions.indexOf(position ?? "top");
    const newPosition = positions[(currentIdx + 1) % positions.length];
    chartRef.current!.updateDelta({ legend: { position: newPosition } });
  };

  const changeTheme = () => {
    const theme = chartRef.current!.getOptions()?.theme as AgChartTheme;
    const markersEnabled =
      theme?.overrides?.area?.series?.marker?.enabled ?? false;
    chartRef.current!.updateDelta({
      theme: {
        overrides: {
          area: { series: { marker: { enabled: !markersEnabled } } },
        },
      },
    });
  };

  return (
    <Fragment>
      <div className="toolbar">
        <button onClick={reverseSeries}>Reverse Series</button>
        <button onClick={swapTitles}>Swap Titles</button>
        <button onClick={rotateLegend}>Rotate Legend</button>
        <button onClick={changeTheme}>Change Theme</button>
      </div>
      <AgCharts ref={chartRef} options={options} />
    </Fragment>
  );
};

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