/**
 * PlotlyParallelCoordinates - Interactive parallel coordinates plot using Plotly
 *
 * Features:
 * - Native zoom, pan, and selection
 * - Hover tooltips with trial details
 * - Brush filtering on each axis
 * - FEA vs NN color differentiation
 * - Export to PNG/SVG
 */

import { useMemo } from 'react';
import Plot from 'react-plotly.js';

interface Trial {
  trial_number: number;
  values: number[];
  params: Record<string, number>;
  user_attrs?: Record<string, any>;
  constraint_satisfied?: boolean;
  source?: 'FEA' | 'NN' | 'V10_FEA';
}

interface Objective {
  name: string;
  direction?: 'minimize' | 'maximize';
  unit?: string;
}

interface DesignVariable {
  name: string;
  unit?: string;
  min?: number;
  max?: number;
}

interface PlotlyParallelCoordinatesProps {
  trials: Trial[];
  objectives: Objective[];
  designVariables: DesignVariable[];
  paretoFront?: Trial[];
  height?: number;
}

export function PlotlyParallelCoordinates({
  trials,
  objectives,
  designVariables,
  paretoFront = [],
  height = 500
}: PlotlyParallelCoordinatesProps) {
  // Create set of Pareto front trial numbers
  const paretoSet = useMemo(() => new Set(paretoFront.map(t => t.trial_number)), [paretoFront]);

  // Build dimensions array for parallel coordinates
  const { dimensions, colorValues, colorScale } = useMemo(() => {
    if (!trials.length) return { dimensions: [], colorValues: [], colorScale: [] };

    const dims: any[] = [];
    const colors: number[] = [];

    // Get all design variable names
    const dvNames = designVariables.map(dv => dv.name);
    const objNames = objectives.map(obj => obj.name);

    // Add design variable dimensions
    dvNames.forEach((name, idx) => {
      const dv = designVariables[idx];
      const values = trials.map(t => t.params[name] ?? 0);
      const validValues = values.filter(v => v !== null && v !== undefined && isFinite(v));

      if (validValues.length === 0) return;

      dims.push({
        label: name,
        values: values,
        range: [
          dv?.min ?? Math.min(...validValues),
          dv?.max ?? Math.max(...validValues)
        ],
        constraintrange: undefined
      });
    });

    // Add objective dimensions
    objNames.forEach((name, idx) => {
      const obj = objectives[idx];
      const values = trials.map(t => {
        // Try to get from values array first, then user_attrs
        if (t.values && t.values[idx] !== undefined) {
          return t.values[idx];
        }
        return t.user_attrs?.[name] ?? 0;
      });
      const validValues = values.filter(v => v !== null && v !== undefined && isFinite(v));

      if (validValues.length === 0) return;

      dims.push({
        label: `${name}${obj.unit ? ` (${obj.unit})` : ''}`,
        values: values,
        range: [Math.min(...validValues) * 0.95, Math.max(...validValues) * 1.05]
      });
    });

    // Build color array: 0 = V10_FEA, 1 = FEA, 2 = NN, 3 = Pareto
    trials.forEach(t => {
      const source = t.source || t.user_attrs?.source || 'FEA';
      const isPareto = paretoSet.has(t.trial_number);

      if (isPareto) {
        colors.push(3); // Pareto - special color
      } else if (source === 'NN') {
        colors.push(2); // NN trials
      } else if (source === 'V10_FEA') {
        colors.push(0); // V10 FEA
      } else {
        colors.push(1); // V11 FEA
      }
    });

    // Color scale: V10_FEA (light blue), FEA (blue), NN (orange), Pareto (green)
    const scale: [number, string][] = [
      [0, '#93C5FD'],      // V10_FEA - light blue
      [0.33, '#2563EB'],   // FEA - blue
      [0.66, '#F97316'],   // NN - orange
      [1, '#10B981']       // Pareto - green
    ];

    return { dimensions: dims, colorValues: colors, colorScale: scale };
  }, [trials, objectives, designVariables, paretoSet]);

  if (!trials.length || dimensions.length === 0) {
    return (
      <div className="flex items-center justify-center h-64 text-gray-500">
        No trial data available for parallel coordinates
      </div>
    );
  }

  // Count trial types for legend
  const feaCount = trials.filter(t => {
    const source = t.source || t.user_attrs?.source || 'FEA';
    return source === 'FEA' || source === 'V10_FEA';
  }).length;
  const nnCount = trials.filter(t => {
    const source = t.source || t.user_attrs?.source || 'FEA';
    return source === 'NN';
  }).length;

  return (
    <div className="w-full">
      {/* Legend */}
      <div className="flex gap-4 justify-center mb-2 text-sm">
        <div className="flex items-center gap-1.5">
          <div className="w-4 h-1 rounded" style={{ backgroundColor: '#2563EB' }} />
          <span className="text-gray-600">FEA ({feaCount})</span>
        </div>
        <div className="flex items-center gap-1.5">
          <div className="w-4 h-1 rounded" style={{ backgroundColor: '#F97316' }} />
          <span className="text-gray-600">NN ({nnCount})</span>
        </div>
        {paretoFront.length > 0 && (
          <div className="flex items-center gap-1.5">
            <div className="w-4 h-1 rounded" style={{ backgroundColor: '#10B981' }} />
            <span className="text-gray-600">Pareto ({paretoFront.length})</span>
          </div>
        )}
      </div>

      <Plot
        data={[
          {
            type: 'parcoords',
            line: {
              color: colorValues,
              colorscale: colorScale as any,
              showscale: false
            },
            dimensions: dimensions,
            labelangle: -30,
            labelfont: {
              size: 11,
              color: '#374151'
            },
            tickfont: {
              size: 10,
              color: '#6B7280'
            }
          } as any
        ]}
        layout={{
          height: height,
          margin: { l: 80, r: 80, t: 30, b: 30 },
          paper_bgcolor: 'rgba(0,0,0,0)',
          plot_bgcolor: 'rgba(0,0,0,0)',
          font: {
            family: 'Inter, system-ui, sans-serif'
          }
        }}
        config={{
          displayModeBar: true,
          displaylogo: false,
          modeBarButtonsToRemove: ['lasso2d', 'select2d'],
          toImageButtonOptions: {
            format: 'png',
            filename: 'parallel_coordinates',
            height: 800,
            width: 1400,
            scale: 2
          }
        }}
        style={{ width: '100%' }}
      />

      <p className="text-xs text-gray-500 text-center mt-2">
        Drag along axes to filter. Double-click to reset.
      </p>
    </div>
  );
}
