// import Chart from 'chart.js/auto';
import { Chart as ChartJS, ArcElement, Tooltip, Legend } from 'chart.js';

import { useRef, useEffect } from 'react';
import './Chart.scss';

interface Props {
  chartData: {
    labels: string[];
    datasets: {
      data: number[];
      toolTipMailArray: string[];
      count: number[];
    }[];
  };
  chartHeight: string;
  chartWidth: string;
  toolTipText: string;
  xAxisLabel: string;
  yAxisLabel: string;
}

const BarChart = ({
  chartData,
  chartHeight,
  chartWidth,
  toolTipText,
  xAxisLabel,
  yAxisLabel,
}: Props) => {
  const dynamicTooltipTextRef = useRef(toolTipText);

  useEffect(() => {
    dynamicTooltipTextRef.current = toolTipText;
  }, [toolTipText]);

  const calculatedWidth = `${chartData?.labels?.length * 10}vw`;
  const containerExtend = {
    height: chartHeight,
    width: calculatedWidth,
  };
  const containerBody = {
    height: chartHeight,
    width: chartWidth,
  };

  const chartRef1 = useRef<any | null>(null);
  const chartRef2 = useRef<any | null>(null);
  const graphRef = useRef<any | null>();
  const renderExternalTooltip = (context: any) => {
    let tooltipEl = document.getElementById('chartjs-tooltip');

    if (!tooltipEl) {
      tooltipEl = document.createElement('div');
      tooltipEl.id = 'chartjs-tooltip';
      document.body.appendChild(tooltipEl);
    }
    const tooltipModel = context.tooltip;
    if (tooltipModel.opacity === 0) {
      tooltipEl.style.opacity = '0';
      return;
    }
    if (tooltipModel.body) {
      const { dataPoints } = tooltipModel;
      tooltipEl.innerHTML = '';
      dataPoints.forEach(({ datasetIndex, dataIndex }: any) => {
        const dataset = chartData.datasets[datasetIndex];
        const label = chartData.labels[dataIndex];
        const data = dataset.data[dataIndex];
        const count = dataset?.count[dataIndex];
        const toolTipMail = dataset.toolTipMailArray[dataIndex];
        if (toolTipMail && toolTipMail.length > 0) {
          tooltipEl.innerHTML += `
            <div class="barChart-tooltip-label">${label}</div>
            <div class="barChart-tooltip-text">${toolTipMail}</div>
            <div class="barChart-tooltip-count"><span class="count-value">${dynamicTooltipTextRef.current}: </span><span class="count-percent">${data} (${count}%)</span></div>`;
        } else {
          tooltipEl.innerHTML += `
            <div class="barChart-tooltip-label">${label}</div>
            <div class="barChart-tooltip-count"><span class="count-value">${dynamicTooltipTextRef.current}: </span><span class="count-percent">${data} (${count}%)</span></div>`;
        }
      });
    }
    const position = context.chart.canvas.getBoundingClientRect();
    const dataIndex = context.tooltip.dataPoints[0]?.dataIndex;
    const isLastBar = dataIndex === chartData.labels.length - 1;
    const tooltipX = isLastBar
      ? position.left + tooltipModel.caretX - tooltipEl.offsetWidth - 5
      : position.left + tooltipModel.caretX;
    const tooltipY = position.top + tooltipModel.caretY - 50;

    tooltipEl.style.position = 'absolute';
    tooltipEl.style.left = `${tooltipX}px`;
    tooltipEl.style.top = `${tooltipY}px`;
    tooltipEl.style.opacity = '1';
    tooltipEl.style.backgroundColor = '#FFFFFF';
    tooltipEl.style.border = '1px solid #C4C3C3';
    tooltipEl.style.borderRadius = '5px';
    tooltipEl.style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)';
    tooltipEl.style.padding = '10px';
    tooltipEl.style.pointerEvents = 'none';
  };
  const zeroCount = chartData.datasets[0].data.every(
    (element) => element === 0
  );
  const canvasCallback = (canvas: HTMLCanvasElement) => {
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    const gracePercent = zeroCount ? '0%' : '5%';
    const yAxisRange = zeroCount ? { min: 0, max: 100 } : { beginAtZero: true };
    if (chartRef1.current) {
      chartRef1.current.destroy();
    }
    if (ctx) {
      chartRef1.current = new ChartJS(ctx, {
        type: 'bar',
        data: chartData,
        options: {
          maintainAspectRatio: false,
          layout: {
            padding: {
              top: 10,
            },
          },
          scales: {
            x: {
              ticks: {
                callback: (value) => {
                  const label =
                    chartRef1.current?.scales['x']?.getLabelForValue(value);
                  return String(label).substring(0, 10);
                },
              },
              grid: {
                display: false,
              },
              title: {
                display: true,
                text: '',
                font: {
                  size: 13,
                },
              },
              offset: true,
            },
            y: {
              ...yAxisRange,
              grace: gracePercent,
              ticks: {
                display: false,
              },
              grid: {
                drawTicks: false,
              },
            },
          },
          plugins: {
            legend: {
              display: false,
            },
            tooltip: {
              enabled: false,
              external: renderExternalTooltip,
            },
          },
        },
      });
    }
  };
  const canvasCallback2 = (canvas: HTMLCanvasElement | null) => {
    let paddingValue = chartData?.labels.length > 10 ? 56 : 56;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    const gracePercent = zeroCount ? '0%' : '5%';
    const yAxisRange = zeroCount ? { min: 0, max: 100 } : { beginAtZero: true };
    if (chartRef2.current) {
      chartRef2.current.destroy();
    }
    if (ctx) {
      chartRef2.current = new ChartJS(ctx, {
        type: 'bar',
        data: chartData,
        options: {
          maintainAspectRatio: false,
          layout: {
            padding: {
              bottom: paddingValue,
            },
          },
          scales: {
            x: {
              ticks: {
                display: false,
              },
              grid: {
                drawTicks: false,
              },
            },
            y: {
              ...yAxisRange,
              grace: gracePercent,
              afterFit: (ctx) => {
                ctx.width = 42;
              },
              title: {
                display: true,
                text: '',
                font: {
                  size: 13,
                },
                padding: {
                  top: -1,
                },
              },
            },
          },
          plugins: {
            legend: {
              display: false,
            },
          },
        },
      });
    }
  };

  useEffect(() => {
    if (chartRef1.current) {
      chartRef1.current.data = chartData;
      chartRef1.current.update();
      chartRef1.current.options.plugins.tooltip.external =
        renderExternalTooltip;
    }
    if (chartRef2.current) {
      chartRef2.current.data = chartData;
      chartRef2.current.update();
    }

    if (chartRef2.current) {
      chartRef2.current.options.scales.y.title.text = yAxisLabel;
      chartRef2.current.update();
    }

    if (chartRef1.current) {
      chartRef1.current.options.scales.x.title.text = xAxisLabel;
      chartRef1.current.update();
    }

    return () => {};
  }, [chartData, toolTipText, xAxisLabel, yAxisLabel]);

  return (
    <div>
      <div className="bar-chartBox" ref={graphRef}>
        <div className="bar-colSmall" style={{ height: chartHeight }}>
          <canvas ref={canvasCallback2} id="chart2"></canvas>
        </div>
        <div className="collarge">
          <div
            style={
              chartData?.labels?.length > 6 ? containerExtend : containerBody
            }
          >
            <canvas
              ref={canvasCallback}
              id="chart1"
              className="barchart-container"
            ></canvas>
          </div>
        </div>
      </div>
    </div>
  );
};

export default BarChart;
