import { useMemo } from 'react';

import TreemapChart from '@composed-components/charts/TreemapChart';
import { useChartColors } from '@composed-components/peopleExperience/hooks/useChartColors';
import CardContainer from '@design-system/CardContainer';
import { Stack, useTheme } from '@mui/material';
import { getContrastTextColor } from '@utils/colors';
import { Chart, LinearScale, Tooltip } from 'chart.js';
import { TreemapController, TreemapElement } from 'chartjs-chart-treemap';
import { truncate } from 'lodash';

import { type TextChartProps } from './types';

Chart.register(TreemapController, TreemapElement, LinearScale, Tooltip);

const TextChart = ({
  data,
  onItemClick,
  footer,
  slotProps,
}: TextChartProps) => {
  const { getColor, getContrastColors, fallbackColor } = useChartColors();
  const theme = useTheme();

  const memoizedData = useMemo(() => {
    const colors = data.map((_, index) => getColor(index));

    return {
      tree: data.map(item => ({
        label: item.label,
        value: item.value,
      })),
      colors,
    };
  }, [data, getColor]);

  return (
    <CardContainer
      color="grey"
      sx={{
        '& .MuiCardContent-root': {
          ...slotProps?.root,
        },
      }}
      fullWidth
      {...slotProps?.cardContainer}
    >
      <Stack sx={{ alignItems: 'center', justifyContent: 'center' }}>
        <TreemapChart
          data={{
            datasets: [
              {
                data: [],
                tree: memoizedData.tree,
                key: 'value',
                groups: ['label'],
                spacing: 1,
                borderWidth: 0,
                borderRadius: 4,
                backgroundColor: (ctx: any) => {
                  if (!ctx.raw) return fallbackColor;
                  return memoizedData.colors[
                    ctx.dataIndex % memoizedData.colors.length
                  ];
                },
                labels: {
                  display: true,
                  formatter: ctx => {
                    const truncationLen = ctx.raw.w * 0.12;
                    return ctx.raw?.g
                      ? truncate(ctx.raw.g, { length: truncationLen })
                      : '';
                  },
                  color: ctx => {
                    if (!ctx.raw)
                      return theme.palette.new.background.elements.default;
                    const bgColor =
                      memoizedData.colors[
                        ctx.dataIndex % memoizedData.colors.length
                      ];
                    const contrastColors = getContrastColors(ctx.dataIndex);
                    return getContrastTextColor(
                      bgColor!,
                      0.6,
                      contrastColors.light,
                      contrastColors.dark,
                    );
                  },
                  font: { size: 14, weight: 600 },
                  position: 'middle',
                },
              },
            ],
          }}
          options={{
            onClick: (_event, elements) => {
              if (!onItemClick) return;
              if (elements.length === 0) return;

              const clickedIndex = elements[0].index;
              onItemClick(clickedIndex);
            },
            responsive: true,
            plugins: {
              legend: {
                display: false,
              },
              tooltip: {
                enabled: true,
                displayColors: false,
                yAlign: 'bottom',
                callbacks: {
                  title: () => '',
                  label: (ctx: any) => {
                    const label = ctx.raw?.g || '';
                    const value = ctx.raw?.v || 0;
                    return `${label}: ${value}`;
                  },
                },
              },
            },
          }}
        />
      </Stack>
      {footer}
    </CardContainer>
  );
};

export default TextChart;
