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

import { useTheme } from "@mui/material/styles";
import { SeriesId } from "@mui/x-charts/internals";
import { LineSeriesType } from "@mui/x-charts/models/seriesType";

import LineChart from "../../../components/charts/LineChart";
import WidgetCard from "../../../components/WidgetCard";
import { useDashboardFilter } from "../../../contexts/DashboardFilterContext";
import { useI18n } from "../../../contexts/I18nContext";
import { ContribComponent } from "../../../types";
import { granularityLabel } from "../../../types/dashboard";
import { SubscriptionStateCountItem } from "../types/stats";

const calculateStep = (value: number, steps: number = 5) => {
  const exponent = Math.floor(Math.log10(value / steps));
  const base = 10 ** exponent;
  return Math.ceil(value / steps / base) * base;
};

const ceilToStep = (value: number, step: number) => value + (step - (value % step));

const RunningSubscriptionCountWidget: ContribComponent<SubscriptionStateCountItem[]> = ({
  data,
  sx,
}) => {
  const { filter } = useDashboardFilter();
  const { t } = useI18n();
  const theme = useTheme();

  const [highlighted, setHighlighted] = useState<SeriesId>("none");

  const [series, yMax, yTickStep] = useMemo(() => {
    const pendingMax = Math.max(...data.map(({ pending }) => pending));
    const runningMax = Math.max(...data.map(({ running }) => running));

    const max =
      highlighted === "none"
        ? Math.max(pendingMax, runningMax)
        : highlighted === "pending"
          ? pendingMax
          : runningMax;

    const yTickStep = Math.max(calculateStep(max, 5), 1);
    const yMax = ceilToStep(max, yTickStep);

    const showPending = (["none", "pending"] as SeriesId[]).includes(highlighted);
    const showRunning = (["none", "running"] as SeriesId[]).includes(highlighted);

    const series = [
      {
        id: "pending",
        label: "Pending",
        data: showPending ? undefined : [],
        dataKey: showPending ? "pending" : undefined,
        showMark: data.length <= 1,
        curve: "monotoneX",
        color: theme.palette.info.light,
      },
      {
        id: "running",
        label: "Running",
        data: showRunning ? undefined : [],
        dataKey: showRunning ? "running" : undefined,
        showMark: data.length <= 1,
        curve: "monotoneX",
        color: theme.palette.success.main,
      },
    ] as LineSeriesType[];

    return [series, yMax, yTickStep];
  }, [data, highlighted]);

  return (
    <WidgetCard
      gridColumn={{ md: "span 6", sm: "span 1" }}
      gridRow="span 2"
      sx={sx}
      title={t(`${granularityLabel(filter.granularity)} Subscriptions`)}
    >
      <LineChart
        dataKeyX="timestamp"
        dataset={data.map(({ timestamp, ...stats }) => ({
          timestamp: new Date(timestamp),
          ...stats,
        }))}
        granularity={filter.granularity}
        legendProps={{
          onItemClick: (_, context) =>
            setHighlighted(highlighted !== context.seriesId ? context.seriesId : "none"),
        }}
        series={series}
        yAxisOptions={{
          max: yMax,
          tickMinStep: yTickStep,
        }}
      />
    </WidgetCard>
  );
};

export default RunningSubscriptionCountWidget;
