/**
 * Performance Chart Component
 * Line chart showing portfolio performance over time
 */

import React, { useEffect, useState, useRef } from 'react';
import {
  getPortfolioPerformance,
  type PerformanceDataPoint,
  type PerformancePeriod,
} from '../../../services/portfolio.service';

interface PerformanceChartProps {
  portfolioId: string;
  height?: number;
}

const PERIOD_OPTIONS: { value: PerformancePeriod; label: string }[] = [
  { value: 'week', label: '7D' },
  { value: 'month', label: '1M' },
  { value: '3months', label: '3M' },
  { value: 'year', label: '1A' },
  { value: 'all', label: 'Todo' },
];

export const PerformanceChart: React.FC<PerformanceChartProps> = ({
  portfolioId,
  height = 300,
}) => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const [data, setData] = useState<PerformanceDataPoint[]>([]);
  const [period, setPeriod] = useState<PerformancePeriod>('month');
  const [loading, setLoading] = useState(true);
  const [hoveredPoint, setHoveredPoint] = useState<PerformanceDataPoint | null>(null);

  useEffect(() => {
    loadData();
  }, [portfolioId, period]);

  useEffect(() => {
    if (data.length > 0) {
      drawChart();
    }
  }, [data, hoveredPoint]);

  const loadData = async () => {
    try {
      setLoading(true);
      const performanceData = await getPortfolioPerformance(portfolioId, period);
      setData(performanceData);
    } catch (error) {
      console.error('Error loading performance data:', error);
      // Generate mock data for demo
      setData(generateMockData(period));
    } finally {
      setLoading(false);
    }
  };

  const generateMockData = (p: PerformancePeriod): PerformanceDataPoint[] => {
    const days = p === 'week' ? 7 : p === 'month' ? 30 : p === '3months' ? 90 : p === 'year' ? 365 : 180;
    const mockData: PerformanceDataPoint[] = [];
    let value = 10000;
    let pnl = 0;

    for (let i = days; i >= 0; i--) {
      const date = new Date();
      date.setDate(date.getDate() - i);
      const change = (Math.random() - 0.4) * value * 0.02;
      value += change;
      pnl = value - 10000;

      mockData.push({
        date: date.toISOString().split('T')[0],
        value,
        pnl,
        pnlPercent: (pnl / 10000) * 100,
        change,
        changePercent: (change / (value - change)) * 100,
      });
    }
    return mockData;
  };

  const drawChart = () => {
    const canvas = canvasRef.current;
    if (!canvas || data.length === 0) return;

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

    const dpr = window.devicePixelRatio || 1;
    const rect = canvas.getBoundingClientRect();
    canvas.width = rect.width * dpr;
    canvas.height = rect.height * dpr;
    ctx.scale(dpr, dpr);

    const width = rect.width;
    const chartHeight = rect.height;
    const padding = { top: 20, right: 20, bottom: 30, left: 60 };
    const chartWidth = width - padding.left - padding.right;
    const innerHeight = chartHeight - padding.top - padding.bottom;

    // Clear canvas
    ctx.clearRect(0, 0, width, chartHeight);

    // Get min/max values
    const values = data.map((d) => d.value);
    const minValue = Math.min(...values) * 0.995;
    const maxValue = Math.max(...values) * 1.005;
    const valueRange = maxValue - minValue;

    // Calculate points
    const points = data.map((d, i) => ({
      x: padding.left + (i / (data.length - 1)) * chartWidth,
      y: padding.top + innerHeight - ((d.value - minValue) / valueRange) * innerHeight,
      data: d,
    }));

    // Determine color based on overall performance
    const isPositive = data[data.length - 1].value >= data[0].value;
    const lineColor = isPositive ? '#10B981' : '#EF4444';
    const fillColor = isPositive ? 'rgba(16, 185, 129, 0.1)' : 'rgba(239, 68, 68, 0.1)';

    // Draw grid lines
    ctx.strokeStyle = 'rgba(156, 163, 175, 0.2)';
    ctx.lineWidth = 1;
    const gridLines = 5;
    for (let i = 0; i <= gridLines; i++) {
      const y = padding.top + (i / gridLines) * innerHeight;
      ctx.beginPath();
      ctx.moveTo(padding.left, y);
      ctx.lineTo(width - padding.right, y);
      ctx.stroke();

      // Y-axis labels
      const value = maxValue - (i / gridLines) * valueRange;
      ctx.fillStyle = '#9CA3AF';
      ctx.font = '11px system-ui';
      ctx.textAlign = 'right';
      ctx.fillText(`$${value.toLocaleString(undefined, { maximumFractionDigits: 0 })}`, padding.left - 8, y + 4);
    }

    // Draw fill gradient
    ctx.beginPath();
    ctx.moveTo(points[0].x, chartHeight - padding.bottom);
    points.forEach((p) => ctx.lineTo(p.x, p.y));
    ctx.lineTo(points[points.length - 1].x, chartHeight - padding.bottom);
    ctx.closePath();
    ctx.fillStyle = fillColor;
    ctx.fill();

    // Draw line
    ctx.beginPath();
    ctx.moveTo(points[0].x, points[0].y);
    points.forEach((p) => ctx.lineTo(p.x, p.y));
    ctx.strokeStyle = lineColor;
    ctx.lineWidth = 2;
    ctx.stroke();

    // Draw X-axis labels (dates)
    ctx.fillStyle = '#9CA3AF';
    ctx.font = '11px system-ui';
    ctx.textAlign = 'center';
    const labelCount = Math.min(6, data.length);
    for (let i = 0; i < labelCount; i++) {
      const idx = Math.floor((i / (labelCount - 1)) * (data.length - 1));
      const point = points[idx];
      const date = new Date(data[idx].date);
      const label = `${date.getDate()}/${date.getMonth() + 1}`;
      ctx.fillText(label, point.x, chartHeight - 10);
    }

    // Draw hovered point
    if (hoveredPoint) {
      const idx = data.findIndex((d) => d.date === hoveredPoint.date);
      if (idx >= 0) {
        const point = points[idx];
        ctx.beginPath();
        ctx.arc(point.x, point.y, 6, 0, Math.PI * 2);
        ctx.fillStyle = lineColor;
        ctx.fill();
        ctx.strokeStyle = '#fff';
        ctx.lineWidth = 2;
        ctx.stroke();

        // Vertical line
        ctx.beginPath();
        ctx.moveTo(point.x, padding.top);
        ctx.lineTo(point.x, chartHeight - padding.bottom);
        ctx.strokeStyle = 'rgba(156, 163, 175, 0.5)';
        ctx.lineWidth = 1;
        ctx.setLineDash([4, 4]);
        ctx.stroke();
        ctx.setLineDash([]);
      }
    }
  };

  const handleMouseMove = (e: React.MouseEvent<HTMLCanvasElement>) => {
    const canvas = canvasRef.current;
    if (!canvas || data.length === 0) return;

    const rect = canvas.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const padding = { left: 60, right: 20 };
    const chartWidth = rect.width - padding.left - padding.right;

    if (x < padding.left || x > rect.width - padding.right) {
      setHoveredPoint(null);
      return;
    }

    const relativeX = (x - padding.left) / chartWidth;
    const idx = Math.round(relativeX * (data.length - 1));
    const point = data[Math.max(0, Math.min(idx, data.length - 1))];
    setHoveredPoint(point);
  };

  const handleMouseLeave = () => {
    setHoveredPoint(null);
  };

  const totalChange = data.length > 0 ? data[data.length - 1].value - data[0].value : 0;
  const totalChangePercent = data.length > 0 && data[0].value > 0
    ? ((data[data.length - 1].value - data[0].value) / data[0].value) * 100
    : 0;

  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl shadow-lg p-6">
      {/* Header */}
      <div className="flex items-center justify-between mb-4">
        <div>
          <h3 className="font-bold text-gray-900 dark:text-white">Rendimiento</h3>
          {data.length > 0 && (
            <div className="flex items-center gap-2 mt-1">
              <span
                className={`text-lg font-bold ${
                  totalChange >= 0 ? 'text-green-500' : 'text-red-500'
                }`}
              >
                {totalChange >= 0 ? '+' : ''}${totalChange.toLocaleString(undefined, {
                  minimumFractionDigits: 2,
                  maximumFractionDigits: 2,
                })}
              </span>
              <span
                className={`text-sm ${
                  totalChangePercent >= 0 ? 'text-green-500' : 'text-red-500'
                }`}
              >
                ({totalChangePercent >= 0 ? '+' : ''}{totalChangePercent.toFixed(2)}%)
              </span>
            </div>
          )}
        </div>
        <div className="flex gap-1">
          {PERIOD_OPTIONS.map((option) => (
            <button
              key={option.value}
              onClick={() => setPeriod(option.value)}
              className={`px-3 py-1 rounded text-sm font-medium transition-colors ${
                period === option.value
                  ? 'bg-blue-600 text-white'
                  : 'bg-gray-100 dark:bg-gray-700 text-gray-600 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600'
              }`}
            >
              {option.label}
            </button>
          ))}
        </div>
      </div>

      {/* Hovered point info */}
      {hoveredPoint && (
        <div className="mb-2 p-2 bg-gray-50 dark:bg-gray-700 rounded-lg text-sm">
          <div className="flex justify-between">
            <span className="text-gray-500 dark:text-gray-400">{hoveredPoint.date}</span>
            <span className="font-medium text-gray-900 dark:text-white">
              ${hoveredPoint.value.toLocaleString(undefined, { minimumFractionDigits: 2 })}
            </span>
          </div>
          <div className="flex justify-between text-xs mt-1">
            <span className="text-gray-500 dark:text-gray-400">Cambio diario</span>
            <span className={hoveredPoint.change >= 0 ? 'text-green-500' : 'text-red-500'}>
              {hoveredPoint.change >= 0 ? '+' : ''}
              {hoveredPoint.changePercent.toFixed(2)}%
            </span>
          </div>
        </div>
      )}

      {/* Chart */}
      {loading ? (
        <div className="flex items-center justify-center" style={{ height }}>
          <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
        </div>
      ) : (
        <canvas
          ref={canvasRef}
          style={{ width: '100%', height }}
          onMouseMove={handleMouseMove}
          onMouseLeave={handleMouseLeave}
          className="cursor-crosshair"
        />
      )}
    </div>
  );
};

export default PerformanceChart;
