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

const myTheme: AgChartTheme = {
  palette: {
    fills: ["#006f9b", "#ff7faa", "#00994d", "#ff8833", "#00a0dd"],
    strokes: ["#003f58", "#934962", "#004a25", "#914d1d", "#006288"],
  },
  params: {
    foregroundColor: "#262a33",
    backgroundColor: "#fff1e5",
    accentColor: "#0d7680",
    chromeBackgroundColor: "#fff7ef",
    chromeTextColor: "#262a33",
    fontFamily: "Georgia, serif",
    fontSize: 14,
  },
  overrides: {
    common: {
      title: {
        fontSize: 24,
      },
      padding: {
        left: 70,
        right: 70,
      },
      axes: {
        category: {
          line: {
            width: 4,
          },
        },
        number: {
          line: {
            width: 2,
          },
        },
      },
    },
    line: {
      series: {
        marker: {
          shape: "circle",
        },
      },
    },
    bar: {
      series: {
        label: {
          enabled: true,
          color: "white",
        },
      },
    },
    pie: {
      padding: {
        top: 40,
        bottom: 40,
      },
      legend: {
        position: "left",
      },
      series: {
        calloutLabel: {
          enabled: true,
        },
        calloutLine: {
          colors: ["#881008"],
        },
      },
    },
  },
};

const ChartExample = () => {
  const [options, setOptions] = useState<AgChartOptions>({
    theme: myTheme,

    title: {
      text: "Multi-Type Chart Theme",
    },
    data: getData(),
    series: [
      {
        type: "bar",
        xKey: "label",
        yKey: "v1",
        stacked: true,
        yName: "Reliability",
      },
      {
        type: "bar",
        xKey: "label",
        yKey: "v2",
        stacked: true,
        yName: "Ease of use",
      },
      {
        type: "bar",
        xKey: "label",
        yKey: "v3",
        stacked: true,
        yName: "Performance",
      },
      {
        type: "line",
        xKey: "label",
        yKey: "v4",
        yName: "Price",
      },
    ],
  });

  const applyOptions = (type: "bar" | "pie") => {
    const nextOptions = clone(options);

    if (type === "pie") {
      nextOptions.series = [
        {
          type: "pie",
          angleKey: "v4",
          calloutLabelKey: "label",
        },
      ];
    } else {
      const names = ["Reliability", "Ease of use", "Performance", "Price"];
      nextOptions.series = [
        ...names.map((yName, idx) => ({
          type: idx <= 2 ? ("bar" as const) : ("line" as const),
          xKey: "label",
          yKey: `v${idx + 1}`,
          stacked: idx <= 2,
          yName,
        })),
      ];
    }

    setOptions(nextOptions);
  };

  return (
    <Fragment>
      <div className="toolbar">
        <button onClick={() => applyOptions("bar")}>
          Bar &amp; Line Chart
        </button>
        <button onClick={() => applyOptions("pie")}>Pie Chart</button>
      </div>
      <AgCharts 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 **/
