import Papa from 'papaparse';
import { CalibrationDataPoint, CalibrationMetrics } from '@/types/calibration';

export function parseCalibrationCSV(csvContent: string): CalibrationDataPoint[] {
  const result = Papa.parse<CalibrationDataPoint>(csvContent, {
    header: true,
    dynamicTyping: true,
    skipEmptyLines: true,
  });

  if (result.errors.length > 0) {
    throw new Error(`CSV parsing error: ${result.errors[0].message}`);
  }

  return result.data.filter(row => 
    row.epoch !== undefined && 
    row.loss !== undefined && 
    row.target_name !== undefined
  );
}

export function getCalibrationMetrics(data: CalibrationDataPoint[]): CalibrationMetrics {
  if (data.length === 0) {
    return {
      epochCount: 0,
      targetNames: [],
      finalLoss: 0,
    };
  }

  const epochs = [...new Set(data.map(d => d.epoch))].sort((a, b) => a - b);
  const targetNames = [...new Set(data.map(d => d.target_name))];
  const finalEpoch = Math.max(...epochs);
  const finalLoss = data.find(d => d.epoch === finalEpoch)?.loss || 0;

  // Find convergence epoch (when loss stops decreasing significantly)
  let convergenceEpoch: number | undefined;
  const lossByEpoch = epochs.map(epoch => {
    const epochData = data.find(d => d.epoch === epoch);
    return { epoch, loss: epochData?.loss || 0 };
  });

  for (let i = 1; i < lossByEpoch.length; i++) {
    const currentLoss = lossByEpoch[i].loss;
    const prevLoss = lossByEpoch[i - 1].loss;
    const improvement = (prevLoss - currentLoss) / prevLoss;
    
    if (improvement < 0.001) { // Less than 0.1% improvement
      convergenceEpoch = lossByEpoch[i].epoch;
      break;
    }
  }

  return {
    epochCount: epochs.length,
    targetNames,
    finalLoss,
    convergenceEpoch,
  };
}