'use client';

import * as React from 'react';
import { Plus, Upload, ChevronDown, ChevronRight, X } from 'lucide-react';
import { Button } from '@/components/ui/Button';
import { Track } from './Track';
import { TrackExtensions } from './TrackExtensions';
import { ImportTrackDialog } from './ImportTrackDialog';
import type { Track as TrackType } from '@/types/track';
import { createEffect, type EffectType, EFFECT_NAMES } from '@/lib/audio/effects/chain';
import { AutomationLane } from '@/components/automation/AutomationLane';
import type { AutomationPoint as AutomationPointType } from '@/types/automation';
import { createAutomationPoint } from '@/lib/audio/automation/utils';
import { EffectDevice } from '@/components/effects/EffectDevice';

export interface TrackListProps {
  tracks: TrackType[];
  zoom: number;
  currentTime: number;
  duration: number;
  selectedTrackId?: string | null;
  onSelectTrack?: (trackId: string | null) => void;
  onAddTrack: () => void;
  onImportTrack?: (buffer: AudioBuffer, name: string) => void;
  onRemoveTrack: (trackId: string) => void;
  onUpdateTrack: (trackId: string, updates: Partial<TrackType>) => void;
  onSeek?: (time: number) => void;
  onSelectionChange?: (trackId: string, selection: { start: number; end: number } | null) => void;
  onToggleRecordEnable?: (trackId: string) => void;
  recordingTrackId?: string | null;
  recordingLevel?: number;
  trackLevels?: Record<string, number>;
  onParameterTouched?: (trackId: string, laneId: string, touched: boolean) => void;
  isPlaying?: boolean;
}

export function TrackList({
  tracks,
  zoom,
  currentTime,
  duration,
  selectedTrackId,
  onSelectTrack,
  onAddTrack,
  onImportTrack,
  onRemoveTrack,
  onUpdateTrack,
  onSeek,
  onSelectionChange,
  onToggleRecordEnable,
  recordingTrackId,
  recordingLevel = 0,
  trackLevels = {},
  onParameterTouched,
  isPlaying = false,
}: TrackListProps) {
  const [importDialogOpen, setImportDialogOpen] = React.useState(false);
  const waveformScrollRef = React.useRef<HTMLDivElement>(null);
  const controlsScrollRef = React.useRef<HTMLDivElement>(null);

  // Synchronize vertical scroll between controls and waveforms
  const handleWaveformScroll = React.useCallback(() => {
    if (waveformScrollRef.current && controlsScrollRef.current) {
      controlsScrollRef.current.scrollTop = waveformScrollRef.current.scrollTop;
    }
  }, []);

  const handleImportTrack = (buffer: AudioBuffer, name: string) => {
    if (onImportTrack) {
      onImportTrack(buffer, name);
    }
  };

  if (tracks.length === 0) {
    return (
      <>
        <div className="flex-1 flex flex-col items-center justify-center gap-4 text-muted-foreground">
          <p className="text-sm">No tracks yet. Add a track to get started.</p>
          <div className="flex gap-2">
            <Button onClick={onAddTrack} variant="secondary">
              <Plus className="h-4 w-4 mr-2" />
              Add Empty Track
            </Button>
            {onImportTrack && (
              <Button onClick={() => setImportDialogOpen(true)} variant="secondary">
                <Upload className="h-4 w-4 mr-2" />
                Import Audio Files
              </Button>
            )}
          </div>
        </div>
        {onImportTrack && (
          <ImportTrackDialog
            open={importDialogOpen}
            onClose={() => setImportDialogOpen(false)}
            onImportTrack={handleImportTrack}
          />
        )}
      </>
    );
  }

  return (
    <div className="flex-1 flex flex-col overflow-hidden">
      {/* Track List - Two Column Layout */}
      <div className="flex-1 flex overflow-hidden">
        {/* Left Column: Track Controls (Fixed Width, No Scroll - synced with waveforms) */}
        <div ref={controlsScrollRef} className="w-48 flex-shrink-0 overflow-hidden pb-3 border-r border-border">
          {tracks.map((track) => (
            <React.Fragment key={track.id}>
              {/* Track Controls */}
              <Track
                track={track}
                zoom={zoom}
                currentTime={currentTime}
                duration={duration}
                isSelected={selectedTrackId === track.id}
                onSelect={onSelectTrack ? () => onSelectTrack(track.id) : undefined}
                onToggleMute={() =>
                  onUpdateTrack(track.id, { mute: !track.mute })
                }
                onToggleSolo={() =>
                  onUpdateTrack(track.id, { solo: !track.solo })
                }
                onToggleCollapse={() =>
                  onUpdateTrack(track.id, { collapsed: !track.collapsed })
                }
                onVolumeChange={(volume) =>
                  onUpdateTrack(track.id, { volume })
                }
                onPanChange={(pan) =>
                  onUpdateTrack(track.id, { pan })
                }
                onRemove={() => onRemoveTrack(track.id)}
                onNameChange={(name) =>
                  onUpdateTrack(track.id, { name })
                }
                onUpdateTrack={onUpdateTrack}
                onSeek={onSeek}
                onLoadAudio={(buffer) =>
                  onUpdateTrack(track.id, { audioBuffer: buffer })
                }
                onToggleEffect={(effectId) => {
                  const updatedChain = {
                    ...track.effectChain,
                    effects: track.effectChain.effects.map((e) =>
                      e.id === effectId ? { ...e, enabled: !e.enabled } : e
                    ),
                  };
                  onUpdateTrack(track.id, { effectChain: updatedChain });
                }}
                onRemoveEffect={(effectId) => {
                  const updatedChain = {
                    ...track.effectChain,
                    effects: track.effectChain.effects.filter((e) => e.id !== effectId),
                  };
                  onUpdateTrack(track.id, { effectChain: updatedChain });
                }}
                onUpdateEffect={(effectId, parameters) => {
                  const updatedChain = {
                    ...track.effectChain,
                    effects: track.effectChain.effects.map((e) =>
                      e.id === effectId ? { ...e, parameters } : e
                    ),
                  };
                  onUpdateTrack(track.id, { effectChain: updatedChain });
                }}
                onAddEffect={(effectType) => {
                  const newEffect = createEffect(
                    effectType,
                    EFFECT_NAMES[effectType]
                  );
                  const updatedChain = {
                    ...track.effectChain,
                    effects: [...track.effectChain.effects, newEffect],
                  };
                  onUpdateTrack(track.id, { effectChain: updatedChain });
                }}
                onSelectionChange={
                  onSelectionChange
                    ? (selection) => onSelectionChange(track.id, selection)
                    : undefined
                }
                onToggleRecordEnable={
                  onToggleRecordEnable
                    ? () => onToggleRecordEnable(track.id)
                    : undefined
                }
                isRecording={recordingTrackId === track.id}
                recordingLevel={recordingTrackId === track.id ? recordingLevel : 0}
                playbackLevel={trackLevels[track.id] || 0}
                onParameterTouched={onParameterTouched}
                isPlaying={isPlaying}
                renderControlsOnly={true}
              />
            </React.Fragment>
          ))}
        </div>

        {/* Right Column: Waveforms (Flexible Width, Shared Horizontal & Vertical Scroll) */}
        <div
          ref={waveformScrollRef}
          onScroll={handleWaveformScroll}
          className="flex-1 overflow-auto custom-scrollbar"
        >
          <div className="flex flex-col">
            {tracks.map((track) => (
              <React.Fragment key={track.id}>
                {/* Track Waveform Row with Overlays */}
                <div className="relative">
                  <Track
                    track={track}
                    zoom={zoom}
                    currentTime={currentTime}
                    duration={duration}
                    isSelected={selectedTrackId === track.id}
                    onSelect={onSelectTrack ? () => onSelectTrack(track.id) : undefined}
                    onToggleMute={() =>
                      onUpdateTrack(track.id, { mute: !track.mute })
                    }
                    onToggleSolo={() =>
                      onUpdateTrack(track.id, { solo: !track.solo })
                    }
                    onToggleCollapse={() =>
                      onUpdateTrack(track.id, { collapsed: !track.collapsed })
                    }
                    onVolumeChange={(volume) =>
                      onUpdateTrack(track.id, { volume })
                    }
                    onPanChange={(pan) =>
                      onUpdateTrack(track.id, { pan })
                    }
                    onRemove={() => onRemoveTrack(track.id)}
                    onNameChange={(name) =>
                      onUpdateTrack(track.id, { name })
                    }
                    onUpdateTrack={onUpdateTrack}
                    onSeek={onSeek}
                    onLoadAudio={(buffer) =>
                      onUpdateTrack(track.id, { audioBuffer: buffer })
                    }
                    onToggleEffect={(effectId) => {
                      const updatedChain = {
                        ...track.effectChain,
                        effects: track.effectChain.effects.map((e) =>
                          e.id === effectId ? { ...e, enabled: !e.enabled } : e
                        ),
                      };
                      onUpdateTrack(track.id, { effectChain: updatedChain });
                    }}
                    onRemoveEffect={(effectId) => {
                      const updatedChain = {
                        ...track.effectChain,
                        effects: track.effectChain.effects.filter((e) => e.id !== effectId),
                      };
                      onUpdateTrack(track.id, { effectChain: updatedChain });
                    }}
                    onUpdateEffect={(effectId, parameters) => {
                      const updatedChain = {
                        ...track.effectChain,
                        effects: track.effectChain.effects.map((e) =>
                          e.id === effectId ? { ...e, parameters } : e
                        ),
                      };
                      onUpdateTrack(track.id, { effectChain: updatedChain });
                    }}
                    onAddEffect={(effectType) => {
                      const newEffect = createEffect(
                        effectType,
                        EFFECT_NAMES[effectType]
                      );
                      const updatedChain = {
                        ...track.effectChain,
                        effects: [...track.effectChain.effects, newEffect],
                      };
                      onUpdateTrack(track.id, { effectChain: updatedChain });
                    }}
                    onSelectionChange={
                      onSelectionChange
                        ? (selection) => onSelectionChange(track.id, selection)
                        : undefined
                    }
                    onToggleRecordEnable={
                      onToggleRecordEnable
                        ? () => onToggleRecordEnable(track.id)
                        : undefined
                    }
                    isRecording={recordingTrackId === track.id}
                    recordingLevel={recordingTrackId === track.id ? recordingLevel : 0}
                    playbackLevel={trackLevels[track.id] || 0}
                    onParameterTouched={onParameterTouched}
                    isPlaying={isPlaying}
                    renderWaveformOnly={true}
                  />

                  {/* Effects Bar - Always visible at bottom */}
                  {!track.collapsed && (
                    <div className="absolute bottom-0 left-0 right-0 z-10 pointer-events-auto bg-card/90 backdrop-blur-sm border-t border-border">
                      {/* Effects Header - Collapsible */}
                      <div
                        className="flex items-center gap-2 px-3 py-1.5 cursor-pointer hover:bg-accent/30 transition-colors"
                        onClick={() => {
                          onUpdateTrack(track.id, { effectsExpanded: !track.effectsExpanded });
                        }}
                      >
                        {track.effectsExpanded ? (
                          <ChevronDown className="h-3 w-3 text-muted-foreground" />
                        ) : (
                          <ChevronRight className="h-3 w-3 text-muted-foreground" />
                        )}
                        <span className="text-xs font-medium">Effects</span>
                        <span className="text-xs text-muted-foreground">
                          ({track.effectChain.effects.length})
                        </span>
                      </div>

                      {/* Effects Content - Collapsible, no inner container */}
                      {track.effectsExpanded && (
                        <div className="h-48 overflow-x-auto custom-scrollbar bg-muted/70 border-t border-border">
                          <div className="flex h-full gap-3 p-3">
                            {track.effectChain.effects.length === 0 ? (
                              <div className="text-xs text-muted-foreground text-center py-8 w-full">
                                No effects. Click + to add an effect.
                              </div>
                            ) : (
                              track.effectChain.effects.map((effect) => (
                                <EffectDevice
                                  key={effect.id}
                                  effect={effect}
                                  onToggleEnabled={() => {
                                    const updatedChain = {
                                      ...track.effectChain,
                                      effects: track.effectChain.effects.map((e) =>
                                        e.id === effect.id ? { ...e, enabled: !e.enabled } : e
                                      ),
                                    };
                                    onUpdateTrack(track.id, { effectChain: updatedChain });
                                  }}
                                  onRemove={() => {
                                    const updatedChain = {
                                      ...track.effectChain,
                                      effects: track.effectChain.effects.filter((e) => e.id !== effect.id),
                                    };
                                    onUpdateTrack(track.id, { effectChain: updatedChain });
                                  }}
                                  onUpdateParameters={(params) => {
                                    const updatedChain = {
                                      ...track.effectChain,
                                      effects: track.effectChain.effects.map((e) =>
                                        e.id === effect.id ? { ...e, parameters: params } : e
                                      ),
                                    };
                                    onUpdateTrack(track.id, { effectChain: updatedChain });
                                  }}
                                  onToggleExpanded={() => {
                                    const updatedEffects = track.effectChain.effects.map((e) =>
                                      e.id === effect.id ? { ...e, expanded: !e.expanded } : e
                                    );
                                    onUpdateTrack(track.id, {
                                      effectChain: { ...track.effectChain, effects: updatedEffects },
                                    });
                                  }}
                                />
                              ))
                            )}
                          </div>
                        </div>
                      )}
                    </div>
                  )}

                  {/* Automation Bar - Always visible above effects bar at bottom */}
                  {!track.collapsed && (
                    <div
                      className="absolute left-0 right-0 z-10 pointer-events-auto bg-card/90 backdrop-blur-sm border-t border-border"
                      style={{
                        bottom: track.effectsExpanded ? '232px' : '32px' // 32px effects header, or 232px if expanded
                      }}
                    >
                      {/* Automation Header - Collapsible */}
                      <div
                        className="flex items-center gap-2 px-3 py-1.5 cursor-pointer hover:bg-accent/30 transition-colors"
                        onClick={() => {
                          const currentLane = track.automation.lanes.find(
                            l => l.parameterId === track.automation.selectedParameterId
                          );
                          if (currentLane) {
                            const updatedLanes = track.automation.lanes.map((l) =>
                              l.id === currentLane.id ? { ...l, visible: !l.visible } : l
                            );
                            onUpdateTrack(track.id, {
                              automation: { ...track.automation, lanes: updatedLanes },
                            });
                          }
                        }}
                      >
                        {track.automation.lanes.find(l => l.parameterId === track.automation.selectedParameterId)?.visible ? (
                          <ChevronDown className="h-3 w-3 text-muted-foreground" />
                        ) : (
                          <ChevronRight className="h-3 w-3 text-muted-foreground" />
                        )}
                        <span className="text-xs font-medium">Automation</span>
                        <span className="text-xs text-muted-foreground">
                          {track.automation.selectedParameterId || 'Volume'}
                        </span>
                      </div>

                      {/* Automation Lane Content - Collapsible */}
                      {track.automation.lanes
                        .filter((lane) => lane.parameterId === track.automation.selectedParameterId && lane.visible)
                        .map((lane) => (
                          <div key={lane.id} className="h-32 border-t border-border">
                            <AutomationLane
                              lane={lane}
                              trackId={track.id}
                              zoom={zoom}
                              currentTime={currentTime}
                              duration={duration}
                              isPlaying={isPlaying}
                              onAddPoint={(time, value) => {
                                const newPoint = createAutomationPoint(time, value);
                                const updatedLanes = track.automation.lanes.map((l) =>
                                  l.id === lane.id
                                    ? { ...l, points: [...l.points, newPoint].sort((a, b) => a.time - b.time) }
                                    : l
                                );
                                onUpdateTrack(track.id, {
                                  automation: { ...track.automation, lanes: updatedLanes },
                                });
                              }}
                              onUpdatePoint={(pointId, updates) => {
                                const updatedLanes = track.automation.lanes.map((l) =>
                                  l.id === lane.id
                                    ? {
                                        ...l,
                                        points: l.points.map((p) =>
                                          p.id === pointId ? { ...p, ...updates } : p
                                        ),
                                      }
                                    : l
                                );
                                onUpdateTrack(track.id, {
                                  automation: { ...track.automation, lanes: updatedLanes },
                                });
                              }}
                              onRemovePoint={(pointId) => {
                                const updatedLanes = track.automation.lanes.map((l) =>
                                  l.id === lane.id
                                    ? { ...l, points: l.points.filter((p) => p.id !== pointId) }
                                    : l
                                );
                                onUpdateTrack(track.id, {
                                  automation: { ...track.automation, lanes: updatedLanes },
                                });
                              }}
                              onUpdateLane={(updates) => {
                                const updatedLanes = track.automation.lanes.map((l) =>
                                  l.id === lane.id ? { ...l, ...updates } : l
                                );
                                onUpdateTrack(track.id, {
                                  automation: { ...track.automation, lanes: updatedLanes },
                                });
                              }}
                              onSeek={onSeek}
                            />
                          </div>
                        ))}
                    </div>
                  )}
                </div>
              </React.Fragment>
            ))}
          </div>
        </div>
      </div>

      {/* Import Dialog */}
      {onImportTrack && (
        <ImportTrackDialog
          open={importDialogOpen}
          onClose={() => setImportDialogOpen(false)}
          onImportTrack={handleImportTrack}
        />
      )}
    </div>
  );
}
