import React from "react";

import { styled, useTheme } from "@mui/material/styles";
import { BarChart as MuiBarChart } from "@mui/x-charts/BarChart";
import { ChartsLegendProps } from "@mui/x-charts/ChartsLegend";
import { DatasetType, MakeOptional, SeriesId } from "@mui/x-charts/internals";
import { BarSeriesType } from "@mui/x-charts/models/seriesType";

import { Granularity } from "../../types/dashboard";
import { getDateValueFormatter } from "../../util/timeline";

declare module "@mui/material/styles" {
  interface Palette {
    graphColorPrimary?: { main: string };
  }
}

const StyledBarChart = styled(MuiBarChart, {
  name: "BananasChart",
  slot: "Chart",
})(({ theme }) =>
  theme.unstable_sx({
    ".MuiChartsAxis-line, .MuiChartsAxis-tick": {
      opacity: 0,
      stroke: theme.palette.divider,
    },
    ".MuiBarLabel-root": {
      fill: theme.palette.primary.contrastText,
    },
  }),
);

export interface BarChartProps {
  dataset: DatasetType;
  series?: MakeOptional<BarSeriesType, "type">[];
  dataKeyX: string;
  dataKeyY?: string;
  height?: number;
  granularity?: Granularity;
  yAxisOptions?: object;
  legendProps?: ChartsLegendProps;
  highlightedSerie?: SeriesId;
}

export const BarChart: React.FC<BarChartProps> = ({
  dataset,
  series,
  dataKeyX,
  dataKeyY,
  height = 300,
  granularity = "day",
  yAxisOptions,
  legendProps,
  highlightedSerie,
}) => {
  const theme = useTheme();

  return (
    <StyledBarChart
      // TODO: Show count on bars when bar is "wide" enough ..
      //       barLabel="value"
      dataset={dataset}
      grid={{ horizontal: true }}
      height={height}
      highlightedItem={
        highlightedSerie
          ? {
              seriesId: highlightedSerie,
            }
          : null
      }
      series={
        series ?? [
          {
            dataKey: dataKeyY,
            color: theme.palette.graphColorPrimary?.main ?? theme.palette.primary.main,
          },
        ]
      }
      slotProps={{
        legend: {
          direction: "row",
          position: { vertical: "top", horizontal: "middle" },
          padding: 0,
          itemMarkWidth: 10,
          itemMarkHeight: 10,
          itemGap: 15,
          labelStyle: {
            fontSize: "0.8rem",
          },
          ...legendProps,
        },
      }}
      xAxis={[
        {
          dataKey: dataKeyX,
          scaleType: "band",
          valueFormatter: getDateValueFormatter(granularity),
        },
      ]}
      yAxis={[
        {
          min: 0,
          tickNumber: 4,
          tickMinStep: 1,
          ...yAxisOptions,
        },
      ]}
    />
  );
};

export default BarChart;
