import React, { useMemo, useState, useEffect } from 'react';
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend } from 'recharts';
import { formatNumber, formatFullNumber } from '../utils/formatters';

/**
 * Helper function to get the start time of the most recent trading session
 * Trading session: 22:30 - next day 05:00
 * @param {Date|null} virtualTime - Virtual time from server (for mock mode), or null to use real time
 */
function getRecentTradingSessionStart(virtualTime = null) {
  // Use virtual time if provided (for mock mode), otherwise use real time
  let now;
  if (virtualTime) {
    // Ensure virtualTime is a valid Date object
    if (virtualTime instanceof Date && !isNaN(virtualTime.getTime())) {
      now = virtualTime;
    } else if (typeof virtualTime === 'string') {
      now = new Date(virtualTime);
      if (isNaN(now.getTime())) {
        console.warn('Invalid virtualTime string, using current time:', virtualTime);
        now = new Date();
      }
    } else {
      console.warn('Invalid virtualTime type, using current time:', typeof virtualTime);
      now = new Date();
    }
  } else {
    now = new Date();
  }

  const currentHour = now.getHours();
  const currentMinute = now.getMinutes();

  // Check if currently in trading session
  const isInTradingSession = (currentHour === 22 && currentMinute >= 30) ||
                              currentHour >= 23 ||
                              (currentHour >= 0 && currentHour < 5) ||
                              (currentHour === 5 && currentMinute === 0);

  let sessionStartTime;
  if (isInTradingSession) {
    // Currently in trading session, find today's 22:30
    sessionStartTime = new Date(now);
    sessionStartTime.setHours(22, 30, 0, 0);
    // If current time is before 22:30, it means yesterday's 22:30
    if (now < sessionStartTime) {
      sessionStartTime.setDate(sessionStartTime.getDate() - 1);
    }
  } else {
    // Not in trading session, find previous session start (yesterday 22:30)
    sessionStartTime = new Date(now);
    sessionStartTime.setDate(sessionStartTime.getDate() - 1);
    sessionStartTime.setHours(22, 30, 0, 0);
  }

  return sessionStartTime;
}

/**
 * Helper function to filter strategy data for live view
 * NOTE: Live mode returns are now pre-processed by the backend, restricted to the
 * latest trading session and already starting at 0% at session start. This helper
 * is kept for potential future use but is no longer used in live mode.
 */
function filterStrategyDataForLive(strategyData, equity, sessionStartTime) {
  if (!strategyData || strategyData.length === 0 || !equity || equity.length === 0) return [];

  try {
    if (!sessionStartTime || isNaN(sessionStartTime.getTime())) {
      console.warn('Invalid sessionStartTime in filterStrategyDataForLive');
      return [];
    }

    const sessionStartTimestamp = sessionStartTime.getTime();

    // Find the last index before session
    let lastDataBeforeSession = null;
    for (let i = equity.length - 1; i >= 0; i--) {
      if (equity[i] && typeof equity[i].t === 'number' && equity[i].t < sessionStartTimestamp) {
        if (strategyData[i] && strategyData[i].v !== undefined && strategyData[i].v !== null) {
          lastDataBeforeSession = strategyData[i];
        }
        break;
      }
    }

    // Find data points in the session
    const sessionData = [];
    for (let i = 0; i < equity.length; i++) {
      if (equity[i] && typeof equity[i].t === 'number' &&
          equity[i].t >= sessionStartTimestamp &&
          strategyData[i] &&
          strategyData[i].v !== undefined && strategyData[i].v !== null) {
        sessionData.push(strategyData[i]);
      }
    }

    // If we have a value before session and session data, add the start point
    // Create a start point with timestamp just before session start
    if (lastDataBeforeSession && sessionData.length > 0) {
      const startPoint = {
        t: sessionStartTimestamp - 1,
        v: lastDataBeforeSession.v
      };
      return [startPoint, ...sessionData];
    }

    return sessionData;
  } catch (error) {
    console.error('Error in filterStrategyDataForLive:', error);
    return [];
  }
}

/**
 * Net Value Chart Component
 * Displays portfolio value over time with multiple strategy comparisons
 */
export default function NetValueChart({ equity, baseline, baseline_vw, momentum, strategies, equity_return, baseline_return, baseline_vw_return, momentum_return, chartTab = 'all', virtualTime = null }) {
  const [activePoint, setActivePoint] = useState(null);
  const [stableYRange, setStableYRange] = useState(null);
  const [legendTooltip, setLegendTooltip] = useState(null);

  // Legend descriptions
  const legendDescriptions = {
    'EvoTraders': 'EvoTraders is our agents investment strategy',
    'Buy & Hold (EW)': 'Equal Weight: Can be viewed as an equal-weighted index of all invested stocks',
    'Buy & Hold (VW)': 'Value Weighted: Can be viewed as a market-cap weighted index of all invested stocks',
    'Momentum': 'Momentum Strategy: Buy stocks that have performed well in the past',
  };


  // For live mode, use cumulative returns calculated by backend
  // For all mode, use portfolio values directly
  const dataSource = useMemo(() => {
    if (chartTab === 'live') {
      return {
        equity: equity_return || equity,
        baseline: baseline_return || baseline,
        baseline_vw: baseline_vw_return || baseline_vw,
        momentum: momentum_return || momentum
      };
    }
    return {
      equity: equity,
      baseline: baseline,
      baseline_vw: baseline_vw,
      momentum: momentum
    };
  }, [chartTab, equity, baseline, baseline_vw, momentum, equity_return, baseline_return, baseline_vw_return, momentum_return]);
  // Filter equity data based on chartTab
  const filteredEquity = useMemo(() => {
    if (chartTab === 'all') {
      const sourceEquity = dataSource.equity;
      if (!sourceEquity || sourceEquity.length === 0) return [];

      // ALL chart: Show only the last point per day
      // Logic: Keep the last equity value before 22:30 each day (the last equity value before US next trading day opens)
      // Data after 22:30 belongs to the next trading day's session and is not shown in this chart
      // Time handling: timestamp(ms) -> UTC -> Asia/Shanghai timezone, then group and filter based on Asia/Shanghai time
      const dailyData = {};

      sourceEquity.forEach((d) => {
        // Timestamp is in milliseconds, first create UTC time, then convert to Asia/Shanghai timezone
        // Equivalent to: pd.to_datetime(timestamp, unit='ms', utc=True).dt.tz_convert('Asia/Shanghai')
        const utcDate = new Date(d.t); // timestamp(ms) -> UTC time

        // Use Intl API to get date/time components in Asia/Shanghai timezone
        const formatter = new Intl.DateTimeFormat('en-US', {
          timeZone: 'Asia/Shanghai',
          year: 'numeric',
          month: '2-digit',
          day: '2-digit',
          hour: '2-digit',
          minute: '2-digit',
          hour12: false
        });

        const parts = formatter.formatToParts(utcDate);
        const year = parts.find(p => p.type === 'year').value;
        const month = parts.find(p => p.type === 'month').value;
        const day = parts.find(p => p.type === 'day').value;
        const hour = parseInt(parts.find(p => p.type === 'hour').value);
        const minute = parseInt(parts.find(p => p.type === 'minute').value);

        // Check if before 22:30 (Asia/Shanghai timezone)
        const isBefore2230 = hour < 22 || (hour === 22 && minute < 30);

        // Only process data before 22:30
        if (isBefore2230) {
          // Use Asia/Shanghai timezone date as key
          const dateKey = `${year}-${month}-${day}`;

          // Update if this day has no data yet, or if current data is later in time
          if (!dailyData[dateKey] || new Date(d.t) > new Date(dailyData[dateKey].t)) {
            dailyData[dateKey] = d;
          }
        }
      });

      // Convert to array and sort by time
      return Object.values(dailyData).sort((a, b) => a.t - b.t);
    } else if (chartTab === 'live') {
      // LIVE chart: Show all updates from the most recent trading session (22:30-05:00)
      // Live mode: Backend has already returned return curves for "current trading session + 0% starting point", frontend can use directly
      const sourceEquity = dataSource.equity;
      if (!sourceEquity || sourceEquity.length === 0) return [];
      return sourceEquity;
    }
    return dataSource.equity || [];
  }, [dataSource.equity, chartTab, virtualTime]);
  // Helper function to get daily indices for 'all' view
  const getDailyIndices = useMemo(() => {
    if (!equity || equity.length === 0) return new Set();
    const dailyIndices = new Set();
    const dailyData = {};

    const formatter = new Intl.DateTimeFormat('en-US', {
      timeZone: 'Asia/Shanghai',
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
      hour12: false
    });

    equity.forEach((d, idx) => {
      const utcDate = new Date(d.t);
      const parts = formatter.formatToParts(utcDate);
      const hour = parseInt(parts.find(p => p.type === 'hour').value);
      const minute = parseInt(parts.find(p => p.type === 'minute').value);

      // Check if before 22:30 (Asia/Shanghai timezone)
      const isBefore2230 = hour < 22 || (hour === 22 && minute < 30);

      // Only process data before 22:30
      if (isBefore2230) {
        const year = parts.find(p => p.type === 'year').value;
        const month = parts.find(p => p.type === 'month').value;
        const day = parts.find(p => p.type === 'day').value;
        const dateKey = `${year}-${month}-${day}`;

        if (!dailyData[dateKey] || new Date(d.t) > new Date(dailyData[dateKey].t)) {
          dailyData[dateKey] = { data: d, index: idx };
        }
      }
    });

    Object.values(dailyData).forEach(({ index }) => dailyIndices.add(index));
    return dailyIndices;
  }, [equity]);

  // Filter baseline, baseline_vw, momentum, strategies to match filteredEquity indices
  const filteredBaseline = useMemo(() => {
    const sourceBaseline = dataSource.baseline;
    if (!sourceBaseline || sourceBaseline.length === 0 || !equity || equity.length === 0) return [];
    if (chartTab === 'all') {
      return sourceBaseline.filter((_, idx) => getDailyIndices.has(idx));
    } else if (chartTab === 'live') {
      // Live mode: Use backend pre-processed baseline return curves directly
      return sourceBaseline;
    }
    return sourceBaseline;
  }, [dataSource.baseline, equity, chartTab, getDailyIndices, virtualTime]);
  const filteredBaselineVw = useMemo(() => {
    const sourceBaselineVw = dataSource.baseline_vw;
    if (!sourceBaselineVw || sourceBaselineVw.length === 0 || !equity || equity.length === 0) return [];
    if (chartTab === 'all') {
      return sourceBaselineVw.filter((_, idx) => getDailyIndices.has(idx));
    } else if (chartTab === 'live') {
      // Live mode: Use backend pre-processed baseline return curves directly
      return sourceBaselineVw;
    }
    return sourceBaselineVw;
  }, [dataSource.baseline_vw, equity, chartTab, getDailyIndices, virtualTime]);
  const filteredMomentum = useMemo(() => {
    const sourceMomentum = dataSource.momentum;
    if (!sourceMomentum || sourceMomentum.length === 0 || !equity || equity.length === 0) return [];
    if (chartTab === 'all') {
      return sourceMomentum.filter((_, idx) => getDailyIndices.has(idx));
    } else if (chartTab === 'live') {
      // Live mode: Use backend pre-processed momentum return curves directly
      return sourceMomentum;
    }
    return sourceMomentum;
  }, [dataSource.momentum, equity, chartTab, getDailyIndices, virtualTime]);
  const filteredStrategies = useMemo(() => {
    if (!strategies || strategies.length === 0 || !equity || equity.length === 0) return [];
    if (chartTab === 'all') {
      return strategies.filter((_, idx) => getDailyIndices.has(idx));
    } else if (chartTab === 'live') {
      const sessionStartTime = getRecentTradingSessionStart(virtualTime);
      return filterStrategyDataForLive(strategies, equity, sessionStartTime);
    }
    return strategies;
  }, [strategies, equity, chartTab, getDailyIndices, virtualTime]);

  const chartData = useMemo(() => {
    if (!filteredEquity || filteredEquity.length === 0) return [];

    try {
      // LIVE mode: Align all curves by timestamp with forward filling to ensure consistent point counts and aligned starting points
      if (chartTab === 'live') {
        // Build timestamp -> value mapping
        const toMap = (arr) => {
          const m = new Map();
          if (Array.isArray(arr)) {
            arr.forEach((p) => {
              if (p && typeof p.t === 'number' && typeof p.v === 'number') {
                m.set(p.t, p.v);
              }
            });
          }
          return m;
        };

        const portfolioMap = toMap(filteredEquity);
        const baselineMap = toMap(filteredBaseline);
        const baselineVwMap = toMap(filteredBaselineVw);
        const momentumMap = toMap(filteredMomentum);
        const strategyMap = toMap(filteredStrategies);

        // Collect all timestamps, sort by time
        const timestampSet = new Set();
        [filteredEquity, filteredBaseline, filteredBaselineVw, filteredMomentum, filteredStrategies].forEach(arr => {
          if (Array.isArray(arr)) {
            arr.forEach(p => {
              if (p && typeof p.t === 'number') timestampSet.add(p.t);
            });
          }
        });

        const timestamps = Array.from(timestampSet).sort((a, b) => a - b);
        if (timestamps.length === 0) return [];

        // Current values for forward filling, initialized to 0% to ensure starting point alignment
        let currentPortfolio = 0;
        let currentBaseline = 0;
        let currentBaselineVw = 0;
        let currentMomentum = 0;
        let currentStrategy = 0;

        return timestamps.map((t, idx) => {
          if (portfolioMap.has(t)) currentPortfolio = portfolioMap.get(t);
          if (baselineMap.has(t)) currentBaseline = baselineMap.get(t);
          if (baselineVwMap.has(t)) currentBaselineVw = baselineVwMap.get(t);
          if (momentumMap.has(t)) currentMomentum = momentumMap.get(t);
          if (strategyMap.has(t)) currentStrategy = strategyMap.get(t);

          const date = new Date(t);
          if (isNaN(date.getTime())) {
            console.warn('Invalid timestamp in live chart data:', t);
            return null;
          }

          return {
            index: idx,
            time:
              date.toLocaleDateString('en-US', {
                month: 'short',
                day: 'numeric',
              }) +
              ' ' +
              date.toLocaleTimeString('en-US', {
                hour: '2-digit',
                minute: '2-digit',
                hour12: false,
              }),
            timestamp: t,
            portfolio: currentPortfolio,
            baseline: currentBaseline,
            baseline_vw: currentBaselineVw,
            momentum: currentMomentum,
            strategy: currentStrategy,
          };
        }).filter(item => item !== null);
      }

      // ALL mode: Keep the original index-based alignment logic
      return filteredEquity.map((d, idx) => {
        if (!d || typeof d.t !== 'number' || typeof d.v !== 'number') {
          console.warn('Invalid equity data point:', d);
          return null;
        }

        const date = new Date(d.t);
        if (isNaN(date.getTime())) {
          console.warn('Invalid timestamp:', d.t);
          return null;
        }

        const baselineVal = filteredBaseline?.[idx]
          ? (typeof filteredBaseline[idx] === 'object' ? filteredBaseline[idx].v : filteredBaseline[idx])
          : null;
        const baselineVwVal = filteredBaselineVw?.[idx]
          ? (typeof filteredBaselineVw[idx] === 'object' ? filteredBaselineVw[idx].v : filteredBaselineVw[idx])
          : null;
        const momentumVal = filteredMomentum?.[idx]
          ? (typeof filteredMomentum[idx] === 'object' ? filteredMomentum[idx].v : filteredMomentum[idx])
          : null;
        const strategyVal = filteredStrategies?.[idx]
          ? (typeof filteredStrategies[idx] === 'object' ? filteredStrategies[idx].v : filteredStrategies[idx])
          : null;

        return {
          index: idx,
          time:
            date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }) +
            ' ' +
            date.toLocaleTimeString('en-US', {
              hour: '2-digit',
              minute: '2-digit',
              hour12: false,
            }),
          timestamp: d.t,
          portfolio: d.v,
          baseline: baselineVal || null,
          baseline_vw: baselineVwVal || null,
          momentum: momentumVal || null,
          strategy: strategyVal || null,
        };
      }).filter(item => item !== null); // Remove null entries
    } catch (error) {
      console.error('Error processing chart data:', error);
      return [];
    }
  }, [filteredEquity, filteredBaseline, filteredBaselineVw, filteredMomentum, filteredStrategies, chartTab]);

  const { yMin, yMax, xTickIndices } = useMemo(() => {
    if (chartData.length === 0) return { yMin: 0, yMax: 1, xTickIndices: [] };

    // Calculate min and max from all series
    const allValues = chartData.flatMap(d =>
      [d.portfolio, d.baseline, d.baseline_vw, d.momentum, d.strategy].filter(v => v !== null && isFinite(v))
    );

    if (allValues.length === 0) {
      return { yMin: 0, yMax: 1000000, xTickIndices: [] };
    }

    const dataMin = Math.min(...allValues);
    const dataMax = Math.max(...allValues);
    const range = dataMax - dataMin || 1;

    // For live mode (percentage data), use smaller padding and finer rounding
    // For all mode (dollar amounts), use larger padding and coarser rounding
    const isLiveMode = chartTab === 'live';

    const paddingFactor = isLiveMode ? range * 0.15 : range * 0.03;

    let yMinCalc = dataMin - paddingFactor;
    let yMaxCalc = dataMax + paddingFactor;

    // Smart rounding based on magnitude and mode
    const magnitude = Math.max(Math.abs(yMinCalc), Math.abs(yMaxCalc));
    let roundTo;

    if (isLiveMode) {
      // For percentage data, use much finer rounding
      if (magnitude >= 100) {
        roundTo = 10;
      } else if (magnitude >= 10) {
        roundTo = 1;
      } else if (magnitude >= 1) {
        roundTo = 0.1;
      } else {
        roundTo = 0.01;
      }
    } else {
      // For dollar amounts, use coarser rounding
      if (magnitude >= 1e6) {
        roundTo = 10000;
      } else if (magnitude >= 1e5) {
        roundTo = 5000;
      } else if (magnitude >= 1e4) {
        roundTo = 1000;
      } else {
        roundTo = 100;
      }
    }

    yMinCalc = Math.floor(yMinCalc / roundTo) * roundTo;
    yMaxCalc = Math.ceil(yMaxCalc / roundTo) * roundTo;

    // Stable range to prevent frequent updates
    if (stableYRange) {
      const { min: stableMin, max: stableMax } = stableYRange;
      const stableRange = stableMax - stableMin;
      const threshold = stableRange * 0.05;

      const needsUpdate =
        dataMin < (stableMin + threshold) ||
        dataMax > (stableMax - threshold);

      if (!needsUpdate) {
        yMinCalc = stableMin;
        yMaxCalc = stableMax;
      }
    }

    // Calculate x-axis tick indices
    const safeLength = Math.min(chartData.length, 10000);
    const targetTicks = Math.min(8, Math.max(5, Math.floor(safeLength / 10)));
    const step = Math.max(1, Math.floor(safeLength / (targetTicks - 1)));

    const indices = [];
    for (let i = 0; i < safeLength && indices.length < 100; i += step) {
      indices.push(i);
    }

    if (safeLength > 0 && indices[indices.length - 1] !== safeLength - 1) {
      indices.push(safeLength - 1);
    }

    return { yMin: yMinCalc, yMax: yMaxCalc, xTickIndices: indices };
  }, [chartData, stableYRange]);

  // Update stableYRange in useEffect to avoid infinite re-renders
  // Use functional update to avoid dependency on stableYRange
  useEffect(() => {
    if (yMin !== undefined && yMax !== undefined && yMin !== null && yMax !== null && isFinite(yMin) && isFinite(yMax)) {
      setStableYRange(prevRange => {
        if (!prevRange) {
          // Initialize stable range
          return { min: yMin, max: yMax };
        } else {
          // Check if update is needed (5% threshold)
          const stableRange = prevRange.max - prevRange.min;
          const threshold = stableRange * 0.05;
          const needsUpdate =
            yMin < (prevRange.min + threshold) ||
            yMax > (prevRange.max - threshold);

          if (needsUpdate) {
            return { min: yMin, max: yMax };
          }
          // No update needed, return previous range
          return prevRange;
        }
      });
    }
  }, [yMin, yMax]);

  if (!equity || equity.length === 0) {
    return (
      <div style={{
        width: '100%',
        height: '100%',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        color: '#cccccc',
        fontFamily: '"Courier New", monospace',
        fontSize: '12px'
      }}>
        暂无图表数据
      </div>
    );
  }

  const CustomTooltip = ({ active, payload }) => {
    if (active && payload && payload.length) {
      const isLiveMode = chartTab === 'live';
      return (
        <div style={{
          background: '#000000',
          border: '1px solid #333333',
          padding: '10px 14px',
          fontFamily: '"Courier New", monospace',
          fontSize: '10px',
          color: '#ffffff'
        }}>
          <div style={{ fontWeight: 700, marginBottom: '6px', fontSize: '11px' }}>
            {payload[0].payload.time}
          </div>
          {payload.map((entry, index) => (
            <div key={index} style={{ color: entry.color, marginTop: '2px' }}>
              <span style={{ fontWeight: 700 }}>{entry.name}:</span> {isLiveMode ? `${entry.value.toFixed(2)}%` : `$${formatNumber(entry.value)}`}            </div>
          ))}
        </div>
      );
    }
    return null;
  };

  const CustomDot = ({ dataKey, ...props }) => {
    const { cx, cy, payload, index } = props;
    const isActive = activePoint === index;
    const isLastPoint = index === chartData.length - 1;

    // Only show dot for the last point
    if (!isLastPoint) {
      return null;
    }
    const colors = {
      portfolio: '#00C853',
      baseline: '#FF6B00',
      baseline_vw: '#9C27B0',
      momentum: '#2196F3',
      strategy: '#795548'
    };

    return (
      <circle
        cx={cx}
        cy={cy}
        r={isActive ? 6 : 8}
        fill={colors[dataKey]}
        stroke="#ffffff"
        strokeWidth={2}
        style={{ cursor: 'pointer' }}
        onMouseEnter={() => setActivePoint(index)}
        onMouseLeave={() => setActivePoint(null)}
        onClick={() => console.log('Clicked point:', { dataKey, ...payload })}
      />
    );
  };

  const CustomXAxisTick = ({ x, y, payload }) => {
    const shouldShow = xTickIndices.includes(payload.index);
    if (!shouldShow) return null;

    return (
      <g transform={`translate(${x},${y})`}>
        <text
          x={0}
          y={0}
          dy={16}
          textAnchor="middle"
          fill="#666666"
          fontSize="10px"
          fontFamily='"Courier New", monospace'
          fontWeight="700"
        >
          {payload.value}
        </text>
      </g>
    );
  };

  const CustomLegend = ({ payload }) => {
    if (!payload || payload.length === 0) return null;

    return (
      <div style={{
        display: 'flex',
        flexWrap: 'wrap',
        gap: '16px',
        padding: '10px 0',
        position: 'relative',
        fontFamily: '"Courier New", monospace',
        fontSize: '11px',
        fontWeight: 700,
        justifyContent: 'center'
      }}>
        {payload.map((entry, index) => {
          const description = legendDescriptions[entry.value] || '';
          const isActive = legendTooltip === entry.value;

          return (
            <div
              key={index}
              style={{
                display: 'flex',
                alignItems: 'center',
                gap: '8px',
                cursor: 'pointer',
                position: 'relative',
                padding: '4px 8px',
                borderRadius: '4px',
                backgroundColor: isActive ? '#f0f0f0' : 'transparent',
                transition: 'background-color 0.2s',
                userSelect: 'none'
              }}
              onMouseEnter={() => setLegendTooltip(entry.value)}
              onMouseLeave={() => setLegendTooltip(null)}
              onClick={(e) => {
                e.stopPropagation();
                setLegendTooltip(isActive ? null : entry.value);
              }}
            >
              <div
                style={{
                  width: '14px',
                  height: '3px',
                  backgroundColor: entry.color,
                  border: 'none'
                }}
              />
              <span
                style={{
                  fontFamily: '"Courier New", monospace',
                  fontSize: '11px',
                  fontWeight: 700,
                  color: '#000000'
                }}
              >
                {entry.value}
              </span>
              {isActive && description && (
                <div
                  style={{
                    position: 'absolute',
                    bottom: '100%',
                    left: 0,
                    marginBottom: '8px',
                    padding: '8px 12px',
                    background: '#000000',
                    color: '#ffffff',
                    fontSize: '10px',
                    fontFamily: '"Courier New", monospace',
                    whiteSpace: 'normal',
                    maxWidth: '300px',
                    zIndex: 1000,
                    borderRadius: '4px',
                    boxShadow: '0 2px 8px rgba(0,0,0,0.3)',
                    pointerEvents: 'none',
                    lineHeight: 1.4
                  }}
                >
                  {description}
                </div>
              )}
            </div>
          );
        })}
      </div>
    );
  };

  return (
    <ResponsiveContainer width="100%" height="100%">
      <LineChart
        data={chartData}
        margin={{ top: 20, right: 30, bottom: 50, left: 60 }}
      >
        <XAxis
          dataKey="time"
          stroke="#666666"
          tick={<CustomXAxisTick />}
          interval={0}
        />
        <YAxis
          domain={[yMin, yMax]}
          stroke="#000000"
          style={{ fontFamily: '"Courier New", monospace', fontSize: '11px', fontWeight: 700 }}
          tick={{ fill: '#000000' }}
          tickFormatter={(value) => chartTab === 'live' ? `${value.toFixed(2)}%` : formatFullNumber(value)}
          width={75}
        />
        <Tooltip content={<CustomTooltip />} />
        <Legend
          content={<CustomLegend />}
        />

        {/* Portfolio line */}
        <Line
          type="linear"
          dataKey="portfolio"
          name="EvoTraders"
          stroke="#00C853"
          strokeWidth={2.5}
          dot={(props) => <CustomDot {...props} dataKey="portfolio" />}
          activeDot={{ r: 6, stroke: '#ffffff', strokeWidth: 2 }}
          isAnimationActive={false}
        />

        {/* Baseline Equal Weight */}
        {baseline && baseline.length > 0 && (
          <Line
            type="linear"
            dataKey="baseline"
            name="Buy & Hold (EW)"
            stroke="#FF6B00"
            strokeWidth={2}
            strokeDasharray="5 5"
            dot={(props) => <CustomDot {...props} dataKey="baseline" />}
            activeDot={{ r: 6, stroke: '#ffffff', strokeWidth: 2 }}
            isAnimationActive={false}
          />
        )}

        {/* Baseline Value Weighted */}
        {baseline_vw && baseline_vw.length > 0 && (
          <Line
            type="linear"
            dataKey="baseline_vw"
            name="Buy & Hold (VW)"
            stroke="#9C27B0"
            strokeWidth={2}
            strokeDasharray="8 4"
            dot={(props) => <CustomDot {...props} dataKey="baseline_vw" />}
            activeDot={{ r: 6, stroke: '#ffffff', strokeWidth: 2 }}
            isAnimationActive={false}
          />
        )}

        {/* Momentum Strategy */}
        {momentum && momentum.length > 0 && (
          <Line
            type="linear"
            dataKey="momentum"
            name="Momentum"
            stroke="#2196F3"
            strokeWidth={2}
            strokeDasharray="3 3"
            dot={(props) => <CustomDot {...props} dataKey="momentum" />}
            activeDot={{ r: 6, stroke: '#ffffff', strokeWidth: 2 }}
            isAnimationActive={false}
          />
        )}

        {/* Other Strategies */}
        {strategies && strategies.length > 0 && (
          <Line
            type="linear"
            dataKey="strategy"
            name="Strategy"
            stroke="#795548"
            strokeWidth={2}
            dot={(props) => <CustomDot {...props} dataKey="strategy" />}
            activeDot={{ r: 6, stroke: '#ffffff', strokeWidth: 2 }}
            isAnimationActive={false}
          />
        )}
      </LineChart>
    </ResponsiveContainer>
  );
}
