import React, { useMemo } from 'react';
import ReactECharts from 'echarts-for-react';
import { useTheme } from '@mui/material/styles';
import { Box, Typography } from '@mui/material';

interface DataPoint {
  currentTimestamp: Date;
  futureTimestamp: Date;
  currentValue: number;
  predictedValue: number;
}

interface MonitoringChartProps {
  data: DataPoint[];
  height?: number;
  zoomRange?: [number, number];
  onZoomChange?: (range: [number, number]) => void;
  chartTitle: string;
  unit: string;
  colors?: {
    current: string;
    predicted: string;
  };
}

const MonitoringChart: React.FC<MonitoringChartProps> = React.memo(({ 
  data, 
  height = 400, 
  zoomRange, 
  onZoomChange,
  chartTitle,
  unit,
  colors
}) => {
  const theme = useTheme();

  const commonSeriesSettings = {
    sampling: 'lttb',
    showSymbol: false,
    smooth: 0.3,
    animation: false,
    emphasis: {
      disabled: true
    }
  };

  const option = useMemo(() => {
    if (!data || data.length === 0) {
      return {};
    }

    const currentData = data.map(item => [
      item.currentTimestamp.getTime(),
      Number(item.currentValue.toFixed(2))
    ]);

    const predictedData = data.map(item => [
      item.futureTimestamp.getTime(),
      Number(item.predictedValue.toFixed(2))
    ]);

    const allValues = [...data.map(d => d.currentValue), ...data.map(d => d.predictedValue)];
    const minValue = Math.min(...allValues);
    const maxValue = Math.max(...allValues);
    const valuePadding = (maxValue - minValue) * 0.1;

    const currentColor = colors?.current || theme.palette.primary.main;
    const predictedColor = colors?.predicted || theme.palette.warning.main;

    return {
      animation: false,
      progressive: 500,
      progressiveThreshold: 1000,
      renderer: 'canvas',
      title: {
        text: chartTitle,
        textStyle: {
          fontSize: 18,
          fontWeight: 'bold',
          color: theme.palette.text.primary,
          fontFamily: 'Montserrat, sans-serif'
        },
        left: 'center',
        top: 10
      },
      tooltip: {
        trigger: 'axis',
        backgroundColor: 'rgba(255, 255, 255, 0.95)',
        borderColor: currentColor,
        borderWidth: 1,
        textStyle: {
          color: theme.palette.text.primary,
          fontFamily: 'Montserrat, sans-serif'
        },
        formatter: function (params: any) {
          const time = new Date(params[0].value[0]).toLocaleString();
          let html = `<div style="margin-bottom: 8px; font-weight: bold;">${time}</div>`;
          params.forEach((param: any) => {
            html += `
              <div style="display: flex; align-items: center; margin-bottom: 4px;">
                <span style="display: inline-block; margin-right: 8px; border-radius: 50%; width: 10px; height: 10px; background-color: ${param.color};"></span>
                <span style="font-weight: 500;">${param.seriesName}:</span>
                <span style="margin-left: 8px; color: ${param.color}; font-weight: bold;">${param.value[1]}${unit}</span>
              </div>
            `;
          });
          return html;
        }
      },
      legend: {
        data: ['Current Value', 'Predicted Value'],
        top: 40,
        textStyle: {
          fontFamily: 'Montserrat, sans-serif',
          fontSize: 12,
          color: theme.palette.text.secondary
        }
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '15%',
        top: '25%',
        containLabel: true
      },
      toolbox: {
        feature: {
          dataZoom: {
            yAxisIndex: 'none',
            title: {
              zoom: 'Zoom',
              back: 'Reset Zoom'
            }
          },
          restore: {
            title: 'Reset'
          },
          saveAsImage: {
            title: 'Save'
          }
        },
        right: 15,
        top: 5
      },
      dataZoom: [
        {
          type: 'slider',
          show: true,
          xAxisIndex: [0],
          start: zoomRange?.[0] ?? 0,
          end: zoomRange?.[1] ?? 100,
          height: 20,
          bottom: 0,
          borderColor: theme.palette.divider,
          fillerColor: `${currentColor}1A`, // 10% opacity
          textStyle: {
            color: theme.palette.text.secondary,
            fontFamily: 'Montserrat, sans-serif'
          },
          handleStyle: {
            color: currentColor
          }
        },
        {
          type: 'inside',
          xAxisIndex: [0],
          start: 0,
          end: 100,
          zoomOnMouseWheel: 'shift'
        }
      ],
      xAxis: {
        type: 'time',
        boundaryGap: false,
        axisLabel: {
          formatter: function (value: number) {
            const date = new Date(value);
            return date.toLocaleTimeString('en-US', { 
              hour: '2-digit', 
              minute: '2-digit'
            });
          },
          color: theme.palette.text.secondary,
          fontFamily: 'Montserrat, sans-serif'
        },
        axisLine: {
          lineStyle: {
            color: theme.palette.divider
          }
        },
        splitLine: {
          show: true,
          lineStyle: {
            color: theme.palette.divider,
            type: 'dashed',
            opacity: 0.5
          }
        }
      },
      yAxis: {
        type: 'value',
        name: chartTitle,
        nameTextStyle: {
          color: theme.palette.text.secondary,
          fontFamily: 'Montserrat, sans-serif',
          fontWeight: 'bold'
        },
        min: Math.max(0, minValue - valuePadding),
        max: maxValue + valuePadding,
        axisLabel: {
          formatter: `{value}${unit}`,
          color: theme.palette.text.secondary,
          fontFamily: 'Montserrat, sans-serif'
        },
        axisLine: {
          lineStyle: {
            color: theme.palette.divider
          }
        },
        splitLine: {
          lineStyle: {
            color: theme.palette.divider,
            type: 'dashed',
            opacity: 0.3
          }
        }
      },
      series: [
        {
          ...commonSeriesSettings,
          name: 'Current Value',
          type: 'line',
          data: currentData,
          lineStyle: {
            color: currentColor,
            width: 2,
            join: 'round'
          },
          itemStyle: {
            color: currentColor,
            opacity: 0.8
          },
          areaStyle: {
            color: {
              type: 'linear',
              x: 0,
              y: 0,
              x2: 0,
              y2: 1,
              colorStops: [{
                offset: 0,
                color: `${currentColor}33` // 20% opacity
              }, {
                offset: 1,
                color: `${currentColor}05` // 2% opacity
              }]
            }
          }
        },
        {
          ...commonSeriesSettings,
          name: 'Predicted Value',
          type: 'line',
          data: predictedData,
          lineStyle: {
            color: predictedColor,
            width: 2,
            type: 'dashed'
          },
          itemStyle: {
            color: predictedColor,
            opacity: 0.8
          }
        }
      ]
    };
  }, [data, theme, chartTitle, unit, colors, zoomRange]);

  if (!data || data.length === 0) {
    return (
      <Box 
        display="flex" 
        justifyContent="center" 
        alignItems="center" 
        height={height}
        bgcolor={theme.palette.background.paper}
        borderRadius={2}
        boxShadow={2}
      >
        <Typography 
          variant="h6" 
          color="text.secondary"
          fontFamily="Montserrat, sans-serif"
        >
          No data available
        </Typography>
      </Box>
    );
  }

  return (
    <Box 
      sx={{ 
        bgcolor: theme.palette.background.paper,
        borderRadius: 2,
        boxShadow: 3,
        overflow: 'hidden'
      }}
    >
      <ReactECharts
        option={option}
        style={{ height: `${height}px`, width: '100%' }}
        opts={{
          renderer: 'canvas',
          width: 'auto',
          height: 'auto',
        }}
        notMerge={true}
        lazyUpdate={true}
        theme={theme.palette.mode}
        loadingOption={{
          color: theme.palette.primary.main,
          maskColor: 'rgba(255, 255, 255, 0.8)',
          text: 'Loading...'
        }}
        onEvents={{
          datazoom: (params: any) => {
            if (onZoomChange && params.batch?.[0]) {
              onZoomChange([params.batch[0].start, params.batch[0].end]);
            }
          }
        }}
      />
    </Box>
  );
}, (prevProps, nextProps) => {
  // Always re-render if data length changes
  if (prevProps.data.length !== nextProps.data.length) return false;
  
  // Always re-render if essential props change
  if (prevProps.height !== nextProps.height) return false;
  if (prevProps.chartTitle !== nextProps.chartTitle) return false;
  if (prevProps.unit !== nextProps.unit) return false;
  if (prevProps.zoomRange?.[0] !== nextProps.zoomRange?.[0] || 
      prevProps.zoomRange?.[1] !== nextProps.zoomRange?.[1]) return false;

  // Deep compare the last few data points
  const compareCount = 5; // Compare last 5 points for smooth transitions
  for (let i = 1; i <= compareCount; i++) {
    const prevItem = prevProps.data[prevProps.data.length - i];
    const nextItem = nextProps.data[nextProps.data.length - i];
    
    if (!prevItem || !nextItem) return false;
    
    if (prevItem.currentTimestamp.getTime() !== nextItem.currentTimestamp.getTime() ||
        prevItem.currentValue !== nextItem.currentValue ||
        prevItem.predictedValue !== nextItem.predictedValue) {
      return false;
    }
  }
  
  return true;
});

MonitoringChart.displayName = 'MonitoringChart';

export default MonitoringChart;