import React, { useCallback, useState } from "react";

import { BarChartRounded, ShowChartRounded, TableRowsRounded } from "@mui/icons-material";
import { ToggleButton, ToggleButtonGroup, Tooltip } from "@mui/material";

import { useDashboardFilter } from "../contexts/DashboardFilterContext";
import { useI18n } from "../contexts/I18nContext";

import BarChart from "./charts/BarChart";
import LineChart from "./charts/LineChart";
import AreaChartIcon from "./Icons/AreaChartIcon";
import StatsDataTable from "./StatsDataTable";

export type ChartType = "line" | "area" | "bar";
export type ChartsWithTableType = ChartType | "table";

export interface DataItem {
  date: string;
  [key: string]: string | number | boolean | Date;
}

export interface ChartProps {
  data: DataItem[];
  charts: ChartType[];
  dataTable?: boolean;
  dataKeyX: string;
  dataKeyY?: string;
  csvFileName?: string;
}

const chartData = {
  line: {
    Icon: ShowChartRounded,
    name: "Line Chart",
  },
  area: {
    Icon: AreaChartIcon,
    name: "Area Chart",
  },
  bar: {
    Icon: BarChartRounded,
    name: "Bar Chart",
  },
  table: {
    Icon: TableRowsRounded,
    name: "Table",
  },
};

export default function Chart({
  data,
  charts,
  dataTable = true,
  dataKeyX,
  dataKeyY,
  csvFileName,
}: ChartProps) {
  const { t } = useI18n();
  const { filter } = useDashboardFilter();
  const [selectedChart, setSelectedChart] = useState<ChartsWithTableType>(charts[0]);

  const chartsWithTable: ChartsWithTableType[] = dataTable ? [...charts, "table"] : charts;

  const handleSelectedChartChange = useCallback(
    (_: React.MouseEvent<HTMLElement>, newChart: string) => {
      if (newChart !== null) {
        setSelectedChart(newChart as ChartsWithTableType);
      }
    },
    [],
  );

  return (
    <>
      {chartsWithTable.length > 1 && (
        <ToggleButtonGroup
          exclusive
          sx={{ position: "absolute", right: 16, top: 16 }}
          unselectable="off"
          value={selectedChart}
          onChange={handleSelectedChartChange}
        >
          {chartsWithTable.map((chart) => {
            const { Icon, name } = chartData[chart];
            return (
              <Tooltip key={chart} title={t(name)}>
                <ToggleButton size="small" value={chart}>
                  <Icon fontSize="small" />
                </ToggleButton>
              </Tooltip>
            );
          })}
        </ToggleButtonGroup>
      )}
      {selectedChart === "bar" && (
        <BarChart
          dataKeyX={dataKeyX}
          dataKeyY={dataKeyY}
          dataset={data.map(({ date, ...props }) => ({ ...props, date: new Date(date) }))}
          granularity={filter.granularity}
        />
      )}
      {(selectedChart === "line" || selectedChart === "area") && (
        <LineChart
          area={selectedChart === "area"}
          dataKeyX={dataKeyX}
          dataKeyY={dataKeyY}
          dataset={data.map(({ date, ...props }) => ({ ...props, date: new Date(date) }))}
          granularity={filter.granularity}
        />
      )}
      {selectedChart === "table" && (
        <StatsDataTable csvFileName={csvFileName} data={data} dateKey={dataKeyX} />
      )}
    </>
  );
}
