import React, { useEffect, useRef } from 'react';
import './style.less';

interface TimeSeriesChartProps {
  labels: string[];
  barData1: number[];
  barData2: number[];
}

const TimeSeriesChart: React.FC<TimeSeriesChartProps> = ({ labels, barData1, barData2 }) => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const animationIdRef = useRef<number>();
  const progressRef = useRef(0);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;

    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    // 防抖函数
    const debounce = (func: () => void, wait: number) => {
      let timeout: NodeJS.Timeout;
      return () => {
        clearTimeout(timeout);
        timeout = setTimeout(() => func(), wait);
      };
    };

    // 数据校验
    if (labels.length === 0 || barData1.length === 0 || barData2.length === 0) {
      console.warn('无数据可绘制');
      return;
    }

    if (barData1.length !== labels.length || barData2.length !== labels.length) {
      console.error('labels、barData1 和 barData2 的长度不一致');
      return;
    }

    // 计算最大值
    const maxDataValue = Math.max(...barData1, ...barData2);
    if (!isFinite(maxDataValue) || maxDataValue < 0) {
      console.error('数据中可能包含非数值或者无效数值');
      return;
    }

    // 如果最大值为0，表示所有数据都是0，此时可以选择不绘制或给出提示
    if (maxDataValue === 0) {
      console.warn('所有数据均为0或无效数据');
      return;
    }

    const yLabels = [0, maxDataValue * 0.2, maxDataValue * 0.4, maxDataValue * 0.6, maxDataValue * 0.8, maxDataValue];

    const resizeCanvas = () => {
      const dpr = window.devicePixelRatio || 1;
      const rect = canvas.getBoundingClientRect();
      canvas.width = rect.width * dpr;
      canvas.height = rect.height * dpr;
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0); // 重置并缩放
      progressRef.current = 0; // 重置动画进度
      draw(); // 调整大小后重新绘制
    };

    const draw = () => {
      // 清除画布
      ctx.clearRect(0, 0, canvas.width, canvas.height);

      const chartWidth = canvas.clientWidth;
      const chartHeight = canvas.clientHeight;
      const leftPadding = 50;
      const rightPadding = 20;
      const bottomPadding = chartHeight * 0.2;
      const topPadding = chartHeight * 0.1;
      const totalBars = labels.length;
      const barGroupWidth = (chartWidth - leftPadding - rightPadding) / totalBars;
      
      // 避免除零
      if (!isFinite(barGroupWidth) || barGroupWidth <= 0) {
        console.error('barGroupWidth 计算不正确，请检查数据和尺寸设置');
        return;
      }

      const barWidth = barGroupWidth / 3.5; 
      const maxBarHeight = chartHeight - topPadding - bottomPadding;
      const fontSize = chartWidth * 0.02; 

      // 绘制y轴标签和网格线
      yLabels.forEach(value => {
        const y = topPadding + (1 - value / maxDataValue) * maxBarHeight;
        ctx.strokeStyle = '#3e4b5b';
        ctx.lineWidth = 1;
        ctx.beginPath();
        ctx.moveTo(leftPadding, y);
        ctx.lineTo(chartWidth - rightPadding, y);
        ctx.stroke();

        ctx.fillStyle = '#FFFFFF';
        ctx.textAlign = 'right';
        ctx.textBaseline = 'middle';
        ctx.font = `${fontSize * 0.6}px Arial`;
        ctx.fillText(`${Math.round(value * 100) / 100}`, leftPadding - 10, y);
      });

      // 绘制单个柱子的函数
      const drawBar = (
        value: number,
        index: number,
        barOffset: number,
        colorStart: string,
        colorEnd: string
      ) => {
        // 避免除零和无效值
        if (maxDataValue === 0) return;

        const barHeight = (value / maxDataValue) * maxBarHeight * progressRef.current;
        const x = leftPadding + index * barGroupWidth + barWidth * barOffset;
        const y = topPadding + (maxBarHeight - barHeight);

        // 在创建渐变前校验数值
        if (!isFinite(x) || !isFinite(y) || !isFinite(barHeight)) {
          console.error('Invalid value for gradient creation:', { x, y, barHeight });
          return;
        }

        const gradient = ctx.createLinearGradient(x, y, x, y + barHeight);
        gradient.addColorStop(0, colorStart);
        gradient.addColorStop(1, colorEnd);

        ctx.fillStyle = gradient;
        ctx.fillRect(x, y, barWidth, barHeight);

        // 显示柱子值
        ctx.fillStyle = '#FFFFFF';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'bottom';
        ctx.font = `${fontSize * 0.5}px Arial`;
        ctx.fillText(`${value}`, x + barWidth / 2, y - 5);
      };

      // 绘制 barData1 的柱子
      barData1.forEach((value, index) => {
        drawBar(value, index, 0.25, 'rgba(128, 191, 255, 1)', 'rgba(128, 191, 255, 0)');
      });

      // 绘制 barData2 的柱子
      barData2.forEach((value, index) => {
        drawBar(value, index, 1.25, 'rgba(255, 234, 128, 1)', 'rgba(255, 234, 128, 0)');
      });

      // 绘制 x 轴标签
      labels.forEach((label, index) => {
        const x = leftPadding + index * barGroupWidth + barGroupWidth / 2;
        ctx.fillStyle = '#FFFFFF';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'top';
        ctx.font = `${fontSize * 0.7}px Arial`;
        ctx.fillText(label, x, chartHeight - bottomPadding + 10);
      });

      // 动画效果
      if (progressRef.current < 1) {
        progressRef.current += 0.02;
        animationIdRef.current = requestAnimationFrame(draw);
      }
    };

    // 初始化尺寸并首次绘制
    resizeCanvas();

    const handleResize = debounce(() => {
      resizeCanvas();
    }, 100);

    window.addEventListener('resize', handleResize);

    // 启动动画
    animationIdRef.current = requestAnimationFrame(draw);

    return () => {
      window.removeEventListener('resize', handleResize);
      if (animationIdRef.current) {
        cancelAnimationFrame(animationIdRef.current);
      }
    };
  }, [labels, barData1, barData2]);

  return <canvas ref={canvasRef} className="time-series-chart" />;
};

export default TimeSeriesChart;
