/**
 * LossChart & ProgressRing Components
 *
 * SVG-based visualizations for training metrics:
 * - LossChart: Line chart for training/validation loss curves
 * - ProgressRing: Circular progress indicator
 */

'use client'

import type { TrainingDataPoint } from './training-metrics-types'

/**
 * Simple line chart component for loss visualization
 */
export function LossChart({
  data,
  height = 200,
  className = ''
}: {
  data: TrainingDataPoint[]
  height?: number
  className?: string
}) {
  if (data.length === 0) {
    return (
      <div className={`flex items-center justify-center bg-slate-50 rounded-lg ${className}`} style={{ height }}>
        <span className="text-slate-400 text-sm">Keine Daten</span>
      </div>
    )
  }

  // Calculate bounds
  const losses = data.map(d => d.loss)
  const valLosses = data.filter(d => d.val_loss !== undefined).map(d => d.val_loss!)
  const allLosses = [...losses, ...valLosses]
  const minLoss = Math.min(...allLosses) * 0.9
  const maxLoss = Math.max(...allLosses) * 1.1
  const lossRange = maxLoss - minLoss || 1

  // SVG dimensions
  const width = 400
  const padding = { top: 20, right: 20, bottom: 30, left: 50 }
  const chartWidth = width - padding.left - padding.right
  const chartHeight = height - padding.top - padding.bottom

  // Generate path for loss line
  const generatePath = (values: number[]) => {
    if (values.length === 0) return ''
    return values
      .map((loss, idx) => {
        const x = padding.left + (idx / (values.length - 1 || 1)) * chartWidth
        const y = padding.top + chartHeight - ((loss - minLoss) / lossRange) * chartHeight
        return `${idx === 0 ? 'M' : 'L'} ${x} ${y}`
      })
      .join(' ')
  }

  const lossPath = generatePath(losses)
  const valLossPath = valLosses.length > 0 ? generatePath(valLosses) : ''

  // Y-axis labels
  const yLabels = [maxLoss, (maxLoss + minLoss) / 2, minLoss].map(v => v.toFixed(3))

  return (
    <svg viewBox={`0 0 ${width} ${height}`} className={`w-full ${className}`} preserveAspectRatio="xMidYMid meet">
      {/* Grid lines */}
      {[0, 0.5, 1].map((ratio, idx) => (
        <line
          key={idx}
          x1={padding.left}
          y1={padding.top + chartHeight * ratio}
          x2={width - padding.right}
          y2={padding.top + chartHeight * ratio}
          stroke="#e2e8f0"
          strokeWidth="1"
        />
      ))}

      {/* Y-axis labels */}
      {yLabels.map((label, idx) => (
        <text
          key={idx}
          x={padding.left - 5}
          y={padding.top + (idx / 2) * chartHeight + 4}
          textAnchor="end"
          className="fill-slate-500 text-xs"
        >
          {label}
        </text>
      ))}

      {/* X-axis label */}
      <text
        x={width / 2}
        y={height - 5}
        textAnchor="middle"
        className="fill-slate-500 text-xs"
      >
        Epoche / Schritt
      </text>

      {/* Y-axis label */}
      <text
        x={12}
        y={height / 2}
        textAnchor="middle"
        className="fill-slate-500 text-xs"
        transform={`rotate(-90, 12, ${height / 2})`}
      >
        Loss
      </text>

      {/* Training loss line */}
      <path
        d={lossPath}
        fill="none"
        stroke="#8b5cf6"
        strokeWidth="2"
        strokeLinecap="round"
        strokeLinejoin="round"
      />

      {/* Validation loss line (dashed) */}
      {valLossPath && (
        <path
          d={valLossPath}
          fill="none"
          stroke="#22c55e"
          strokeWidth="2"
          strokeDasharray="5,5"
          strokeLinecap="round"
          strokeLinejoin="round"
        />
      )}

      {/* Data points */}
      {data.map((point, idx) => {
        const x = padding.left + (idx / (data.length - 1 || 1)) * chartWidth
        const y = padding.top + chartHeight - ((point.loss - minLoss) / lossRange) * chartHeight
        return (
          <circle
            key={idx}
            cx={x}
            cy={y}
            r="3"
            fill="#8b5cf6"
            className="hover:r-4 transition-all"
          >
            <title>Epoch {point.epoch}, Step {point.step}: {point.loss.toFixed(4)}</title>
          </circle>
        )
      })}

      {/* Legend */}
      <g transform={`translate(${padding.left}, ${height - 25})`}>
        <line x1="0" y1="0" x2="20" y2="0" stroke="#8b5cf6" strokeWidth="2" />
        <text x="25" y="4" className="fill-slate-600 text-xs">Training Loss</text>

        {valLossPath && (
          <>
            <line x1="120" y1="0" x2="140" y2="0" stroke="#22c55e" strokeWidth="2" strokeDasharray="5,5" />
            <text x="145" y="4" className="fill-slate-600 text-xs">Val Loss</text>
          </>
        )}
      </g>
    </svg>
  )
}

/**
 * Progress ring component
 */
export function ProgressRing({
  progress,
  size = 80,
  strokeWidth = 6,
  className = ''
}: {
  progress: number
  size?: number
  strokeWidth?: number
  className?: string
}) {
  const radius = (size - strokeWidth) / 2
  const circumference = radius * 2 * Math.PI
  const offset = circumference - (progress / 100) * circumference

  return (
    <svg width={size} height={size} className={className}>
      {/* Background circle */}
      <circle
        cx={size / 2}
        cy={size / 2}
        r={radius}
        fill="none"
        stroke="#e2e8f0"
        strokeWidth={strokeWidth}
      />
      {/* Progress circle */}
      <circle
        cx={size / 2}
        cy={size / 2}
        r={radius}
        fill="none"
        stroke="#8b5cf6"
        strokeWidth={strokeWidth}
        strokeDasharray={circumference}
        strokeDashoffset={offset}
        strokeLinecap="round"
        transform={`rotate(-90 ${size / 2} ${size / 2})`}
        className="transition-all duration-300"
      />
      {/* Center text */}
      <text
        x={size / 2}
        y={size / 2}
        textAnchor="middle"
        dominantBaseline="middle"
        className="fill-slate-900 font-bold text-lg"
      >
        {progress.toFixed(0)}%
      </text>
    </svg>
  )
}
