/**
 * ConvergenceSparkline - Tiny SVG chart showing optimization convergence
 * 
 * Displays the last N trial values as a mini line chart.
 * Used on ObjectiveNode to show convergence trend.
 */

import { useMemo } from 'react';

interface ConvergenceSparklineProps {
  /** Array of values (most recent last) */
  values: number[];
  /** Width in pixels */
  width?: number;
  /** Height in pixels */
  height?: number;
  /** Line color */
  color?: string;
  /** Best value line color */
  bestColor?: string;
  /** Whether to show the best value line */
  showBest?: boolean;
  /** Direction: minimize shows lower as better, maximize shows higher as better */
  direction?: 'minimize' | 'maximize';
  /** Show dots at each point */
  showDots?: boolean;
  /** Number of points to display */
  maxPoints?: number;
}

export function ConvergenceSparkline({
  values,
  width = 80,
  height = 24,
  color = '#60a5fa',
  bestColor = '#34d399',
  showBest = true,
  direction = 'minimize',
  showDots = false,
  maxPoints = 20,
}: ConvergenceSparklineProps) {
  const { path, bestY, points } = useMemo(() => {
    if (!values || values.length === 0) {
      return { path: '', bestY: null, points: [], minVal: 0, maxVal: 1 };
    }

    // Take last N points
    const data = values.slice(-maxPoints);
    if (data.length === 0) {
      return { path: '', bestY: null, points: [], minVal: 0, maxVal: 1 };
    }

    // Calculate bounds with padding
    const minVal = Math.min(...data);
    const maxVal = Math.max(...data);
    const range = maxVal - minVal || 1;
    const padding = range * 0.1;
    const yMin = minVal - padding;
    const yMax = maxVal + padding;
    const yRange = yMax - yMin;

    // Calculate best value
    const bestVal = direction === 'minimize' ? Math.min(...data) : Math.max(...data);

    // Map values to SVG coordinates
    const xStep = width / Math.max(data.length - 1, 1);
    const mapY = (v: number) => height - ((v - yMin) / yRange) * height;

    // Build path
    const points = data.map((v, i) => ({
      x: i * xStep,
      y: mapY(v),
      value: v,
    }));

    const pathParts = points.map((p, i) => 
      i === 0 ? `M ${p.x} ${p.y}` : `L ${p.x} ${p.y}`
    );

    return {
      path: pathParts.join(' '),
      bestY: mapY(bestVal),
      points,
      minVal,
      maxVal,
    };
  }, [values, width, height, maxPoints, direction]);

  if (!values || values.length === 0) {
    return (
      <div 
        className="flex items-center justify-center text-dark-500 text-xs"
        style={{ width, height }}
      >
        No data
      </div>
    );
  }

  return (
    <svg 
      width={width} 
      height={height} 
      className="overflow-visible"
      viewBox={`0 0 ${width} ${height}`}
    >
      {/* Best value line */}
      {showBest && bestY !== null && (
        <line
          x1={0}
          y1={bestY}
          x2={width}
          y2={bestY}
          stroke={bestColor}
          strokeWidth={1}
          strokeDasharray="2,2"
          opacity={0.5}
        />
      )}

      {/* Main line */}
      <path
        d={path}
        fill="none"
        stroke={color}
        strokeWidth={1.5}
        strokeLinecap="round"
        strokeLinejoin="round"
      />

      {/* Gradient fill under the line */}
      <defs>
        <linearGradient id="sparkline-gradient" x1="0%" y1="0%" x2="0%" y2="100%">
          <stop offset="0%" stopColor={color} stopOpacity={0.3} />
          <stop offset="100%" stopColor={color} stopOpacity={0} />
        </linearGradient>
      </defs>
      
      {points.length > 1 && (
        <path
          d={`${path} L ${points[points.length - 1].x} ${height} L ${points[0].x} ${height} Z`}
          fill="url(#sparkline-gradient)"
        />
      )}

      {/* Dots at each point */}
      {showDots && points.map((p, i) => (
        <circle
          key={i}
          cx={p.x}
          cy={p.y}
          r={2}
          fill={color}
        />
      ))}

      {/* Last point highlight */}
      {points.length > 0 && (
        <circle
          cx={points[points.length - 1].x}
          cy={points[points.length - 1].y}
          r={3}
          fill={color}
          stroke="white"
          strokeWidth={1}
        />
      )}
    </svg>
  );
}

/**
 * ProgressRing - Circular progress indicator
 */
interface ProgressRingProps {
  /** Progress percentage (0-100) */
  progress: number;
  /** Size in pixels */
  size?: number;
  /** Stroke width */
  strokeWidth?: number;
  /** Progress color */
  color?: string;
  /** Background color */
  bgColor?: string;
  /** Show percentage text */
  showText?: boolean;
}

export function ProgressRing({
  progress,
  size = 32,
  strokeWidth = 3,
  color = '#60a5fa',
  bgColor = '#374151',
  showText = true,
}: ProgressRingProps) {
  const radius = (size - strokeWidth) / 2;
  const circumference = radius * 2 * Math.PI;
  const offset = circumference - (Math.min(100, Math.max(0, progress)) / 100) * circumference;

  return (
    <div className="relative inline-flex items-center justify-center" style={{ width: size, height: size }}>
      <svg width={size} height={size} className="transform -rotate-90">
        {/* Background circle */}
        <circle
          cx={size / 2}
          cy={size / 2}
          r={radius}
          fill="none"
          stroke={bgColor}
          strokeWidth={strokeWidth}
        />
        {/* Progress circle */}
        <circle
          cx={size / 2}
          cy={size / 2}
          r={radius}
          fill="none"
          stroke={color}
          strokeWidth={strokeWidth}
          strokeDasharray={circumference}
          strokeDashoffset={offset}
          strokeLinecap="round"
          className="transition-all duration-300"
        />
      </svg>
      {showText && (
        <span 
          className="absolute text-xs font-medium"
          style={{ color, fontSize: size * 0.25 }}
        >
          {Math.round(progress)}%
        </span>
      )}
    </div>
  );
}

export default ConvergenceSparkline;
