'use client';

import { useState, useEffect, useCallback } from 'react';

interface TrainingRun {
  run_id: string;
  model_type: string;
  status: string;
  created_at: string;
  metrics_summary?: {
    f1_macro?: number;
    accuracy?: number;
    test_f1_macro?: number;
    test_accuracy?: number;
    [key: string]: number | undefined;
  };
}

interface ModelSelectorProps {
  currentModelVersion: string | null | undefined;
  onModelLoaded: () => void;
  onLoadError: (msg: string) => void;
  onLoadStart: () => void;
  disabled?: boolean;
}

function formatDate(iso: string): string {
  try {
    return new Date(iso).toLocaleString(undefined, {
      month: 'short',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit',
    });
  } catch {
    return iso;
  }
}

export default function ModelSelector({
  currentModelVersion,
  onModelLoaded,
  onLoadError,
  onLoadStart,
  disabled = false,
}: ModelSelectorProps) {
  const [runs, setRuns] = useState<TrainingRun[]>([]);
  const [isLoadingRuns, setIsLoadingRuns] = useState(false);
  const [isLoadingModel, setIsLoadingModel] = useState(false);
  const [selectedRunId, setSelectedRunId] = useState<string>('');

  const fetchRuns = useCallback(async () => {
    setIsLoadingRuns(true);
    try {
      const res = await fetch('/api/training/runs');
      if (!res.ok) return;
      const data = await res.json();
      const runList: TrainingRun[] = (data.runs || data).filter(
        (r: TrainingRun) => r.status === 'completed'
      );
      setRuns(runList);
    } catch {
      // ignore
    } finally {
      setIsLoadingRuns(false);
    }
  }, []);

  useEffect(() => {
    fetchRuns();
  }, [fetchRuns]);

  const handleChange = async (runId: string) => {
    if (!runId || isLoadingModel) return;
    setSelectedRunId(runId);
    setIsLoadingModel(true);
    onLoadStart();

    try {
      const res = await fetch('/api/model/load', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ run_id: runId }),
      });

      if (!res.ok) {
        const data = await res.json();
        throw new Error(data.error || data.detail || 'Failed to load model');
      }

      onModelLoaded();
    } catch (e) {
      setSelectedRunId(''); // revert selection
      onLoadError(e instanceof Error ? e.message : 'Failed to load model');
    } finally {
      setIsLoadingModel(false);
    }
  };

  if (isLoadingRuns) {
    return <p className="text-[10px] text-muted-foreground">Loading models...</p>;
  }

  if (runs.length === 0) {
    return (
      <p className="text-[10px] text-muted-foreground italic">No trained models available</p>
    );
  }

  return (
    <div>
      <label className="text-[10px] text-muted-foreground block mb-0.5">Switch Model</label>
      <select
        value={selectedRunId}
        onChange={(e) => handleChange(e.target.value)}
        disabled={disabled || isLoadingModel}
        className="w-full text-[10px] bg-secondary text-foreground rounded px-1.5 py-1 border-0 outline-none disabled:opacity-50"
      >
        <option value="">
          {isLoadingModel ? 'Loading...' : '— select a model —'}
        </option>
        {runs.map((run) => {
          const f1 = run.metrics_summary?.f1_macro ?? run.metrics_summary?.test_f1_macro;
          const label = [
            run.model_type.replace('_', ' '),
            formatDate(run.created_at),
            f1 !== undefined ? `F1:${(f1 * 100).toFixed(0)}%` : null,
          ]
            .filter(Boolean)
            .join(' · ');
          return (
            <option key={run.run_id} value={run.run_id}>
              {label}
            </option>
          );
        })}
      </select>
    </div>
  );
}
