/**
 * Introspection Panel - Shows discovered expressions and extractors from NX model
 */

import { useState, useEffect, useCallback, useMemo } from 'react';
import {
  X,
  Search,
  RefreshCw,
  Plus,
  ChevronDown,
  ChevronRight,
  FileBox,
  Cpu,
  FlaskConical,
  SlidersHorizontal,
  AlertTriangle,
  Scale,
  Link,
  Box,
  Settings2,
  GitBranch,
  File,
  Database,
  CheckCircle2,
} from 'lucide-react';
import { useCanvasStore } from '../../../hooks/useCanvasStore';

interface IntrospectionPanelProps {
  filePath: string;
  studyId?: string;
  onClose: () => void;
}

interface Expression {
  name: string;
  value: number;
  rhs?: string;
  min?: number;
  max?: number;
  unit?: string;
  units?: string;  // API returns 'units' not 'unit'
  type: string;
  source?: string;
}

interface Extractor {
  id: string;
  name: string;
  description?: string;
  always?: boolean;
}

interface DependentFile {
  path: string;
  type: string;
  name: string;
}

// File dependency structure from backend
interface FileDependencies {
  files: {
    sim: string[];
    afm: string[];
    fem: string[];
    prt: string[];
    idealized: string[];
  };
  dependencies: Array<{
    source: string;
    target: string;
    type: string;
  }>;
  root_sim: string | null;
}

// The API returns expressions in a nested structure
interface ExpressionsResult {
  user: Expression[];
  internal: Expression[];
  total_count: number;
  user_count: number;
}

interface IntrospectionResult {
  part_file?: string;
  part_path?: string;
  file_path?: string;
  file_type?: string;
  success?: boolean;
  error?: string | null;
  // Expressions can be either an array (old format) or object with user/internal (new format)
  expressions: Expression[] | ExpressionsResult;
  solver_type?: string | null;
  dependent_files?: DependentFile[];
  extractors_available?: Extractor[];
  warnings?: string[];
  // Additional fields from NX introspection
  mass_properties?: Record<string, unknown>;
  materials?: Record<string, unknown>;
  bodies?: Record<string, unknown>;
  attributes?: Array<{ title: string; value: string }>;
  units?: Record<string, unknown>;
  linked_parts?: Record<string, unknown>;
  file_dependencies?: FileDependencies;
  existing_fea_results?: {
    has_results: boolean;
    sources: Array<{
      location: string;
      path: string;
      op2: string[];
      f06: string[];
      bdf: string[];
      timestamp?: number;
    }>;
    recommended?: {
      location: string;
      path: string;
      op2: string[];
    };
  };
}

// Baseline run result interface
interface BaselineRunResult {
  success: boolean;
  study_id: string;
  baseline_dir: string;
  sim_file?: string;
  elapsed_time?: number;
  result_files?: {
    op2: string[];
    f06: string[];
    bdf: string[];
  };
  errors?: string[];
  error?: string;
  message: string;
}

// Part info from /nx/parts endpoint
interface PartInfo {
  name: string;
  stem: string;
  is_idealized: boolean;
  size_kb: number;
  has_cache: boolean;
}

export function IntrospectionPanel({ filePath, studyId, onClose }: IntrospectionPanelProps) {
  const [result, setResult] = useState<IntrospectionResult | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [expandedSections, setExpandedSections] = useState<Set<string>>(
    new Set(['expressions', 'extractors', 'file_deps', 'fea_results'])
  );
  const [searchTerm, setSearchTerm] = useState('');
  
  // Part selection state
  const [availableParts, setAvailableParts] = useState<PartInfo[]>([]);
  const [selectedPart, setSelectedPart] = useState<string>(''); // empty = default/assembly
  const [isLoadingParts, setIsLoadingParts] = useState(false);
  
  // Baseline run state
  const [isRunningBaseline, setIsRunningBaseline] = useState(false);
  const [baselineResult, setBaselineResult] = useState<BaselineRunResult | null>(null);

  const { addNode, nodes } = useCanvasStore();

  // Fetch available parts when studyId changes
  const fetchAvailableParts = useCallback(async () => {
    if (!studyId) return;
    
    setIsLoadingParts(true);
    try {
      const res = await fetch(`/api/optimization/studies/${studyId}/nx/parts`);
      if (res.ok) {
        const data = await res.json();
        setAvailableParts(data.parts || []);
      }
    } catch (e) {
      console.error('Failed to fetch parts:', e);
    } finally {
      setIsLoadingParts(false);
    }
  }, [studyId]);

  const runIntrospection = useCallback(async (partName?: string) => {
    if (!filePath && !studyId) return;

    setIsLoading(true);
    setError(null);
    try {
      let res;
      
      // If we have a studyId, use the study-aware introspection endpoint
      if (studyId) {
        // Use specific part endpoint if a part is selected
        const endpoint = partName 
          ? `/api/optimization/studies/${studyId}/nx/introspect/${encodeURIComponent(partName)}`
          : `/api/optimization/studies/${studyId}/nx/introspect`;
        res = await fetch(endpoint);
      } else {
        // Fallback to direct path introspection
        res = await fetch('/api/nx/introspect', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ file_path: filePath }),
        });
      }
      
      if (!res.ok) {
        const errData = await res.json().catch(() => ({}));
        throw new Error(errData.detail || 'Introspection failed');
      }
      const data = await res.json();
      
      // Handle different response formats
      setResult(data.introspection || data);
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Failed to introspect model';
      setError(msg);
      console.error('Introspection error:', e);
    } finally {
      setIsLoading(false);
    }
  }, [filePath, studyId]);

  // Fetch parts list on mount
  useEffect(() => {
    fetchAvailableParts();
  }, [fetchAvailableParts]);

  // Run introspection when component mounts or selected part changes
  useEffect(() => {
    runIntrospection(selectedPart || undefined);
  }, [selectedPart]); // eslint-disable-line react-hooks/exhaustive-deps
  
  // Handle part selection change
  const handlePartChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
    const newPart = e.target.value;
    setSelectedPart(newPart);
  };

  // Run baseline FEA simulation
  const runBaseline = useCallback(async () => {
    if (!studyId) {
      setError('Study ID required to run baseline');
      return;
    }

    setIsRunningBaseline(true);
    setBaselineResult(null);
    setError(null);
    
    try {
      const res = await fetch(`/api/optimization/studies/${studyId}/nx/run-baseline`, {
        method: 'POST',
      });
      
      const data = await res.json();
      setBaselineResult(data);
      
      if (!data.success && data.error) {
        setError(`Baseline run failed: ${data.error}`);
      }
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Failed to run baseline';
      setError(msg);
      console.error('Baseline run error:', e);
    } finally {
      setIsRunningBaseline(false);
    }
  }, [studyId]);

  const toggleSection = (section: string) => {
    setExpandedSections((prev) => {
      const next = new Set(prev);
      if (next.has(section)) next.delete(section);
      else next.add(section);
      return next;
    });
  };

  const addExpressionAsDesignVar = (expr: Expression) => {
    // Find a good position (left of model node)
    const modelNode = nodes.find((n) => n.data.type === 'model');
    const existingDvars = nodes.filter((n) => n.data.type === 'designVar');

    const position = {
      x: (modelNode?.position.x || 300) - 250,
      y: (modelNode?.position.y || 100) + existingDvars.length * 100,
    };

    // Calculate min/max based on value if not provided
    const minValue = expr.min ?? expr.value * 0.5;
    const maxValue = expr.max ?? expr.value * 1.5;

    addNode('designVar', position, {
      label: expr.name,
      expressionName: expr.name,
      minValue,
      maxValue,
      unit: expr.unit,
      configured: true,
    });
  };

  const addExtractorNode = (extractor: Extractor) => {
    // Find a good position (right of solver node)
    const solverNode = nodes.find((n) => n.data.type === 'solver');
    const existingExtractors = nodes.filter((n) => n.data.type === 'extractor');

    const position = {
      x: (solverNode?.position.x || 400) + 200,
      y: (solverNode?.position.y || 100) + existingExtractors.length * 100,
    };

    addNode('extractor', position, {
      label: extractor.name,
      extractorId: extractor.id,
      extractorName: extractor.name,
      configured: true,
    });
  };

  // Handle both array format (old) and object format (new API)
  const allExpressions: Expression[] = useMemo(() => {
    if (!result?.expressions) return [];
    
    // Check if expressions is an array (old format) or object (new format)
    if (Array.isArray(result.expressions)) {
      return result.expressions;
    }
    
    // New format: { user: [...], internal: [...] }
    const exprObj = result.expressions as ExpressionsResult;
    return [...(exprObj.user || []), ...(exprObj.internal || [])];
  }, [result?.expressions]);

  const filteredExpressions = allExpressions.filter((e) =>
    e.name.toLowerCase().includes(searchTerm.toLowerCase())
  );

  return (
    <div className="bg-dark-850 border border-dark-700 rounded-xl w-80 max-h-[70vh] flex flex-col shadow-xl">
      {/* Header */}
      <div className="flex items-center justify-between px-4 py-3 border-b border-dark-700">
        <div className="flex items-center gap-2">
          <Search size={16} className="text-primary-400" />
          <span className="font-medium text-white text-sm">
            Model Introspection
            {selectedPart && <span className="text-primary-400 ml-1">({selectedPart})</span>}
          </span>
        </div>
        <div className="flex items-center gap-1">
          <button
            onClick={() => runIntrospection(selectedPart || undefined)}
            disabled={isLoading}
            className="p-1.5 text-dark-400 hover:text-white hover:bg-dark-700 rounded transition-colors"
            title="Refresh"
          >
            <RefreshCw size={14} className={isLoading ? 'animate-spin' : ''} />
          </button>
          <button
            onClick={onClose}
            className="p-1.5 text-dark-400 hover:text-white hover:bg-dark-700 rounded transition-colors"
          >
            <X size={14} />
          </button>
        </div>
      </div>

      {/* Part Selector + Search */}
      <div className="px-4 py-2 border-b border-dark-700 space-y-2">
        {/* Part dropdown */}
        {studyId && availableParts.length > 0 && (
          <div className="flex items-center gap-2">
            <label className="text-xs text-dark-400 whitespace-nowrap">Part:</label>
            <select
              value={selectedPart}
              onChange={handlePartChange}
              disabled={isLoading || isLoadingParts}
              className="flex-1 px-2 py-1.5 bg-dark-800 border border-dark-600 rounded-lg
                         text-sm text-white focus:outline-none focus:border-primary-500
                         disabled:opacity-50"
            >
              <option value="">Default (Assembly)</option>
              {availableParts
                .filter(p => !p.is_idealized) // Hide idealized parts
                .map(part => (
                  <option key={part.name} value={part.stem}>
                    {part.stem} ({part.size_kb > 1000 ? `${(part.size_kb/1024).toFixed(1)}MB` : `${part.size_kb}KB`})
                  </option>
                ))
              }
            </select>
            {isLoadingParts && (
              <RefreshCw size={12} className="animate-spin text-dark-400" />
            )}
          </div>
        )}
        
        {/* Search input */}
        <input
          type="text"
          placeholder="Filter expressions..."
          value={searchTerm}
          onChange={(e) => setSearchTerm(e.target.value)}
          className="w-full px-3 py-1.5 bg-dark-800 border border-dark-600 rounded-lg
                     text-sm text-white placeholder-dark-500 focus:outline-none focus:border-primary-500"
        />
      </div>

      {/* Run Baseline Button */}
      {studyId && (
        <div className="px-4 py-2 border-b border-dark-700">
          <button
            onClick={runBaseline}
            disabled={isRunningBaseline}
            className="w-full flex items-center justify-center gap-2 px-3 py-2 
                       bg-emerald-600 hover:bg-emerald-500 disabled:bg-dark-700 
                       text-white disabled:text-dark-400 text-sm font-medium 
                       rounded-lg transition-colors"
          >
            {isRunningBaseline ? (
              <>
                <RefreshCw size={14} className="animate-spin" />
                Running Baseline FEA...
              </>
            ) : (
              <>
                <Cpu size={14} />
                Run Baseline Simulation
              </>
            )}
          </button>
          <p className="text-xs text-dark-500 mt-1.5 text-center">
            Creates result files (.op2, .f06) for testing extractors
          </p>
        </div>
      )}

      {/* Baseline Run Result */}
      {baselineResult && (
        <div className={`mx-2 my-2 p-3 rounded-lg border ${
          baselineResult.success 
            ? 'bg-emerald-500/10 border-emerald-500/30' 
            : 'bg-red-500/10 border-red-500/30'
        }`}>
          <div className="flex items-center gap-2 mb-2">
            {baselineResult.success ? (
              <div className="w-2 h-2 rounded-full bg-emerald-400" />
            ) : (
              <AlertTriangle size={14} className="text-red-400" />
            )}
            <span className={`text-xs font-medium ${
              baselineResult.success ? 'text-emerald-400' : 'text-red-400'
            }`}>
              {baselineResult.message}
            </span>
          </div>
          
          {baselineResult.elapsed_time && (
            <p className="text-xs text-dark-400 mb-1">
              Completed in {baselineResult.elapsed_time.toFixed(1)}s
            </p>
          )}
          
          {baselineResult.result_files && (
            <div className="space-y-1">
              {baselineResult.result_files.op2.length > 0 && (
                <p className="text-xs text-dark-300">
                  <span className="text-emerald-400">OP2:</span> {baselineResult.result_files.op2.join(', ')}
                </p>
              )}
              {baselineResult.result_files.f06.length > 0 && (
                <p className="text-xs text-dark-300">
                  <span className="text-blue-400">F06:</span> {baselineResult.result_files.f06.join(', ')}
                </p>
              )}
              {baselineResult.result_files.bdf.length > 0 && (
                <p className="text-xs text-dark-300">
                  <span className="text-amber-400">BDF:</span> {baselineResult.result_files.bdf.join(', ')}
                </p>
              )}
            </div>
          )}
          
          {baselineResult.error && (
            <p className="text-xs text-red-400 mt-1">{baselineResult.error}</p>
          )}
        </div>
      )}

      {/* Content */}
      <div className="flex-1 overflow-auto">
        {isLoading ? (
          <div className="flex items-center justify-center h-32 text-dark-500">
            <RefreshCw size={20} className="animate-spin mr-2" />
            Analyzing model...
          </div>
        ) : error ? (
          <div className="p-4 text-red-400 text-sm">{error}</div>
        ) : result ? (
          <div className="p-2 space-y-2">
            {/* Solver Type */}
            {result.solver_type && (
              <div className="p-2 bg-dark-800 rounded-lg">
                <div className="flex items-center gap-2 text-sm">
                  <Cpu size={14} className="text-violet-400" />
                  <span className="text-dark-300">Solver:</span>
                  <span className="text-white font-medium">{result.solver_type}</span>
                </div>
              </div>
            )}

            {/* Expressions Section */}
            <div className="border border-dark-700 rounded-lg overflow-hidden">
              <button
                onClick={() => toggleSection('expressions')}
                className="w-full flex items-center justify-between px-3 py-2 bg-dark-800 hover:bg-dark-750 transition-colors"
              >
                <div className="flex items-center gap-2">
                  <SlidersHorizontal size={14} className="text-emerald-400" />
                  <span className="text-sm font-medium text-white">
                    Expressions ({filteredExpressions.length})
                  </span>
                </div>
                {expandedSections.has('expressions') ? (
                  <ChevronDown size={14} className="text-dark-400" />
                ) : (
                  <ChevronRight size={14} className="text-dark-400" />
                )}
              </button>

              {expandedSections.has('expressions') && (
                <div className="p-2 space-y-1 max-h-48 overflow-y-auto">
                  {filteredExpressions.length === 0 ? (
                    <p className="text-xs text-dark-500 text-center py-2">
                      No expressions found
                    </p>
                  ) : (
                    filteredExpressions.map((expr) => (
                      <div
                        key={expr.name}
                        className="flex items-center justify-between p-2 bg-dark-850 rounded hover:bg-dark-750 group transition-colors"
                      >
                        <div className="flex-1 min-w-0">
                          <p className="text-sm text-white truncate">{expr.name}</p>
                          <p className="text-xs text-dark-500">
                            {expr.value} {expr.units || expr.unit || ''}
                            {expr.source === 'inferred' && (
                              <span className="ml-1 text-amber-500">(inferred)</span>
                            )}
                          </p>
                        </div>
                        <button
                          onClick={() => addExpressionAsDesignVar(expr)}
                          className="p-1.5 text-dark-500 hover:text-primary-400 hover:bg-dark-700 rounded
                                     opacity-0 group-hover:opacity-100 transition-all"
                          title="Add as Design Variable"
                        >
                          <Plus size={14} />
                        </button>
                      </div>
                    ))
                  )}
                </div>
              )}
            </div>

            {/* Mass Properties Section */}
            {result.mass_properties && (
              <div className="border border-dark-700 rounded-lg overflow-hidden">
                <button
                  onClick={() => toggleSection('mass')}
                  className="w-full flex items-center justify-between px-3 py-2 bg-dark-800 hover:bg-dark-750 transition-colors"
                >
                  <div className="flex items-center gap-2">
                    <Scale size={14} className="text-blue-400" />
                    <span className="text-sm font-medium text-white">Mass Properties</span>
                  </div>
                  {expandedSections.has('mass') ? (
                    <ChevronDown size={14} className="text-dark-400" />
                  ) : (
                    <ChevronRight size={14} className="text-dark-400" />
                  )}
                </button>

                {expandedSections.has('mass') && (
                  <div className="p-2 space-y-1">
                    {result.mass_properties.mass_kg !== undefined && (
                      <div className="flex justify-between p-2 bg-dark-850 rounded text-xs">
                        <span className="text-dark-400">Mass</span>
                        <span className="text-white font-mono">
                          {(result.mass_properties.mass_kg as number).toFixed(4)} kg
                        </span>
                      </div>
                    )}
                    {result.mass_properties.volume_mm3 !== undefined && (result.mass_properties.volume_mm3 as number) > 0 && (
                      <div className="flex justify-between p-2 bg-dark-850 rounded text-xs">
                        <span className="text-dark-400">Volume</span>
                        <span className="text-white font-mono">
                          {((result.mass_properties.volume_mm3 as number) / 1e9).toFixed(6)} m³
                        </span>
                      </div>
                    )}
                    {result.mass_properties.surface_area_mm2 !== undefined && (result.mass_properties.surface_area_mm2 as number) > 0 && (
                      <div className="flex justify-between p-2 bg-dark-850 rounded text-xs">
                        <span className="text-dark-400">Surface Area</span>
                        <span className="text-white font-mono">
                          {((result.mass_properties.surface_area_mm2 as number) / 1e6).toFixed(4)} m²
                        </span>
                      </div>
                    )}
                    {Array.isArray(result.mass_properties.center_of_gravity_mm) && (
                      <div className="flex justify-between p-2 bg-dark-850 rounded text-xs">
                        <span className="text-dark-400">CoG (mm)</span>
                        <span className="text-white font-mono text-right">
                          [{(result.mass_properties.center_of_gravity_mm as number[]).map((v: number) => v.toFixed(1)).join(', ')}]
                        </span>
                      </div>
                    )}
                    {typeof result.mass_properties.num_bodies === 'number' && (
                      <div className="flex justify-between p-2 bg-dark-850 rounded text-xs">
                        <span className="text-dark-400">Bodies</span>
                        <span className="text-white font-mono">{result.mass_properties.num_bodies}</span>
                      </div>
                    )}
                  </div>
                )}
              </div>
            )}

            {/* Linked Parts / File Dependencies Section */}
            {result.linked_parts && (
              <div className="border border-dark-700 rounded-lg overflow-hidden">
                <button
                  onClick={() => toggleSection('linked')}
                  className="w-full flex items-center justify-between px-3 py-2 bg-dark-800 hover:bg-dark-750 transition-colors"
                >
                  <div className="flex items-center gap-2">
                    <Link size={14} className="text-purple-400" />
                    <span className="text-sm font-medium text-white">
                      Linked Parts ({(result.linked_parts.loaded_parts as Array<{name: string}>)?.length || 0})
                    </span>
                  </div>
                  {expandedSections.has('linked') ? (
                    <ChevronDown size={14} className="text-dark-400" />
                  ) : (
                    <ChevronRight size={14} className="text-dark-400" />
                  )}
                </button>

                {expandedSections.has('linked') && (
                  <div className="p-2 space-y-1 max-h-48 overflow-y-auto">
                    {((result.linked_parts.loaded_parts as Array<{name: string, path: string, leaf_name: string}>) || []).map((part) => (
                      <div
                        key={part.path}
                        className="p-2 bg-dark-850 rounded"
                      >
                        <p className="text-sm text-white">{part.name}</p>
                        <p className="text-xs text-dark-500 truncate" title={part.path}>
                          {part.leaf_name || part.path.split(/[/\\]/).pop()}
                        </p>
                      </div>
                    ))}
                    {((result.linked_parts.loaded_parts as Array<unknown>) || []).length === 0 && (
                      <p className="text-xs text-dark-500 text-center py-2">No linked parts found</p>
                    )}
                  </div>
                )}
              </div>
            )}

            {/* Bodies Section */}
            {result.bodies && (result.bodies.counts as {total: number})?.total > 0 && (
              <div className="border border-dark-700 rounded-lg overflow-hidden">
                <button
                  onClick={() => toggleSection('bodies')}
                  className="w-full flex items-center justify-between px-3 py-2 bg-dark-800 hover:bg-dark-750 transition-colors"
                >
                  <div className="flex items-center gap-2">
                    <Box size={14} className="text-orange-400" />
                    <span className="text-sm font-medium text-white">
                      Bodies ({(result.bodies.counts as {total: number})?.total || 0})
                    </span>
                  </div>
                  {expandedSections.has('bodies') ? (
                    <ChevronDown size={14} className="text-dark-400" />
                  ) : (
                    <ChevronRight size={14} className="text-dark-400" />
                  )}
                </button>

                {expandedSections.has('bodies') && (
                  <div className="p-2 space-y-1">
                    <div className="flex justify-between p-2 bg-dark-850 rounded text-xs">
                      <span className="text-dark-400">Solid Bodies</span>
                      <span className="text-white font-mono">{(result.bodies.counts as {solid: number})?.solid || 0}</span>
                    </div>
                    <div className="flex justify-between p-2 bg-dark-850 rounded text-xs">
                      <span className="text-dark-400">Sheet Bodies</span>
                      <span className="text-white font-mono">{(result.bodies.counts as {sheet: number})?.sheet || 0}</span>
                    </div>
                  </div>
                )}
              </div>
            )}

            {/* Units Section */}
            {result.units && (
              <div className="border border-dark-700 rounded-lg overflow-hidden">
                <button
                  onClick={() => toggleSection('units')}
                  className="w-full flex items-center justify-between px-3 py-2 bg-dark-800 hover:bg-dark-750 transition-colors"
                >
                  <div className="flex items-center gap-2">
                    <Settings2 size={14} className="text-gray-400" />
                    <span className="text-sm font-medium text-white">
                      Units ({(result.units as {system?: string})?.system || 'Unknown'})
                    </span>
                  </div>
                  {expandedSections.has('units') ? (
                    <ChevronDown size={14} className="text-dark-400" />
                  ) : (
                    <ChevronRight size={14} className="text-dark-400" />
                  )}
                </button>

                {expandedSections.has('units') && (
                  <div className="p-2 space-y-1">
                    {(result.units as {base_units?: Record<string, string>})?.base_units && 
                      Object.entries((result.units as {base_units: Record<string, string>}).base_units).map(([key, value]) => (
                        <div key={key} className="flex justify-between p-2 bg-dark-850 rounded text-xs">
                          <span className="text-dark-400">{key}</span>
                          <span className="text-white font-mono">{value}</span>
                        </div>
                      ))
                    }
                  </div>
                )}
              </div>
            )}

            {/* File Dependencies Section (NX file chain) */}
            {result.file_dependencies && (
              <div className="border border-dark-700 rounded-lg overflow-hidden">
                <button
                  onClick={() => toggleSection('file_deps')}
                  className="w-full flex items-center justify-between px-3 py-2 bg-dark-800 hover:bg-dark-750 transition-colors"
                >
                  <div className="flex items-center gap-2">
                    <GitBranch size={14} className="text-cyan-400" />
                    <span className="text-sm font-medium text-white">
                      File Dependencies ({result.file_dependencies.dependencies?.length || 0} links)
                    </span>
                  </div>
                  {expandedSections.has('file_deps') ? (
                    <ChevronDown size={14} className="text-dark-400" />
                  ) : (
                    <ChevronRight size={14} className="text-dark-400" />
                  )}
                </button>

                {expandedSections.has('file_deps') && (
                  <div className="p-2 space-y-2 max-h-64 overflow-y-auto">
                    {/* Show file tree structure */}
                    {result.file_dependencies.root_sim && (
                      <div className="text-xs">
                        {/* Simulation files */}
                        {result.file_dependencies.files.sim.map((sim) => (
                          <div key={sim} className="ml-0">
                            <div className="flex items-center gap-1 p-1 bg-purple-500/10 rounded text-purple-400">
                              <File size={12} />
                              <span className="font-mono">{sim}</span>
                              <span className="text-purple-500/60 text-[10px]">(.sim)</span>
                            </div>
                            
                            {/* AFM files connected to this SIM */}
                            {result.file_dependencies!.dependencies
                              .filter(d => d.source === sim && d.type === 'sim_to_afm')
                              .map(d => (
                                <div key={d.target} className="ml-4 mt-1">
                                  <div className="flex items-center gap-1 p-1 bg-blue-500/10 rounded text-blue-400">
                                    <File size={12} />
                                    <span className="font-mono">{d.target}</span>
                                    <span className="text-blue-500/60 text-[10px]">(.afm)</span>
                                  </div>
                                  
                                  {/* FEM files connected to this AFM */}
                                  {result.file_dependencies!.dependencies
                                    .filter(d2 => d2.source === d.target && d2.type === 'afm_to_fem')
                                    .map(d2 => (
                                      <div key={d2.target} className="ml-4 mt-1">
                                        <div className="flex items-center gap-1 p-1 bg-green-500/10 rounded text-green-400">
                                          <File size={12} />
                                          <span className="font-mono">{d2.target}</span>
                                          <span className="text-green-500/60 text-[10px]">(.fem)</span>
                                        </div>
                                        
                                        {/* Idealized parts connected to this FEM */}
                                        {result.file_dependencies!.dependencies
                                          .filter(d3 => d3.source === d2.target && d3.type === 'fem_to_idealized')
                                          .map(d3 => (
                                            <div key={d3.target} className="ml-4 mt-1">
                                              <div className="flex items-center gap-1 p-1 bg-yellow-500/10 rounded text-yellow-400">
                                                <File size={12} />
                                                <span className="font-mono">{d3.target}</span>
                                                <span className="text-yellow-500/60 text-[10px]">(_i.prt)</span>
                                              </div>
                                              
                                              {/* Geometry parts */}
                                              {result.file_dependencies!.dependencies
                                                .filter(d4 => d4.source === d3.target && d4.type === 'idealized_to_prt')
                                                .map(d4 => (
                                                  <div key={d4.target} className="ml-4 mt-1">
                                                    <div className="flex items-center gap-1 p-1 bg-orange-500/10 rounded text-orange-400">
                                                      <File size={12} />
                                                      <span className="font-mono">{d4.target}</span>
                                                      <span className="text-orange-500/60 text-[10px]">(.prt)</span>
                                                    </div>
                                                  </div>
                                                ))
                                              }
                                            </div>
                                          ))
                                        }
                                      </div>
                                    ))
                                  }
                                </div>
                              ))
                            }

                            {/* Direct FEM connections (no AFM) */}
                            {result.file_dependencies!.dependencies
                              .filter(d => d.source === sim && d.type === 'sim_to_fem')
                              .map(d => (
                                <div key={d.target} className="ml-4 mt-1">
                                  <div className="flex items-center gap-1 p-1 bg-green-500/10 rounded text-green-400">
                                    <File size={12} />
                                    <span className="font-mono">{d.target}</span>
                                    <span className="text-green-500/60 text-[10px]">(.fem)</span>
                                  </div>
                                </div>
                              ))
                            }
                          </div>
                        ))}
                        
                        {/* Show any orphan PRT files not in the tree */}
                        {result.file_dependencies.files.prt.filter(prt => 
                          !result.file_dependencies!.dependencies.some(d => d.target === prt)
                        ).length > 0 && (
                          <div className="mt-2 pt-2 border-t border-dark-700">
                            <span className="text-dark-500 text-[10px]">Additional geometry files:</span>
                            {result.file_dependencies.files.prt
                              .filter(prt => !result.file_dependencies!.dependencies.some(d => d.target === prt))
                              .map(prt => (
                                <div key={prt} className="ml-2 mt-1">
                                  <div className="flex items-center gap-1 p-1 bg-dark-800 rounded text-dark-400">
                                    <File size={12} />
                                    <span className="font-mono">{prt}</span>
                                  </div>
                                </div>
                              ))
                            }
                          </div>
                        )}
                      </div>
                    )}
                    
                    {!result.file_dependencies.root_sim && (
                      <p className="text-xs text-dark-500 text-center py-2">No simulation file found</p>
                    )}
                  </div>
                )}
              </div>
            )}

            {/* Existing FEA Results Section */}
            {result.existing_fea_results && (
              <div className="border border-dark-700 rounded-lg overflow-hidden">
                <button
                  onClick={() => toggleSection('fea_results')}
                  className="w-full flex items-center justify-between px-3 py-2 bg-dark-800 hover:bg-dark-750 transition-colors"
                >
                  <div className="flex items-center gap-2">
                    {result.existing_fea_results.has_results ? (
                      <CheckCircle2 size={14} className="text-green-400" />
                    ) : (
                      <Database size={14} className="text-dark-500" />
                    )}
                    <span className="text-sm font-medium text-white">
                      FEA Results {result.existing_fea_results.has_results ? 
                        `(${result.existing_fea_results.sources?.length || 0} sources)` : 
                        '(none)'}
                    </span>
                  </div>
                  {expandedSections.has('fea_results') ? (
                    <ChevronDown size={14} className="text-dark-400" />
                  ) : (
                    <ChevronRight size={14} className="text-dark-400" />
                  )}
                </button>

                {expandedSections.has('fea_results') && (
                  <div className="p-2 space-y-2">
                    {result.existing_fea_results.has_results ? (
                      <>
                        <p className="text-xs text-green-400 mb-2">
                          Existing results found - no solve needed for extraction
                        </p>
                        {result.existing_fea_results.sources?.map((source, idx) => (
                          <div 
                            key={idx} 
                            className={`p-2 rounded text-xs ${
                              source.location === result.existing_fea_results?.recommended?.location 
                                ? 'bg-green-500/10 border border-green-500/30' 
                                : 'bg-dark-850'
                            }`}
                          >
                            <div className="flex items-center justify-between mb-1">
                              <span className="text-white font-medium">{source.location}</span>
                              {source.location === result.existing_fea_results?.recommended?.location && (
                                <span className="text-[10px] text-green-400 bg-green-500/20 px-1 rounded">
                                  recommended
                                </span>
                              )}
                            </div>
                            <div className="text-dark-400 space-y-0.5">
                              {source.op2?.length > 0 && (
                                <p>OP2: {source.op2.join(', ')}</p>
                              )}
                              {source.f06?.length > 0 && (
                                <p>F06: {source.f06.join(', ')}</p>
                              )}
                            </div>
                          </div>
                        ))}
                      </>
                    ) : (
                      <p className="text-xs text-dark-500 text-center py-2">
                        No FEA results found. Run baseline to generate results.
                      </p>
                    )}
                  </div>
                )}
              </div>
            )}

            {/* Extractors Section - only show if available */}
            {(result.extractors_available?.length ?? 0) > 0 && (
            <div className="border border-dark-700 rounded-lg overflow-hidden">
              <button
                onClick={() => toggleSection('extractors')}
                className="w-full flex items-center justify-between px-3 py-2 bg-dark-800 hover:bg-dark-750 transition-colors"
              >
                <div className="flex items-center gap-2">
                  <FlaskConical size={14} className="text-cyan-400" />
                  <span className="text-sm font-medium text-white">
                    Available Extractors ({result.extractors_available?.length || 0})
                  </span>
                </div>
                {expandedSections.has('extractors') ? (
                  <ChevronDown size={14} className="text-dark-400" />
                ) : (
                  <ChevronRight size={14} className="text-dark-400" />
                )}
              </button>

              {expandedSections.has('extractors') && (
                <div className="p-2 space-y-1 max-h-48 overflow-y-auto">
                  {(result.extractors_available || []).map((ext) => (
                    <div
                      key={ext.id}
                      className="flex items-center justify-between p-2 bg-dark-850 rounded hover:bg-dark-750 group transition-colors"
                    >
                      <div className="flex-1 min-w-0">
                        <p className="text-sm text-white">{ext.name}</p>
                        <p className="text-xs text-dark-500">
                          {ext.id}
                          {ext.description && ` - ${ext.description}`}
                        </p>
                      </div>
                      <button
                        onClick={() => addExtractorNode(ext)}
                        className="p-1.5 text-dark-500 hover:text-primary-400 hover:bg-dark-700 rounded
                                   opacity-0 group-hover:opacity-100 transition-all"
                        title="Add Extractor"
                      >
                        <Plus size={14} />
                      </button>
                    </div>
                  ))}
                </div>
              )}
            </div>
            )}

            {/* Dependent Files */}
            {(result.dependent_files?.length ?? 0) > 0 && (
              <div className="border border-dark-700 rounded-lg overflow-hidden">
                <button
                  onClick={() => toggleSection('files')}
                  className="w-full flex items-center justify-between px-3 py-2 bg-dark-800 hover:bg-dark-750 transition-colors"
                >
                  <div className="flex items-center gap-2">
                    <FileBox size={14} className="text-amber-400" />
                    <span className="text-sm font-medium text-white">
                      Dependent Files ({result.dependent_files?.length || 0})
                    </span>
                  </div>
                  {expandedSections.has('files') ? (
                    <ChevronDown size={14} className="text-dark-400" />
                  ) : (
                    <ChevronRight size={14} className="text-dark-400" />
                  )}
                </button>

                {expandedSections.has('files') && (
                  <div className="p-2 space-y-1 max-h-32 overflow-y-auto">
                    {(result.dependent_files || []).map((file) => (
                      <div
                        key={file.path}
                        className="flex items-center gap-2 p-2 bg-dark-850 rounded"
                      >
                        <FileBox size={14} className="text-dark-400 flex-shrink-0" />
                        <div className="flex-1 min-w-0">
                          <p className="text-sm text-white truncate">{file.name}</p>
                          <p className="text-xs text-dark-500">{file.type}</p>
                        </div>
                      </div>
                    ))}
                  </div>
                )}
              </div>
            )}

            {/* Warnings */}
            {(result.warnings?.length ?? 0) > 0 && (
              <div className="p-2 bg-amber-500/10 border border-amber-500/30 rounded-lg">
                <div className="flex items-center gap-1.5 mb-1">
                  <AlertTriangle size={12} className="text-amber-400" />
                  <p className="text-xs text-amber-400 font-medium">Warnings</p>
                </div>
                {(result.warnings || []).map((w, i) => (
                  <p key={i} className="text-xs text-amber-300">
                    {w}
                  </p>
                ))}
              </div>
            )}
          </div>
        ) : (
          <div className="flex items-center justify-center h-32 text-dark-500 text-sm">
            Select a model to introspect
          </div>
        )}
      </div>
    </div>
  );
}
