import { useCallback } from 'react';
import type { Cell } from '../../../lib/types';
import type { WaveformData } from '../../../lib/types';
import { useNotebookStore } from '../../../lib/notebook-store';
import { CellToolbar } from '../toolbar/CellToolbar';
import { SpiceEditor } from '../editor/SpiceEditor';
import { WaveformViewer } from '../output/WaveformViewer';
import { SchematicViewer } from '../output/SchematicViewer';
import { SimulationLog } from '../output/SimulationLog';
import { cn } from '../../../lib/cn';

interface SpiceCellProps {
  cell: Cell;
  isFirst: boolean;
  isLast: boolean;
}

export function SpiceCell({ cell, isFirst, isLast }: SpiceCellProps) {
  const {
    activeCell,
    runningCells,
    setActiveCell,
    updateCellSource,
    deleteCell,
    moveCell,
    runCell,
    generateSchematic,
  } = useNotebookStore();

  const isActive = activeCell === cell.id;
  const isRunning = runningCells.has(cell.id);

  const handleChange = useCallback(
    (value: string) => {
      updateCellSource(cell.id, value);
    },
    [cell.id, updateCellSource],
  );

  const handleRun = useCallback(() => {
    runCell(cell.id);
  }, [cell.id, runCell]);

  const handleGenerateSchematic = useCallback(() => {
    generateSchematic(cell.id);
  }, [cell.id, generateSchematic]);

  // Extract simulation output
  const simOutput = cell.outputs.find(
    (o) => o.output_type === 'simulation_result' || o.output_type === 'error',
  );
  const outputData = simOutput?.data as {
    success?: boolean;
    waveform?: WaveformData | null;
    log?: string;
    error?: string | null;
    elapsed_seconds?: number;
  } | null;

  // Extract schematic output
  const schematicOutput = cell.outputs.find((o) => o.output_type === 'schematic');
  const schematicSvg = schematicOutput?.data?.svg as string | null;

  return (
    <div
      className={cn(
        'rounded-lg border transition-colors overflow-hidden',
        isActive
          ? 'border-blue-500/50 ring-1 ring-blue-500/20'
          : 'border-slate-700/50 hover:border-slate-600',
      )}
      onClick={() => setActiveCell(cell.id)}
    >
      <CellToolbar
        cellId={cell.id}
        cellType="spice"
        isRunning={isRunning}
        isFirst={isFirst}
        isLast={isLast}
        onRun={handleRun}
        onGenerateSchematic={handleGenerateSchematic}
        onDelete={() => deleteCell(cell.id)}
        onMoveUp={() => moveCell(cell.id, 'up')}
        onMoveDown={() => moveCell(cell.id, 'down')}
      />

      {/* Schematic — shown above the editor when generated */}
      {schematicSvg && (
        <div className="border-b border-slate-700/50">
          <SchematicViewer svg={schematicSvg} />
        </div>
      )}

      {/* SPICE Editor — always visible */}
      <div className="min-h-[80px]">
        <SpiceEditor
          value={cell.source}
          onChange={handleChange}
          onRun={handleRun}
        />
      </div>

      {/* Running indicator */}
      {isRunning && (
        <div className="border-t border-slate-700/50 px-4 py-3">
          <div className="flex items-center gap-2 text-sm text-blue-400">
            <div className="w-4 h-4 border-2 border-blue-400/30 border-t-blue-400 rounded-full animate-spin" />
            Processing...
          </div>
        </div>
      )}

      {/* Waveform + Simulation results — shown below the editor */}
      {!isRunning && outputData && (
        <div className="border-t border-slate-700/50">
          {/* Error banner */}
          {!outputData.success && outputData.error && (
            <div className="px-4 py-3 bg-red-600/10 border-b border-red-500/20">
              <div className="text-sm text-red-400 font-mono whitespace-pre-wrap">
                {outputData.error}
              </div>
            </div>
          )}

          {/* Waveform plot */}
          {outputData.waveform && (
            <div className="p-3 bg-slate-900/50">
              <WaveformViewer waveform={outputData.waveform} />
            </div>
          )}

          {/* Simulation log */}
          <SimulationLog
            log={outputData.log || ''}
            error={outputData.success ? null : (outputData.error ?? null)}
            elapsedSeconds={outputData.elapsed_seconds || 0}
            defaultOpen={!outputData.success}
          />
        </div>
      )}
    </div>
  );
}
