import { useState, useEffect, lazy, Suspense } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  LineChart, Line, ScatterChart, Scatter,
  XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, Cell
} from 'recharts';
import { Terminal } from 'lucide-react';
import { useOptimizationWebSocket } from '../hooks/useWebSocket';
import { apiClient } from '../api/client';
import { useStudy } from '../context/StudyContext';
import { Card } from '../components/common/Card';
import { MetricCard } from '../components/dashboard/MetricCard';
import { ControlPanel } from '../components/dashboard/ControlPanel';
import { ClaudeTerminal } from '../components/ClaudeTerminal';
import { ParetoPlot } from '../components/ParetoPlot';
import { ParallelCoordinatesPlot } from '../components/ParallelCoordinatesPlot';
import { ParameterImportanceChart } from '../components/ParameterImportanceChart';
import { ConvergencePlot } from '../components/ConvergencePlot';
import { StudyReportViewer } from '../components/StudyReportViewer';
import { ConsoleOutput } from '../components/ConsoleOutput';
import { ExpandableChart } from '../components/ExpandableChart';
import type { Trial, ConvergenceDataPoint, ParameterSpaceDataPoint } from '../types';

// Lazy load Plotly components for better initial load performance
const PlotlyParallelCoordinates = lazy(() => import('../components/plotly/PlotlyParallelCoordinates').then(m => ({ default: m.PlotlyParallelCoordinates })));
const PlotlyParetoPlot = lazy(() => import('../components/plotly/PlotlyParetoPlot').then(m => ({ default: m.PlotlyParetoPlot })));
const PlotlyConvergencePlot = lazy(() => import('../components/plotly/PlotlyConvergencePlot').then(m => ({ default: m.PlotlyConvergencePlot })));
const PlotlyParameterImportance = lazy(() => import('../components/plotly/PlotlyParameterImportance').then(m => ({ default: m.PlotlyParameterImportance })));

// Loading placeholder for lazy components
const ChartLoading = () => (
  <div className="flex items-center justify-center h-64 text-dark-400">
    <div className="animate-pulse">Loading chart...</div>
  </div>
);

export default function Dashboard() {
  const navigate = useNavigate();
  const { selectedStudy, refreshStudies } = useStudy();
  const selectedStudyId = selectedStudy?.id || null;

  // Redirect to home if no study selected
  useEffect(() => {
    if (!selectedStudy) {
      navigate('/');
    }
  }, [selectedStudy, navigate]);

  const [allTrials, setAllTrials] = useState<Trial[]>([]);
  const [displayedTrials, setDisplayedTrials] = useState<Trial[]>([]);
  const [bestValue, setBestValue] = useState<number>(Infinity);
  const [prunedCount, setPrunedCount] = useState<number>(0);
  const [alerts, setAlerts] = useState<Array<{ id: number; type: 'success' | 'warning'; message: string }>>([]);
  const [alertIdCounter, setAlertIdCounter] = useState(0);
  const [expandedTrials, setExpandedTrials] = useState<Set<number>>(new Set());
  const [sortBy, setSortBy] = useState<'performance' | 'chronological'>('performance');

  // Parameter Space axis selection
  const [paramXIndex, setParamXIndex] = useState(0);
  const [paramYIndex, setParamYIndex] = useState(1);

  // Protocol 13: New state for metadata and Pareto front
  const [studyMetadata, setStudyMetadata] = useState<any>(null);
  const [paretoFront, setParetoFront] = useState<any[]>([]);
  const [allTrialsRaw, setAllTrialsRaw] = useState<any[]>([]); // All trials for parallel coordinates

  // Chart library toggle: 'recharts' (faster) or 'plotly' (more interactive but slower)
  const [chartLibrary, setChartLibrary] = useState<'plotly' | 'recharts'>('recharts');

  // Claude chat panel state
  const [chatOpen, setChatOpen] = useState(false);
  const [chatExpanded, setChatExpanded] = useState(false);

  const showAlert = (type: 'success' | 'warning', message: string) => {
    const id = alertIdCounter;
    setAlertIdCounter(prev => prev + 1);
    setAlerts(prev => [...prev, { id, type, message }]);
    setTimeout(() => {
      setAlerts(prev => prev.filter(a => a.id !== id));
    }, 5000);
  };

  // WebSocket connection
  const { connectionStatus: _connectionStatus } = useOptimizationWebSocket({
    studyId: selectedStudyId,
    onMessage: (msg) => {
      if (msg.type === 'trial_completed') {
        const trial = msg.data as Trial;
        setAllTrials(prev => [...prev, trial]);
        if (trial.objective !== null && trial.objective !== undefined && trial.objective < bestValue) {
          setBestValue(trial.objective);
          showAlert('success', `New best: ${trial.objective.toFixed(4)} (Trial #${trial.trial_number})`);
        }
      } else if (msg.type === 'trial_pruned') {
        setPrunedCount(prev => prev + 1);
        showAlert('warning', `Trial pruned: ${msg.data.pruning_cause}`);
      }
    }
  });

  // Load initial trial history when study changes
  useEffect(() => {
    if (selectedStudyId) {
      setAllTrials([]);
      setBestValue(Infinity);
      setPrunedCount(0);
      setExpandedTrials(new Set());

      apiClient.getStudyHistory(selectedStudyId)
        .then(data => {
          const validTrials = data.trials.filter(t => t.objective !== null && t.objective !== undefined);
          setAllTrials(validTrials);
          if (validTrials.length > 0) {
            const minObj = Math.min(...validTrials.map(t => t.objective));
            setBestValue(minObj);
          }
        })
        .catch(console.error);

      apiClient.getStudyPruning(selectedStudyId)
        .then(data => {
          // Use count if available (new API), fallback to array length (legacy)
          setPrunedCount(data.count ?? data.pruned_trials?.length ?? 0);
        })
        .catch(console.error);

      // Protocol 13: Fetch metadata
      fetch(`/api/optimization/studies/${selectedStudyId}/metadata`)
        .then(res => res.json())
        .then(data => {
          setStudyMetadata(data);
        })
        .catch(err => console.error('Failed to load metadata:', err));

      // Protocol 13: Fetch Pareto front (raw format for Protocol 13 components)
      fetch(`/api/optimization/studies/${selectedStudyId}/pareto-front`)
        .then(res => res.json())
        .then(paretoData => {
          console.log('[Dashboard] Pareto front data:', paretoData);
          if (paretoData.is_multi_objective && paretoData.pareto_front) {
            console.log('[Dashboard] Setting Pareto front with', paretoData.pareto_front.length, 'trials');
            setParetoFront(paretoData.pareto_front);
          } else {
            console.log('[Dashboard] No Pareto front or not multi-objective');
            setParetoFront([]);
          }
        })
        .catch(err => console.error('Failed to load Pareto front:', err));

      // Fetch ALL trials (not just Pareto) for parallel coordinates and charts
      fetch(`/api/optimization/studies/${selectedStudyId}/history`)
        .then(res => res.json())
        .then(data => {
          // Transform to match the format expected by charts
          // API returns 'objectives' (array) for multi-objective, 'objective' (number) for single
          const trialsData = data.trials.map((t: any) => {
            // Build values array: use objectives if available, otherwise wrap single objective
            let values: number[] = [];
            if (t.objectives && Array.isArray(t.objectives)) {
              values = t.objectives;
            } else if (t.objective !== null && t.objective !== undefined) {
              values = [t.objective];
            }

            return {
              trial_number: t.trial_number,
              values,
              params: t.design_variables || {},
              user_attrs: t.user_attrs || {},
              constraint_satisfied: t.constraint_satisfied !== false,
              source: t.source || t.user_attrs?.source || 'FEA'  // FEA vs NN differentiation
            };
          });
          setAllTrialsRaw(trialsData);
        })
        .catch(err => console.error('Failed to load all trials:', err));
    }
  }, [selectedStudyId]);

  // Sort trials based on selected sort order
  useEffect(() => {
    let sorted = [...allTrials];
    if (sortBy === 'performance') {
      // Sort by objective (best first)
      sorted.sort((a, b) => {
        const aObj = a.objective ?? Infinity;
        const bObj = b.objective ?? Infinity;
        return aObj - bObj;
      });
    } else {
      // Chronological (newest first)
      sorted.sort((a, b) => b.trial_number - a.trial_number);
    }
    setDisplayedTrials(sorted);
  }, [allTrials, sortBy]);

  // Auto-refresh polling (every 3 seconds) for trial history
  useEffect(() => {
    if (!selectedStudyId) return;

    const refreshInterval = setInterval(() => {
      apiClient.getStudyHistory(selectedStudyId)
        .then(data => {
          const validTrials = data.trials.filter(t => t.objective !== null && t.objective !== undefined);
          setAllTrials(validTrials);
          if (validTrials.length > 0) {
            const minObj = Math.min(...validTrials.map(t => t.objective));
            setBestValue(minObj);
          }
        })
        .catch(err => console.error('Auto-refresh failed:', err));
    }, 3000); // Poll every 3 seconds

    return () => clearInterval(refreshInterval);
  }, [selectedStudyId]);

  // Prepare chart data with proper null/undefined handling
  const convergenceData: ConvergenceDataPoint[] = allTrials
    .filter(t => t.objective !== null && t.objective !== undefined)
    .sort((a, b) => a.trial_number - b.trial_number)
    .map((trial, idx, arr) => {
      const previousTrials = arr.slice(0, idx + 1);
      const validObjectives = previousTrials.map(t => t.objective).filter(o => o !== null && o !== undefined);
      return {
        trial_number: trial.trial_number,
        objective: trial.objective,
        best_so_far: validObjectives.length > 0 ? Math.min(...validObjectives) : trial.objective,
      };
    });

  const parameterSpaceData: ParameterSpaceDataPoint[] = allTrials
    .filter(t => t.objective !== null && t.objective !== undefined && t.design_variables)
    .map(trial => {
      const params = Object.values(trial.design_variables);
      return {
        trial_number: trial.trial_number,
        x: params[paramXIndex] || 0,
        y: params[paramYIndex] || 0,
        objective: trial.objective,
        isBest: trial.objective === bestValue,
      };
    });

  // Calculate average objective
  const validObjectives = allTrials.filter(t => t.objective !== null && t.objective !== undefined).map(t => t.objective);
  const avgObjective = validObjectives.length > 0
    ? validObjectives.reduce((sum, obj) => sum + obj, 0) / validObjectives.length
    : 0;

  // Get parameter names
  const paramNames = allTrials.length > 0 && allTrials[0].design_variables
    ? Object.keys(allTrials[0].design_variables)
    : [];

  // Toggle trial expansion
  const toggleTrialExpansion = (trialNumber: number) => {
    setExpandedTrials(prev => {
      const newSet = new Set(prev);
      if (newSet.has(trialNumber)) {
        newSet.delete(trialNumber);
      } else {
        newSet.add(trialNumber);
      }
      return newSet;
    });
  };

  // Export functions
  const exportJSON = () => {
    if (allTrials.length === 0) return;
    const data = JSON.stringify(allTrials, null, 2);
    const blob = new Blob([data], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `${selectedStudyId}_trials.json`;
    a.click();
    URL.revokeObjectURL(url);
    showAlert('success', 'JSON exported successfully!');
  };

  const exportCSV = () => {
    if (allTrials.length === 0) return;
    const headers = ['trial_number', 'objective', ...paramNames].join(',');
    const rows = allTrials.map(t => [
      t.trial_number,
      t.objective,
      ...paramNames.map(k => t.design_variables?.[k] ?? '')
    ].join(','));
    const csv = [headers, ...rows].join('\n');
    const blob = new Blob([csv], { type: 'text/csv' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `${selectedStudyId}_trials.csv`;
    a.click();
    URL.revokeObjectURL(url);
    showAlert('success', 'CSV exported successfully!');
  };

  return (
    <div className="w-full max-w-[2400px] mx-auto px-4">
      {/* Alerts */}
      <div className="fixed top-4 right-4 z-50 space-y-2">
        {alerts.map(alert => (
          <div
            key={alert.id}
            className={`px-4 py-3 rounded-lg shadow-lg transition-all duration-300 ${
              alert.type === 'success'
                ? 'bg-green-900 border-l-4 border-green-400 text-green-100'
                : 'bg-yellow-900 border-l-4 border-yellow-400 text-yellow-100'
            }`}
          >
            {alert.message}
          </div>
        ))}
      </div>

      {/* Header */}
      <header className="mb-8 flex items-center justify-between border-b border-dark-600 pb-4">
        <div>
          <h1 className="text-3xl font-bold text-primary-400">Live Dashboard</h1>
          <p className="text-dark-300 mt-1">Real-time optimization monitoring</p>
        </div>
        <div className="flex gap-2">
          {/* Claude Code Terminal Toggle Button */}
          <button
            onClick={() => setChatOpen(!chatOpen)}
            className={`flex items-center gap-2 px-4 py-2 rounded-lg transition-colors ${
              chatOpen
                ? 'bg-primary-600 text-white'
                : 'bg-dark-700 text-dark-200 hover:bg-dark-600 hover:text-white border border-dark-600'
            }`}
            title="Open Claude Code terminal"
          >
            <Terminal className="w-4 h-4" />
            <span className="hidden sm:inline">Claude Code</span>
          </button>
          {selectedStudyId && (
            <StudyReportViewer studyId={selectedStudyId} />
          )}
          <button
            onClick={() => {
              // Open Optuna dashboard on port 8081
              // Note: The dashboard needs to be started separately with the correct study database
              window.open('http://localhost:8081', '_blank');
            }}
            className="btn-secondary"
            title="Open Optuna Dashboard (runs on port 8081)"
          >
            Optuna Dashboard
          </button>
          <button onClick={exportJSON} className="btn-secondary" disabled={allTrials.length === 0}>
            Export JSON
          </button>
          <button onClick={exportCSV} className="btn-secondary" disabled={allTrials.length === 0}>
            Export CSV
          </button>
          {/* Chart library toggle */}
          <div className="flex rounded-lg overflow-hidden border border-dark-500 ml-2">
            <button
              onClick={() => setChartLibrary('plotly')}
              className={`px-3 py-1.5 text-sm transition-colors ${
                chartLibrary === 'plotly'
                  ? 'bg-primary-500 text-white'
                  : 'bg-dark-600 text-dark-200 hover:bg-dark-500'
              }`}
              title="Interactive Plotly charts with zoom, pan, and export"
            >
              Plotly
            </button>
            <button
              onClick={() => setChartLibrary('recharts')}
              className={`px-3 py-1.5 text-sm transition-colors ${
                chartLibrary === 'recharts'
                  ? 'bg-primary-500 text-white'
                  : 'bg-dark-600 text-dark-200 hover:bg-dark-500'
              }`}
              title="Simple Recharts visualization"
            >
              Simple
            </button>
          </div>
        </div>
      </header>

      <div className="grid grid-cols-12 gap-6">
        {/* Control Panel - Left Sidebar */}
        <aside className="col-span-3">
          <ControlPanel onStatusChange={refreshStudies} />
        </aside>

        {/* Main Content - shrinks when chat is open */}
        <main className={chatOpen ? 'col-span-5' : 'col-span-9'}>
          {/* Study Name Header */}
          {selectedStudyId && (
            <div className="mb-4 pb-3 border-b border-dark-600">
              <h2 className="text-xl font-semibold text-primary-300">
                {selectedStudyId}
              </h2>
              {studyMetadata?.description && (
                <p className="text-sm text-dark-400 mt-1">{studyMetadata.description}</p>
              )}
            </div>
          )}

          {/* Metrics Grid */}
          <div className="grid grid-cols-4 gap-4 mb-6">
            <MetricCard label="Total Trials" value={allTrials.length} />
            <MetricCard
              label="Best Value"
              value={bestValue === Infinity ? '-' : bestValue.toFixed(4)}
              valueColor="text-green-400"
            />
            <MetricCard
              label="Avg Objective"
              value={avgObjective > 0 ? avgObjective.toFixed(4) : '-'}
              valueColor="text-blue-400"
            />
            <MetricCard
              label="Pruned"
              value={prunedCount}
              valueColor={prunedCount > 0 ? 'text-red-400' : 'text-green-400'}
            />
          </div>

          {/* Protocol 13: Intelligent Optimizer & Pareto Front */}
          {selectedStudyId && paretoFront.length > 0 && studyMetadata && studyMetadata.objectives && (
            <div className="grid grid-cols-2 gap-6 mb-6">
              <Card title="Optimizer Strategy">
                <div className="space-y-2">
                  <div className="text-sm text-dark-300">
                    <span className="font-semibold text-dark-100">Algorithm:</span> {studyMetadata.sampler || 'NSGA-II'}
                  </div>
                  <div className="text-sm text-dark-300">
                    <span className="font-semibold text-dark-100">Type:</span> Multi-objective
                  </div>
                  <div className="text-sm text-dark-300">
                    <span className="font-semibold text-dark-100">Objectives:</span> {studyMetadata.objectives?.length || 2}
                  </div>
                  <div className="text-sm text-dark-300">
                    <span className="font-semibold text-dark-100">Design Variables:</span> {studyMetadata.design_variables?.length || 0}
                  </div>
                </div>
              </Card>
              <ExpandableChart
                title="Pareto Front"
                subtitle={`${paretoFront.length} Pareto-optimal solutions`}
              >
                {chartLibrary === 'plotly' ? (
                  <Suspense fallback={<ChartLoading />}>
                    <PlotlyParetoPlot
                      trials={allTrialsRaw}
                      paretoFront={paretoFront}
                      objectives={studyMetadata.objectives}
                      height={350}
                    />
                  </Suspense>
                ) : (
                  <ParetoPlot
                    paretoData={paretoFront}
                    objectives={studyMetadata.objectives}
                    allTrials={allTrialsRaw}
                  />
                )}
              </ExpandableChart>
            </div>
          )}

          {/* Parallel Coordinates (full width for multi-objective) */}
          {allTrialsRaw.length > 0 && studyMetadata && studyMetadata.objectives && studyMetadata.design_variables && (
            <div className="mb-6">
              <ExpandableChart
                title="Parallel Coordinates Plot"
                subtitle={`${allTrialsRaw.length} trials - Design Variables → Objectives`}
              >
                {chartLibrary === 'plotly' ? (
                  <Suspense fallback={<ChartLoading />}>
                    <PlotlyParallelCoordinates
                      trials={allTrialsRaw}
                      objectives={studyMetadata.objectives}
                      designVariables={studyMetadata.design_variables}
                      paretoFront={paretoFront}
                      height={450}
                    />
                  </Suspense>
                ) : (
                  <ParallelCoordinatesPlot
                    paretoData={allTrialsRaw}
                    objectives={studyMetadata.objectives}
                    designVariables={studyMetadata.design_variables}
                    paretoFront={paretoFront}
                  />
                )}
              </ExpandableChart>
            </div>
          )}

          {/* Convergence Plot - Full Width */}
          {allTrialsRaw.length > 0 && (
            <div className="mb-6">
              <ExpandableChart
                title="Convergence Plot"
                subtitle={`Best ${studyMetadata?.objectives?.[0]?.name || 'Objective'} over ${allTrialsRaw.length} trials`}
              >
                {chartLibrary === 'plotly' ? (
                  <Suspense fallback={<ChartLoading />}>
                    <PlotlyConvergencePlot
                      trials={allTrialsRaw}
                      objectiveIndex={0}
                      objectiveName={studyMetadata?.objectives?.[0]?.name || 'Objective'}
                      direction="minimize"
                      height={350}
                    />
                  </Suspense>
                ) : (
                  <ConvergencePlot
                    trials={allTrialsRaw}
                    objectiveIndex={0}
                    objectiveName={studyMetadata?.objectives?.[0]?.name || 'Objective'}
                    direction="minimize"
                  />
                )}
              </ExpandableChart>
            </div>
          )}

          {/* Parameter Importance - Full Width */}
          {allTrialsRaw.length > 0 && (studyMetadata?.design_variables?.length > 0 || (allTrialsRaw[0]?.params && Object.keys(allTrialsRaw[0].params).length > 0)) && (
            <div className="mb-6">
              <ExpandableChart
                title="Parameter Importance"
                subtitle={`Correlation with ${studyMetadata?.objectives?.[0]?.name || 'Objective'}`}
              >
                {chartLibrary === 'plotly' ? (
                  <Suspense fallback={<ChartLoading />}>
                    <PlotlyParameterImportance
                      trials={allTrialsRaw}
                      designVariables={
                        studyMetadata?.design_variables?.length > 0
                          ? studyMetadata.design_variables
                          : Object.keys(allTrialsRaw[0]?.params || {}).map(name => ({ name }))
                      }
                      objectiveIndex={0}
                      objectiveName={studyMetadata?.objectives?.[0]?.name || 'Objective'}
                      height={350}
                    />
                  </Suspense>
                ) : (
                  <ParameterImportanceChart
                    trials={allTrialsRaw}
                    designVariables={
                      studyMetadata?.design_variables?.length > 0
                        ? studyMetadata.design_variables
                        : Object.keys(allTrialsRaw[0]?.params || {}).map(name => ({ name }))
                    }
                    objectiveIndex={0}
                    objectiveName={studyMetadata?.objectives?.[0]?.name || 'Objective'}
                  />
                )}
              </ExpandableChart>
            </div>
          )}

          {/* Charts */}
          <div className="grid grid-cols-2 gap-6 mb-6">
            {/* Convergence Chart */}
            <ExpandableChart
              title="Convergence Plot (Single Objective)"
              subtitle={`${convergenceData.length} trials`}
            >
              <Card title="Convergence Plot">
                {convergenceData.length > 0 ? (
                  <ResponsiveContainer width="100%" height={300}>
                    <LineChart data={convergenceData}>
                      <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
                      <XAxis
                        dataKey="trial_number"
                        stroke="#94a3b8"
                        label={{ value: 'Trial Number', position: 'insideBottom', offset: -5, fill: '#94a3b8' }}
                      />
                      <YAxis
                        stroke="#94a3b8"
                        label={{ value: 'Objective', angle: -90, position: 'insideLeft', fill: '#94a3b8' }}
                      />
                      <Tooltip
                        contentStyle={{ backgroundColor: '#1e293b', border: 'none', borderRadius: '8px' }}
                        labelStyle={{ color: '#e2e8f0' }}
                      />
                      <Legend />
                      <Line
                        type="monotone"
                        dataKey="objective"
                        stroke="#60a5fa"
                        name="Objective"
                        dot={{ r: 3 }}
                      />
                      <Line
                        type="monotone"
                        dataKey="best_so_far"
                        stroke="#10b981"
                        name="Best So Far"
                        strokeWidth={2}
                        dot={{ r: 4 }}
                      />
                    </LineChart>
                  </ResponsiveContainer>
                ) : (
                  <div className="h-64 flex items-center justify-center text-dark-300">
                    No trial data yet
                  </div>
                )}
              </Card>
            </ExpandableChart>

            {/* Parameter Space Chart with Selectable Axes */}
            <ExpandableChart
              title="Parameter Space"
              subtitle={`${parameterSpaceData.length} trials - ${paramNames[paramXIndex] || 'X'} vs ${paramNames[paramYIndex] || 'Y'}`}
            >
              <Card title={
                <div className="flex items-center justify-between w-full">
                  <span>Parameter Space</span>
                  {paramNames.length > 2 && (
                    <div className="flex items-center gap-2 text-sm">
                      <span className="text-dark-400">X:</span>
                      <select
                        value={paramXIndex}
                        onChange={(e) => setParamXIndex(Number(e.target.value))}
                        className="bg-dark-600 text-dark-100 px-2 py-1 rounded text-xs border border-dark-500"
                      >
                        {paramNames.map((name, idx) => (
                          <option key={idx} value={idx}>{name}</option>
                        ))}
                      </select>
                      <span className="text-dark-400">Y:</span>
                      <select
                        value={paramYIndex}
                        onChange={(e) => setParamYIndex(Number(e.target.value))}
                        className="bg-dark-600 text-dark-100 px-2 py-1 rounded text-xs border border-dark-500"
                      >
                        {paramNames.map((name, idx) => (
                          <option key={idx} value={idx}>{name}</option>
                        ))}
                      </select>
                    </div>
                  )}
                </div>
              }>
                {parameterSpaceData.length > 0 ? (
                  <ResponsiveContainer width="100%" height={300}>
                    <ScatterChart>
                      <CartesianGrid strokeDasharray="3 3" stroke="#334155" />
                      <XAxis
                        type="number"
                        dataKey="x"
                        stroke="#94a3b8"
                        name={paramNames[paramXIndex] || 'X'}
                        label={{ value: paramNames[paramXIndex] || 'Parameter X', position: 'insideBottom', offset: -5, fill: '#94a3b8' }}
                      />
                      <YAxis
                        type="number"
                        dataKey="y"
                        stroke="#94a3b8"
                        name={paramNames[paramYIndex] || 'Y'}
                        label={{ value: paramNames[paramYIndex] || 'Parameter Y', angle: -90, position: 'insideLeft', fill: '#94a3b8' }}
                      />
                      <Tooltip
                        cursor={{ strokeDasharray: '3 3' }}
                        contentStyle={{ backgroundColor: '#1e293b', border: 'none', borderRadius: '8px' }}
                        labelStyle={{ color: '#e2e8f0' }}
                        formatter={(value: any, name: string) => {
                          if (name === 'objective') return [value.toFixed(4), 'Objective'];
                          return [value.toFixed(3), name];
                        }}
                      />
                      <Scatter name="Trials" data={parameterSpaceData}>
                        {parameterSpaceData.map((entry, index) => (
                          <Cell
                            key={`cell-${index}`}
                            fill={entry.isBest ? '#10b981' : '#60a5fa'}
                            r={entry.isBest ? 8 : 5}
                          />
                        ))}
                      </Scatter>
                    </ScatterChart>
                  </ResponsiveContainer>
                ) : (
                  <div className="h-64 flex items-center justify-center text-dark-300">
                    No trial data yet
                  </div>
                )}
              </Card>
            </ExpandableChart>
          </div>

          {/* Trial History with Sort Controls */}
          <Card
            title={
              <div className="flex items-center justify-between w-full">
                <span>Trial History ({displayedTrials.length} trials)</span>
                <div className="flex gap-2">
                  <button
                    onClick={() => setSortBy('performance')}
                    className={`px-3 py-1 rounded text-sm ${
                      sortBy === 'performance'
                        ? 'bg-primary-500 text-white'
                        : 'bg-dark-500 text-dark-200 hover:bg-dark-400'
                    }`}
                  >
                    Best First
                  </button>
                  <button
                    onClick={() => setSortBy('chronological')}
                    className={`px-3 py-1 rounded text-sm ${
                      sortBy === 'chronological'
                        ? 'bg-primary-500 text-white'
                        : 'bg-dark-500 text-dark-200 hover:bg-dark-400'
                    }`}
                  >
                    Newest First
                  </button>
                </div>
              </div>
            }
          >
            <div className="space-y-2 max-h-[600px] overflow-y-auto">
              {displayedTrials.length > 0 ? (
                displayedTrials.map(trial => {
                  const isExpanded = expandedTrials.has(trial.trial_number);
                  const isBest = trial.objective === bestValue;

                  return (
                    <div
                      key={trial.trial_number}
                      className={`rounded-lg transition-all duration-200 cursor-pointer ${
                        isBest
                          ? 'bg-green-900 border-l-4 border-green-400'
                          : 'bg-dark-500 hover:bg-dark-400'
                      }`}
                      onClick={() => toggleTrialExpansion(trial.trial_number)}
                    >
                      {/* Collapsed View */}
                      <div className="p-3">
                        <div className="flex justify-between items-center">
                          <span className="font-semibold text-primary-400">
                            Trial #{trial.trial_number}
                            {isBest && <span className="ml-2 text-xs bg-green-700 text-green-100 px-2 py-1 rounded">BEST</span>}
                          </span>
                          <div className="flex items-center gap-3">
                            <span className={`font-mono text-lg ${
                              isBest ? 'text-green-400 font-bold' : 'text-dark-100'
                            }`}>
                              {trial.objective !== null && trial.objective !== undefined
                                ? trial.objective.toFixed(4)
                                : 'N/A'}
                            </span>
                            <span className="text-dark-400 text-sm">
                              {isExpanded ? '▼' : '▶'}
                            </span>
                          </div>
                        </div>

                        {/* Quick Preview - Show ALL metrics */}
                        {!isExpanded && trial.results && Object.keys(trial.results).length > 0 && (
                          <div className="text-xs text-primary-300 flex flex-wrap gap-3 mt-2">
                            {Object.entries(trial.results).slice(0, 6).map(([key, val]) => {
                              // Format value based on type
                              const formatValue = (v: unknown): string => {
                                if (typeof v === 'number') {
                                  // Use fewer decimals for quick preview
                                  return Math.abs(v) < 0.01 ? v.toExponential(2) : v.toFixed(2);
                                }
                                if (Array.isArray(v)) return `[${v.length}]`;
                                return String(v);
                              };
                              // Format key: snake_case to Title Case, abbreviate long names
                              const formatKey = (k: string): string => {
                                const short = k.replace(/_/g, ' ')
                                  .replace(/rel /g, 'Δ')
                                  .replace(/filtered rms/g, 'fRMS')
                                  .replace(/global rms/g, 'gRMS')
                                  .replace(/ vs /g, '/')
                                  .replace(/mfg /g, '')
                                  .replace(/optician workload/g, 'work');
                                return short.length > 15 ? short.slice(0, 12) + '...' : short;
                              };
                              return (
                                <span key={key} title={`${key}: ${val}`}>
                                  {formatKey(key)}: {formatValue(val)}
                                </span>
                              );
                            })}
                            {Object.keys(trial.results).length > 6 && (
                              <span className="text-dark-400">+{Object.keys(trial.results).length - 6} more</span>
                            )}
                          </div>
                        )}
                      </div>

                      {/* Expanded View */}
                      {isExpanded && (
                        <div className="px-3 pb-3 space-y-3">
                          {/* Design Variables */}
                          {trial.design_variables && Object.keys(trial.design_variables).length > 0 && (
                            <div className="border-t border-dark-400 pt-3">
                              <h4 className="text-sm font-semibold text-dark-200 mb-2">Design Variables</h4>
                              <div className="grid grid-cols-2 gap-2 text-xs">
                                {Object.entries(trial.design_variables).map(([key, val]) => (
                                  <div key={key} className="flex justify-between bg-dark-600 px-2 py-1 rounded">
                                    <span className="text-dark-300">{key}:</span>
                                    <span className="text-dark-100 font-mono">{val.toFixed(4)}</span>
                                  </div>
                                ))}
                              </div>
                            </div>
                          )}

                          {/* Results */}
                          {trial.results && Object.keys(trial.results).length > 0 && (
                            <div className="border-t border-dark-400 pt-3">
                              <h4 className="text-sm font-semibold text-dark-200 mb-2">Extracted Results</h4>
                              <div className="grid grid-cols-2 gap-2 text-xs">
                                {Object.entries(trial.results).map(([key, val]) => (
                                  <div key={key} className="flex justify-between bg-dark-600 px-2 py-1 rounded">
                                    <span className="text-dark-300">{key}:</span>
                                    <span className="text-primary-300 font-mono">
                                      {typeof val === 'number' ? val.toFixed(4) : String(val)}
                                    </span>
                                  </div>
                                ))}
                              </div>
                            </div>
                          )}

                          {/* All User Attributes */}
                          {trial.user_attrs && Object.keys(trial.user_attrs).length > 0 && (
                            <div className="border-t border-dark-400 pt-3">
                              <h4 className="text-sm font-semibold text-dark-200 mb-2">All Attributes</h4>
                              <div className="max-h-48 overflow-y-auto">
                                <pre className="text-xs text-dark-300 bg-dark-700 p-2 rounded">
                                  {JSON.stringify(trial.user_attrs, null, 2)}
                                </pre>
                              </div>
                            </div>
                          )}

                          {/* Timestamps */}
                          {trial.start_time && trial.end_time && (
                            <div className="border-t border-dark-400 pt-3 text-xs text-dark-400">
                              <div className="flex justify-between">
                                <span>Duration:</span>
                                <span>
                                  {((new Date(trial.end_time).getTime() - new Date(trial.start_time).getTime()) / 1000).toFixed(1)}s
                                </span>
                              </div>
                            </div>
                          )}
                        </div>
                      )}
                    </div>
                  );
                })
              ) : (
                <div className="text-center py-8 text-dark-300">
                  No trials yet. Waiting for optimization to start...
                </div>
              )}
            </div>
          </Card>

          {/* Console Output - at the bottom */}
          <div className="mt-6">
            <ConsoleOutput
              studyId={selectedStudyId}
              refreshInterval={2000}
              maxLines={200}
            />
          </div>
        </main>

        {/* Claude Code Terminal - Right Sidebar */}
        {chatOpen && (
          <aside className="col-span-4 h-[calc(100vh-12rem)] sticky top-24">
            <ClaudeTerminal
              isExpanded={chatExpanded}
              onToggleExpand={() => setChatExpanded(!chatExpanded)}
              onClose={() => setChatOpen(false)}
            />
          </aside>
        )}
      </div>
    </div>
  );
}
