import {
  Box,
  CircularProgress,
  CircularProgressLabel,
  Flex,
  Input,
  Modal,
  ModalContent,
  ModalOverlay,
  Stack,
  Text,
} from '@chakra-ui/react';
import { clsx } from 'clsx';
// Add this new import
import Hls from 'hls.js';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useHotkeys } from 'react-hotkeys-hook';

import { toast } from '@/components/toast/Toast';
import {
  elementSupportsNativeHls,
  isHlsVideoUrl,
} from '@/components/video/SimpleVideoPlayer';
import { CheckIcon, PauseIcon, PlayIcon } from '@/icons';
import { BLUE_AURA_URL, ORANGE_AURA_URL_WEB } from '@/utils/constants';

import Button, { ButtonSize, ButtonVariant } from '../button/Button';
import SpinnerSVG from '../svg/SpinnerSVG';

// Add this constant at the top of the file with other constants
const CREDITS_EARNED_SOUND_URL = 'https://cdn-o.suno.com/kah-ching.mp3';

interface ReviewItem {
  key: string;
  url: string;
  name: string;
  metadata?: Record<string, any>;
  // Remove type since it's handled by layout prop
}

interface PreferenceModalProps {
  isOpen: boolean;
  onClose: () => void;
  taskId: string;
  reviewItems: ReviewItem[];
  question: string;
  instructions: string;
  preferenceDimensions: Array<{ key: string; name: string }>;
  minListenTimeSeconds?: number; // Default to 30 if not provided
  credits_per_annotation?: number;
  syncPlayheads?: boolean;
  onSubmit: (
    taskId: string,
    preference: Record<string, string>,
    feedback: string,
    listenTimes: Record<string, number>
  ) => Promise<void>;
  onSkip?: () => void;
  layout?: 'audio' | 'video'; // Make optional since we have a default
}

// Simple waveform component that works with direct audio URLs
const SimpleWaveform = ({
  audioUrl,
  progress,
  onSeek,
  isPlaying,
  onPlayPause,
  forceLoading = false,
}: {
  audioUrl: string;
  progress: number;
  onSeek: (progress: number) => void;
  isPlaying: boolean;
  onPlayPause: (seekTo?: number) => void; // Modified to accept optional seek position
  forceLoading?: boolean;
}) => {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [waveformData, setWaveformData] = useState<number[]>([]);

  useEffect(() => {
    if (!audioUrl) {
      setIsLoading(false);
      return;
    }

    setIsLoading(true);
    const generateWaveform = async () => {
      try {
        const response = await fetch(audioUrl);
        const arrayBuffer = await response.arrayBuffer();
        const audioContext = new (window.AudioContext ||
          (window as any).webkitAudioContext)();
        const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);

        // Generate waveform data
        const channelData = audioBuffer.getChannelData(0); // Use first channel
        const samples = channelData.length;
        const blockSize = Math.floor(samples / 100); // 100 data points
        const waveform: number[] = [];

        for (let i = 0; i < 100; i++) {
          const start = i * blockSize;
          const end = start + blockSize;
          let sum = 0;
          for (let j = start; j < end; j++) {
            sum += Math.abs(channelData[j]);
          }
          waveform.push(sum / blockSize);
        }

        setWaveformData(waveform);
      } catch (error) {
        console.error('Failed to generate waveform:', error);
        setWaveformData([]);
      } finally {
        setIsLoading(false);
      }
    };

    generateWaveform();
  }, [audioUrl]);

  useEffect(() => {
    if (!canvasRef.current || waveformData.length === 0) return;

    const canvas = canvasRef.current;
    const ctx = canvas.getContext('2d');
    if (!ctx) return;

    const width = canvas.width;
    const height = canvas.height;
    const centerY = height / 2;

    // Clear canvas
    ctx.clearRect(0, 0, width, height);

    // Draw waveform as area chart
    ctx.fillStyle = '#726e6c';
    ctx.beginPath();

    // Start at the left edge
    ctx.moveTo(0, centerY);

    // Draw the top half of the waveform
    waveformData.forEach((value, index) => {
      const x = (index / (waveformData.length - 1)) * width;
      const amplitude = (value / Math.max(...waveformData)) * (height * 0.4);
      const y = centerY - amplitude;
      ctx.lineTo(x, y);
    });

    // Draw the bottom half of the waveform (mirrored)
    for (let i = waveformData.length - 1; i >= 0; i--) {
      const x = (i / (waveformData.length - 1)) * width;
      const amplitude =
        (waveformData[i] / Math.max(...waveformData)) * (height * 0.4);
      const y = centerY + amplitude;
      ctx.lineTo(x, y);
    }

    // Close the path back to the start
    ctx.lineTo(0, centerY);
    ctx.closePath();
    ctx.fill();

    // Draw progress line
    ctx.fillStyle = '#ffffff';
    const progressX = progress * width;
    ctx.fillRect(progressX - 1, 0, 2, height);
  }, [waveformData, progress]);

  if (isLoading || forceLoading) {
    return (
      <Flex align='center' justify='center' h='40px'>
        <SpinnerSVG />
      </Flex>
    );
  }

  return (
    <canvas
      ref={canvasRef}
      width={300}
      height={40}
      style={{
        width: '100%',
        height: '40px',
        borderRadius: '4px',
        cursor: 'pointer',
      }}
      onMouseDown={(e) => {
        const rect = e.currentTarget.getBoundingClientRect();
        const newProgress = (e.clientX - rect.left) / rect.width;
        if (!isPlaying) {
          // If this clip isn't playing, start it and seek in one operation
          onPlayPause(Math.max(0, Math.min(1, newProgress)));
        } else {
          // If already playing, just seek
          onSeek(Math.max(0, Math.min(1, newProgress)));
        }
      }}
    />
  );
};

const PreferenceTrack = ({
  clipUrl,
  clipKey,
  isPlaying,
  onPlayPause,
  progress,
  onSeek,
  forceLoading = false,
}: {
  clipUrl: string;
  clipKey: string;
  isPlaying: boolean;
  onPlayPause: (clipKey: string, seekTo?: number) => void;
  progress: number;
  onSeek: (progress: number) => void;
  forceLoading?: boolean;
}) => {
  // Create a bound version of onPlayPause that includes the clipKey
  const handlePlayPause = useCallback(
    (seekTo?: number) => onPlayPause(clipKey, seekTo),
    [clipKey, onPlayPause]
  );

  return (
    <Stack spacing={1} w='full'>
      <Flex
        align='center'
        gap={3}
        p={2}
        bg='whiteAlpha.50'
        borderRadius='lg'
        w='full'
      >
        <Box
          css={{
            '& button:focus-visible': {
              outline: 'none !important',
              boxShadow: 'none !important',
              border: 'none !important',
            },
          }}
        >
          <Button
            onClick={() => handlePlayPause()}
            variant={ButtonVariant.Tertiary}
            size={ButtonSize.Small}
            icon={isPlaying ? <PauseIcon /> : <PlayIcon />}
            aria-label={isPlaying ? 'Pause' : 'Play'}
          />
        </Box>
        <Box flex={1} position='relative' h='40px'>
          <SimpleWaveform
            audioUrl={clipUrl}
            progress={progress}
            onSeek={onSeek}
            isPlaying={isPlaying}
            onPlayPause={handlePlayPause}
            forceLoading={forceLoading}
          />
        </Box>
      </Flex>
    </Stack>
  );
};

const VideoComparison: React.FC<{
  items: ReviewItem[];
  playingClip: string | null;
  onPlayPause: (clipKey: string) => void;
  setProgressMap: (value: React.SetStateAction<Record<string, number>>) => void;
  listenTimes: Record<string, number>;
  setListenTimes: (value: React.SetStateAction<Record<string, number>>) => void;
  minListenTimeSeconds: number;
  focusedIndex: number;
  selections: Record<string, string>;
  preferenceDimensions: Array<{ key: string; name: string }>;
  videoRefs: React.MutableRefObject<(HTMLVideoElement | null)[]>;
}> = ({
  items,
  playingClip,
  onPlayPause,
  setProgressMap,
  listenTimes,
  setListenTimes,
  minListenTimeSeconds,
  focusedIndex,
  selections,
  preferenceDimensions,
  videoRefs,
}) => {
  const hlsInstancesRef = useRef<(Hls | null)[]>([]);

  // Add time tracking
  useEffect(() => {
    const interval = setInterval(() => {
      items.forEach((item, index) => {
        const video = videoRefs.current[index];
        if (video && !video.paused) {
          setListenTimes((prev) => ({
            ...prev,
            [item.key]: (prev[item.key] || 0) + 1,
          }));
        }
      });
    }, 1000);

    return () => clearInterval(interval);
  }, [items, setListenTimes]);

  // Handle play/pause
  useEffect(() => {
    items.forEach((item, index) => {
      const video = videoRefs.current[index];
      if (!video) return;

      if (playingClip === item.key) {
        video.play().catch(console.error);
      } else {
        video.pause();
      }
    });
  }, [playingClip, items]);

  // Track progress
  useEffect(() => {
    const handleTimeUpdate = (key: string, video: HTMLVideoElement) => {
      setProgressMap((prev) => ({
        ...prev,
        [key]: video.currentTime / video.duration,
      }));
    };

    const cleanups: (() => void)[] = [];

    items.forEach((item, index) => {
      const video = videoRefs.current[index];
      if (!video) return;

      const update = () => handleTimeUpdate(item.key, video);
      video.addEventListener('timeupdate', update);
      cleanups.push(() => video.removeEventListener('timeupdate', update));
    });

    return () => cleanups.forEach((cleanup) => cleanup());
  }, [items, setProgressMap]);

  // Setup HLS
  useEffect(() => {
    items.forEach((item, index) => {
      const videoElement = videoRefs.current[index];
      if (!videoElement) return;

      // Cleanup previous HLS instance
      if (hlsInstancesRef.current[index]) {
        hlsInstancesRef.current[index]?.destroy();
        hlsInstancesRef.current[index] = null;
      }

      if (isHlsVideoUrl(item.url)) {
        if (!elementSupportsNativeHls(videoElement) && Hls.isSupported()) {
          const hls = new Hls();
          hlsInstancesRef.current[index] = hls;
          hls.loadSource(item.url);
          hls.attachMedia(videoElement);
        } else {
          videoElement.src = item.url;
        }
      } else {
        videoElement.src = item.url;
      }
    });

    return () => {
      const currentInstances = [...hlsInstancesRef.current]; // Capture current value
      currentInstances.forEach((hls) => hls?.destroy());
    };
  }, [items]);

  return (
    <Flex gap={8} w='100%' justify='center' align='center' position='relative'>
      {/* Left hotkey with watch time */}
      {items.length > 0 && (
        <Flex
          position='absolute'
          left='5%' // Changed from 10% to move further out
          top='50%'
          transform='translateY(-50%)'
          direction='column'
          align='center'
          gap={2}
          onClick={() => onPlayPause(items[0].key)}
          cursor='pointer' // Show it's clickable
        >
          <CircularProgress
            value={
              ((listenTimes[items[0].key] || 0) / minListenTimeSeconds) * 100
            }
            color='var(--color-accent-pink)'
            trackColor='var(--color-background-secondary)'
            size='64px'
          >
            <CircularProgressLabel>
              <Text fontSize='lg' color='var(--color-foreground-secondary)'>
                A
              </Text>
            </CircularProgressLabel>
          </CircularProgress>
          <Text fontSize='xs' color='var(--color-foreground-secondary)'>
            {(listenTimes[items[0].key] || 0) >= minListenTimeSeconds
              ? `Watch time: ${listenTimes[items[0].key]}s`
              : `Watch for ${minListenTimeSeconds - (listenTimes[items[0].key] || 0)}s more`}
          </Text>
        </Flex>
      )}

      {/* Right hotkey with watch time */}
      {items.length > 1 && (
        <Flex
          position='absolute'
          right='5%' // Changed from 10% to move further out
          top='50%'
          transform='translateY(-50%)'
          direction='column'
          align='center'
          gap={2}
          onClick={() => onPlayPause(items[1].key)}
          cursor='pointer' // Show it's clickable
        >
          <CircularProgress
            value={
              ((listenTimes[items[1].key] || 0) / minListenTimeSeconds) * 100
            }
            color='var(--color-accent-pink)'
            trackColor='var(--color-background-secondary)'
            size='64px'
          >
            <CircularProgressLabel>
              <Text fontSize='lg' color='var(--color-foreground-secondary)'>
                B
              </Text>
            </CircularProgressLabel>
          </CircularProgress>
          <Text fontSize='xs' color='var(--color-foreground-secondary)'>
            {(listenTimes[items[1].key] || 0) >= minListenTimeSeconds
              ? `Watch time: ${listenTimes[items[1].key]}s`
              : `Watch for ${minListenTimeSeconds - (listenTimes[items[1].key] || 0)}s more`}
          </Text>
        </Flex>
      )}

      {/* Videos */}
      {items.map((item, index) => (
        <Box
          key={item.key}
          flex='1'
          position='relative'
          maxW='275px'
          cursor='pointer'
          borderRadius='xl'
          overflow='hidden'
          border='2px solid'
          borderColor={(() => {
            const dimensionIndex = focusedIndex - items.length;
            const isInPreferences =
              dimensionIndex >= 0 &&
              dimensionIndex < preferenceDimensions.length;
            const currentDimension = isInPreferences
              ? preferenceDimensions[dimensionIndex]
              : null;
            return isInPreferences &&
              currentDimension?.key &&
              selections[currentDimension.key] === item.key
              ? 'var(--color-accent-pink)'
              : 'transparent';
          })()}
          transition='all 0.3s'
          onClick={() => onPlayPause(item.key)}
          sx={{
            transform: (() => {
              const dimensionIndex = focusedIndex - items.length;
              const isInPreferences =
                dimensionIndex >= 0 &&
                dimensionIndex < preferenceDimensions.length;
              const currentDimension = isInPreferences
                ? preferenceDimensions[dimensionIndex]
                : null;
              const isSelected =
                isInPreferences &&
                currentDimension?.key &&
                selections[currentDimension.key] === item.key;

              // If selected in preferences section, elevate
              if (isSelected) {
                return 'translateY(-20px)';
              }
              // If playing and not in preferences section, elevate
              if (playingClip === item.key && !isInPreferences) {
                return 'translateY(-20px)';
              }
              // If not playing and not selected, move down
              if (playingClip && playingClip !== item.key && !isSelected) {
                return 'translateY(20px)';
              }
              // Default position
              return 'translateY(0)';
            })(),
            zIndex: (() => {
              const dimensionIndex = focusedIndex - items.length;
              const isInPreferences =
                dimensionIndex >= 0 &&
                dimensionIndex < preferenceDimensions.length;
              const currentDimension = isInPreferences
                ? preferenceDimensions[dimensionIndex]
                : null;
              const isSelected =
                isInPreferences &&
                currentDimension?.key &&
                selections[currentDimension.key] === item.key;

              return isSelected || playingClip === item.key ? 2 : 1;
            })(),
            opacity: playingClip && playingClip !== item.key ? 0.8 : 1,
          }}
        >
          <Box position='relative' w='100%' h='450px'>
            <video
              ref={(el) => {
                if (el) {
                  videoRefs.current[index] = el;
                }
              }}
              style={{
                width: '100%',
                height: '100%',
                objectFit: 'cover',
                borderRadius: '8px',
                aspectRatio: '9/16', // Force portrait ratio
                margin: '0 auto', // Center in fullscreen
              }}
              playsInline
              preload='metadata'
              loop // Add loop
            />
          </Box>
        </Box>
      ))}
    </Flex>
  );
};

const PreferenceModal = ({
  isOpen,
  onClose,
  taskId,
  reviewItems,
  question,
  instructions,
  preferenceDimensions,
  minListenTimeSeconds = 30, // Default to 30 seconds
  credits_per_annotation,
  syncPlayheads,
  onSubmit,
  onSkip,
  layout = 'audio', // Default to audio layout
}: PreferenceModalProps) => {
  // Add videoRefs at the top level
  const videoRefs = useRef<(HTMLVideoElement | null)[]>([]);

  const [selections, setSelections] = useState<Record<string, string>>({});
  const [feedback, setFeedback] = useState('');
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [playingClip, setPlayingClip] = useState<string | null>(null);
  const [progressMap, setProgressMap] = useState<Record<string, number>>({});
  const [listenTimes, setListenTimes] = useState<Record<string, number>>({});
  // Track focus as a single number: 0 = clip A, 1 = clip B, 2+ = dimensions
  const [focusedIndex, setFocusedIndex] = useState(0);
  //const [isAutoSwitching, setIsAutoSwitching] = useState(false);
  const [isLoadingNextTask, setIsLoadingNextTask] = useState(false);
  // Add a ref to track positions for each clip
  const clipPositionsRef = useRef<Record<string, number>>({});
  // Shared position for sync playheads mode
  const sharedPositionRef = useRef<number>(0);
  const inputRef = useRef<HTMLInputElement>(null);

  const audioRef = useRef<HTMLAudioElement | null>(null);
  const playStartTimeRef = useRef<number | null>(null);
  const currentClipKeyRef = useRef<string | null>(null);
  const intervalRef = useRef<NodeJS.Timeout | null>(null);
  const autoSwitchIntervalRef = useRef<NodeJS.Timeout | null>(null);
  const listenersAttachedRef = useRef(false);

  // First, add a new state for smooth progress at the top with other states
  const [smoothProgressMap, setSmoothProgressMap] = useState<
    Record<string, number>
  >({});

  // Add this new effect for smooth progress animation
  useEffect(() => {
    const intervalId = setInterval(() => {
      setSmoothProgressMap((prev) => {
        const newProgress = { ...prev };
        let hasChanges = false;

        reviewItems.forEach((item) => {
          const listenTime = listenTimes[item.key] || 0;
          const targetProgress =
            Math.min(listenTime / minListenTimeSeconds, 1) * 100;
          const currentProgress = prev[item.key] || 0;
          const diff = targetProgress - currentProgress;

          if (Math.abs(diff) > 0.1) {
            newProgress[item.key] = currentProgress + diff * 0.1;
            hasChanges = true;
          } else if (currentProgress !== targetProgress) {
            newProgress[item.key] = targetProgress;
            hasChanges = true;
          }
        });

        return hasChanges ? newProgress : prev;
      });
    }, 16); // ~60fps

    return () => clearInterval(intervalId);
  }, [listenTimes, minListenTimeSeconds, reviewItems]);

  // Effect to reset focus to first clip when modal opens
  useEffect(() => {
    if (isOpen) {
      setFocusedIndex(0);
    }
  }, [isOpen]);

  // Reset loading state when new tasks are loaded
  // This handles the normal flow after submit/skip completes
  useEffect(() => {
    if (reviewItems.length > 0) {
      setIsLoadingNextTask(false);
    }
  }, [reviewItems]);

  // Wrap resetForm in useCallback
  const resetForm = useCallback(() => {
    setSelections({});
    setFeedback('');
    setIsSubmitting(false);
    setPlayingClip(null);
    setProgressMap({});
    setListenTimes({});
    //setIsAutoSwitching(false);
    clipPositionsRef.current = {}; // Clear saved positions
    sharedPositionRef.current = 0; // Reset shared position
    playStartTimeRef.current = null;
    currentClipKeyRef.current = null;
    listenersAttachedRef.current = false;

    // Clear intervals
    if (intervalRef.current) {
      clearInterval(intervalRef.current);
      intervalRef.current = null;
    }
    if (autoSwitchIntervalRef.current) {
      clearInterval(autoSwitchIntervalRef.current);
      autoSwitchIntervalRef.current = null;
    }

    // Stop any playing audio and cleanup listeners
    if (audioRef.current) {
      if ((audioRef.current as any)._cleanupListeners) {
        (audioRef.current as any)._cleanupListeners();
      }
      audioRef.current.pause();
      audioRef.current.src = '';
    }
  }, []); // No dependencies since it only uses setState functions which are stable

  const handleClose = () => {
    resetForm();
    onClose();
  };

  // Initialize progress map and listen times for all review items
  useEffect(() => {
    const newProgressMap: Record<string, number> = {};
    reviewItems.forEach((item) => {
      newProgressMap[item.key] = 0;
      // Use a functional update to safely reference current state
      setListenTimes((prev) => {
        // Only initialize if not already present
        if (!(item.key in prev)) {
          return {
            ...prev,
            [item.key]: 0,
          };
        }
        return prev; // No change needed
      });
    });
    setProgressMap(newProgressMap);
  }, [reviewItems]); // Only depend on reviewItems since this is initialization logic

  // Auto-switch effect for synced playheads
  // NOTE: Auto-switch disabled - will revisit after further experimentation
  // Keeping code for future reference
  // NOTE: playingClip is intentionally NOT in the dependency array to prevent interval cascades.
  // The interval uses setPlayingClip with a functional update form which receives the current
  // value as a parameter, so it doesn't need playingClip as a dependency. If we included it,
  // the interval would be recreated every 6 seconds when playingClip changes.
  /* useEffect(() => {
    if (isAutoSwitching && reviewItems.length > 0) {
      // Set up the interval
      autoSwitchIntervalRef.current = setInterval(() => {
        // Use functional update to get current value without depending on playingClip
        setPlayingClip((currentPlaying) => {
          if (!currentPlaying) return reviewItems[0].key;

          const currentIndex = reviewItems.findIndex(
            (item) => item.key === currentPlaying
          );
          const nextIndex = (currentIndex + 1) % reviewItems.length;
          return reviewItems[nextIndex].key;
        });
      }, 6000); // 6 seconds

      return () => {
        if (autoSwitchIntervalRef.current) {
          clearInterval(autoSwitchIntervalRef.current);
          autoSwitchIntervalRef.current = null;
        }
      };
    } else {
      // Clean up interval when auto-switching is disabled
      if (autoSwitchIntervalRef.current) {
        clearInterval(autoSwitchIntervalRef.current);
        autoSwitchIntervalRef.current = null;
      }
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isAutoSwitching, reviewItems]); */

  // Set up audio event listeners when audio element is created
  const setupAudioEventListeners = (audio: HTMLAudioElement) => {
    // Only attach listeners once
    if (listenersAttachedRef.current) {
      return;
    }

    const handleTimeUpdate = () => {
      if (currentClipKeyRef.current && audio.duration) {
        setProgressMap((prev) => ({
          ...prev,
          [currentClipKeyRef.current!]: audio.currentTime / audio.duration,
        }));
      }
    };

    const handlePlay = () => {
      // Start listen time tracking
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
      }
      intervalRef.current = setInterval(() => {
        if (!audio.paused && currentClipKeyRef.current) {
          setListenTimes((prev) => ({
            ...prev,
            [currentClipKeyRef.current!]:
              (prev[currentClipKeyRef.current!] || 0) + 1,
          }));
        }
      }, 1000);
    };

    const handlePause = () => {
      if (intervalRef.current) {
        clearInterval(intervalRef.current);
        intervalRef.current = null;
      }
    };

    const handleEnded = () => {
      handlePause();
      setPlayingClip(null);
    };

    // Add event listeners
    audio.addEventListener('timeupdate', handleTimeUpdate);
    audio.addEventListener('play', handlePlay);
    audio.addEventListener('pause', handlePause);
    audio.addEventListener('ended', handleEnded);

    listenersAttachedRef.current = true;

    // Store cleanup function on the audio element
    (audio as any)._cleanupListeners = () => {
      audio.removeEventListener('timeupdate', handleTimeUpdate);
      audio.removeEventListener('play', handlePlay);
      audio.removeEventListener('pause', handlePause);
      audio.removeEventListener('ended', handleEnded);
      listenersAttachedRef.current = false;
    };
  };

  // Consolidate all audio control in one effect
  useEffect(() => {
    if (!audioRef.current) return;
    const audio = audioRef.current;
    let isLoadingNewSource = false;

    const saveCurrentPosition = () => {
      // Ensure we have a string key when saving position and duration is loaded
      if (currentClipKeyRef.current && !isLoadingNewSource && audio.duration) {
        if (syncPlayheads) {
          sharedPositionRef.current = audio.currentTime;
        } else {
          // Store as percentage (0-1) for consistency
          clipPositionsRef.current[`${currentClipKeyRef.current}_seek`] =
            audio.currentTime / audio.duration;
        }
      }
    };

    // Handle continuous position tracking
    const handleTimeUpdate = () => saveCurrentPosition();
    audio.addEventListener('timeupdate', handleTimeUpdate);

    const handlePlay = async () => {
      if (!playingClip) return;

      const reviewItem = reviewItems.find((item) => item.key === playingClip);
      if (!reviewItem) return;

      try {
        saveCurrentPosition();

        // Update current clip key
        currentClipKeyRef.current = playingClip;
        isLoadingNewSource = true;

        // Load new source if different
        if (audio.src !== reviewItem.url) {
          audio.src = reviewItem.url;

          // Wait for metadata
          await new Promise((resolve, reject) => {
            const onMetadata = () => {
              audio.removeEventListener('loadedmetadata', onMetadata);
              audio.removeEventListener('error', onError);
              resolve(null);
            };

            const onError = (error: Event) => {
              audio.removeEventListener('loadedmetadata', onMetadata);
              audio.removeEventListener('error', onError);
              reject(error);
            };

            audio.addEventListener('loadedmetadata', onMetadata, {
              once: true,
            });
            audio.addEventListener('error', onError, { once: true });
          });

          // Restore saved position (convert from percentage to time if needed)
          const savedPosition = syncPlayheads
            ? sharedPositionRef.current
            : clipPositionsRef.current[`${playingClip}_seek`] || 0;
          // clipPositionsRef stores percentages (0-1), sharedPositionRef stores actual time
          audio.currentTime = syncPlayheads
            ? savedPosition
            : savedPosition * audio.duration;
          isLoadingNewSource = false;
        } else if (syncPlayheads) {
          // If same source and sync mode, restore shared position
          audio.currentTime = sharedPositionRef.current;
        } else {
          // If same source and non-sync mode, restore saved position for this clip
          const savedPosition =
            clipPositionsRef.current[`${playingClip}_seek`] || 0;
          // clipPositionsRef stores percentages (0-1), convert to time
          audio.currentTime = savedPosition * audio.duration;
        }

        await audio.play();
      } catch (error) {
        console.error('Error playing audio:', error);
        setPlayingClip(null);
        currentClipKeyRef.current = null;
        isLoadingNewSource = false;
      }
    };

    const handlePause = () => {
      if (!audio.paused) {
        saveCurrentPosition();
        audio.pause();
      }
      currentClipKeyRef.current = null;
    };

    // Main control flow
    if (playingClip) {
      handlePlay();
    } else {
      handlePause();
    }

    // Cleanup
    return () => {
      audio.removeEventListener('timeupdate', handleTimeUpdate);
      saveCurrentPosition();
    };
  }, [playingClip, reviewItems, syncPlayheads]);

  // Update handleSeek to only change position for focused clips
  const handleSeek = useCallback(
    (clipKey: string, newProgress: number) => {
      // If this clip isn't focused, just focus it
      if (
        reviewItems.findIndex((item) => item.key === clipKey) !== focusedIndex
      ) {
        setFocusedIndex(reviewItems.findIndex((item) => item.key === clipKey));
        return;
      }

      // Only update position if we have audio and this is the focused clip
      if (!audioRef.current || !audioRef.current.duration) return;

      // Store as percentage (0-1) for consistency
      if (syncPlayheads) {
        // sharedPositionRef stores actual time
        sharedPositionRef.current = newProgress * audioRef.current.duration;
      } else {
        // clipPositionsRef stores percentages (0-1)
        clipPositionsRef.current[`${clipKey}_seek`] = newProgress;
      }

      // Update current time if this is the playing clip
      if (playingClip === clipKey) {
        audioRef.current.currentTime = newProgress * audioRef.current.duration;
      }
    },
    [playingClip, focusedIndex, reviewItems, syncPlayheads]
  );

  // Update handlePlayPause to handle the combined play+seek operation
  const handlePlayPause = useCallback(
    (clipKey: string, seekTo?: number) => {
      // Store the raw seek percentage instead of calculating time
      if (seekTo !== undefined) {
        if (syncPlayheads) {
          // In sync mode, we need to convert percentage to time
          // Store in a temporary ref that handlePlay will use
          if (
            audioRef.current &&
            audioRef.current.duration &&
            !isNaN(audioRef.current.duration)
          ) {
            sharedPositionRef.current = seekTo * audioRef.current.duration;
          }
        } else {
          clipPositionsRef.current[`${clipKey}_seek`] = seekTo;
        }
      }
      setPlayingClip((current) => (current === clipKey ? null : clipKey));

      const clipIndex = reviewItems.findIndex((item) => item.key === clipKey);
      if (clipIndex !== -1) {
        setFocusedIndex(clipIndex);
      }
    },
    [reviewItems, syncPlayheads]
  );

  // Wrap handleSelectionChange in useCallback
  const handleSelectionChange = useCallback(
    (dimensionKey: string, selectedClipKey: string) => {
      setSelections((prev) => ({
        ...prev,
        [dimensionKey]: selectedClipKey,
      }));
      // Find and focus the dimension that was just selected
      const dimensionIndex = preferenceDimensions.findIndex(
        (dim) => dim.key === dimensionKey
      );
      if (dimensionIndex !== -1) {
        setFocusedIndex(reviewItems.length + dimensionIndex);
      }
    },
    [reviewItems.length, preferenceDimensions]
  );

  // Add a helper function to check if all preferences are selected
  const areAllPreferencesSelected = useCallback(() => {
    return Object.keys(selections).length === preferenceDimensions.length;
  }, [selections, preferenceDimensions]);

  // Add this function near other audio-related functions
  const playCreditsEarnedSound = useCallback(async () => {
    try {
      const audio = new Audio(CREDITS_EARNED_SOUND_URL);
      audio.volume = 0.5;
      await audio.play();
    } catch (error) {
      // Log the error but don't show to user since this is non-critical
      console.warn('Failed to play credits earned sound:', error);
    }
  }, []);

  // Update handleSubmit to await the sound
  const handleSubmit = useCallback(async () => {
    // Check all preferences are selected
    if (!areAllPreferencesSelected()) {
      toast({
        title: 'Please make all selections',
        description: 'You must select a preference for each dimension',
        status: 'error',
      });
      return;
    }

    // Add minimum listen time validation
    if (
      !reviewItems.every(
        (item) => (listenTimes[item.key] || 0) >= minListenTimeSeconds
      )
    ) {
      toast({
        title: 'Please listen to all clips',
        description: `Each clip must be listened to for at least ${minListenTimeSeconds} seconds`,
        status: 'error',
      });
      return;
    }

    setIsSubmitting(true);
    setIsLoadingNextTask(true);
    try {
      await onSubmit(taskId, selections, feedback, listenTimes);
      await playCreditsEarnedSound(); // Wait for sound to play or fail
      resetForm();
    } catch (err) {
      toast({
        title: 'Error',
        description: err instanceof Error ? err.message : 'Failed to submit',
        status: 'error',
      });
    } finally {
      setIsSubmitting(false);
      setIsLoadingNextTask(false);
    }
  }, [
    taskId,
    selections,
    feedback,
    listenTimes,
    onSubmit,
    toast,
    resetForm,
    playCreditsEarnedSound,
    areAllPreferencesSelected,
    reviewItems,
    minListenTimeSeconds,
  ]);

  // Update the Enter hotkey to use the same validation
  useHotkeys(
    'enter',
    () => {
      if (
        !isSubmitting &&
        areAllPreferencesSelected() &&
        reviewItems.every(
          (item) => (listenTimes[item.key] || 0) >= minListenTimeSeconds
        )
      ) {
        handleSubmit();
      }
    },
    [
      isSubmitting,
      reviewItems,
      listenTimes,
      minListenTimeSeconds,
      handleSubmit,
      areAllPreferencesSelected,
    ],
    { enableOnFormTags: true }
  );

  // Add this helper function at the top of the component
  const isInputFocused = () => {
    return document.activeElement === inputRef.current;
  };

  // Update all the hotkey handlers to check for input focus
  // Update 'a' hotkey
  useHotkeys(
    'a',
    (e) => {
      if (isInputFocused()) return;
      e.preventDefault();
      if (isSubmitting) return;

      if (focusedIndex >= reviewItems.length) {
        // If in preferences, make selection
        const dimensionIndex = focusedIndex - reviewItems.length;
        if (
          dimensionIndex >= 0 &&
          dimensionIndex < preferenceDimensions.length &&
          reviewItems.length > 0
        ) {
          const dimension = preferenceDimensions[dimensionIndex];
          handleSelectionChange(dimension.key, reviewItems[0].key);
        }
      } else {
        // Play the first clip
        if (reviewItems.length > 0) {
          handlePlayPause(reviewItems[0].key);
        }
      }
    },
    [
      isSubmitting,
      focusedIndex,
      reviewItems,
      preferenceDimensions,
      handleSelectionChange,
      handlePlayPause,
    ],
    { enableOnFormTags: false }
  );

  // Update 'b' hotkey
  useHotkeys(
    'b',
    (e) => {
      if (isInputFocused()) return;
      e.preventDefault();
      if (isSubmitting) return;

      if (focusedIndex >= reviewItems.length) {
        // If in preferences, make selection
        const dimensionIndex = focusedIndex - reviewItems.length;
        if (
          dimensionIndex >= 0 &&
          dimensionIndex < preferenceDimensions.length &&
          reviewItems.length > 1
        ) {
          const dimension = preferenceDimensions[dimensionIndex];
          handleSelectionChange(dimension.key, reviewItems[1].key);
        }
      } else {
        // Play the second clip
        if (reviewItems.length > 1) {
          handlePlayPause(reviewItems[1].key);
        }
      }
    },
    [
      isSubmitting,
      focusedIndex,
      reviewItems,
      preferenceDimensions,
      handleSelectionChange,
      handlePlayPause,
    ],
    { enableOnFormTags: false }
  );

  // Update 'c' hotkey
  useHotkeys(
    'c',
    (e) => {
      if (isInputFocused()) return;
      e.preventDefault();
      if (isSubmitting) return;

      const focusedDimensionIndex = focusedIndex - reviewItems.length;
      if (
        focusedDimensionIndex >= 0 &&
        focusedDimensionIndex < preferenceDimensions.length &&
        reviewItems.length > 2
      ) {
        // If a preference dimension is focused, make a selection
        const dimension = preferenceDimensions[focusedDimensionIndex];
        handleSelectionChange(dimension.key, reviewItems[2].key);
      } else {
        // Otherwise, play the corresponding clip
        if (reviewItems[2]) {
          handlePlayPause(reviewItems[2].key);
        }
      }
    },
    [
      isSubmitting,
      focusedIndex,
      reviewItems,
      preferenceDimensions,
      handleSelectionChange,
      handlePlayPause,
    ],
    { enableOnFormTags: false }
  );

  useHotkeys(
    'n',
    (e) => {
      if (isInputFocused()) return;
      e.preventDefault();
      if (isSubmitting) return;
      const focusedDimensionIndex = focusedIndex - reviewItems.length;
      if (
        focusedDimensionIndex >= 0 &&
        focusedDimensionIndex < preferenceDimensions.length
      ) {
        const dimension = preferenceDimensions[focusedDimensionIndex];
        handleSelectionChange(dimension.key, 'neither');
      }
    },
    [
      isSubmitting,
      focusedIndex,
      reviewItems.length,
      preferenceDimensions,
      handleSelectionChange,
    ],
    { enableOnFormTags: false }
  );

  // Auto-switch toggle hotkey (only when syncPlayheads is enabled)
  // NOTE: Disabled - will revisit after further experimentation
  /* useHotkeys(
    's',
    (e) => {
      if (isInputFocused()) return;
      if (!syncPlayheads) return; // Only work when syncPlayheads is enabled
      e.preventDefault();
      if (isSubmitting) return;
      setIsAutoSwitching((prev) => !prev);
    },
    [isSubmitting, syncPlayheads],
    { enableOnFormTags: false }
  ); */

  // For skip hotkey
  useHotkeys(
    'x',
    (e) => {
      if (isInputFocused()) return;
      e.preventDefault();
      if (!isSubmitting && onSkip) {
        handleSkip();
      }
    },
    [isSubmitting, onSkip],
    { enableOnFormTags: false }
  );

  // Update the space hotkey handler
  useHotkeys(
    'space',
    (e) => {
      if (isInputFocused()) return;
      e.preventDefault(); // Prevent page scroll
      if (isSubmitting) return;

      // Get the currently focused clip if we're focused on a clip
      const focusedClip =
        focusedIndex >= 0 && focusedIndex < reviewItems.length
          ? reviewItems[focusedIndex].key
          : null;

      // If something is playing and it's not the focused clip, stop it and play the focused clip
      if (playingClip && focusedClip && playingClip !== focusedClip) {
        handlePlayPause(playingClip); // Stop current
        handlePlayPause(focusedClip); // Play new
        return;
      }

      // If something is playing and it's the focused clip, just pause it
      if (playingClip) {
        handlePlayPause(playingClip);
        return;
      }

      // If nothing is playing and we're focused on a clip, play it
      if (focusedClip) {
        handlePlayPause(focusedClip);
      }
    },
    [isSubmitting, playingClip, focusedIndex, reviewItems, handlePlayPause],
    { enableOnFormTags: false }
  );

  const handleSkip = useCallback(async () => {
    if (onSkip) {
      setIsLoadingNextTask(true);
      try {
        await onSkip();
        resetForm();
      } catch (err) {
        // If skip fails, show error and don't reset form
        toast({
          title: 'Error',
          description:
            err instanceof Error ? err.message : 'Failed to skip task',
          status: 'error',
        });
      } finally {
        setIsLoadingNextTask(false);
      }
    }
  }, [onSkip, resetForm, toast]);

  // Generate visual elements for each review item
  const visualElements = [
    { src: ORANGE_AURA_URL_WEB, color: 'orange' },
    { src: BLUE_AURA_URL, color: 'blue' },
    { src: ORANGE_AURA_URL_WEB, color: 'orange' }, // Fallback for additional items
    { src: BLUE_AURA_URL, color: 'blue' },
  ];

  // Helper to check if all tags are the same and not empty
  const allTags = reviewItems.map((item) => item.metadata?.tags?.trim() || '');
  const uniqueTags = Array.from(new Set(allTags.filter(Boolean)));
  const showSingleTagsBox = uniqueTags.length === 1 && uniqueTags[0] !== '';

  // Which clip's lyrics/tags to show in the right pane
  const activeClipKey =
    playingClip && reviewItems.some((item) => item.key === playingClip)
      ? playingClip
      : reviewItems[0]?.key;
  const activeClip = reviewItems.find((item) => item.key === activeClipKey);

  // Check if there's any metadata to display
  const hasMetadata =
    activeClip?.metadata?.prompt ||
    (showSingleTagsBox ? uniqueTags[0] : activeClip?.metadata?.tags) ||
    (showSingleTagsBox && activeClip?.metadata?.lyrics);

  // Effect to focus input when it becomes focused
  useEffect(() => {
    if (focusedIndex === -1 && inputRef.current) {
      inputRef.current.focus();
    }
  }, [focusedIndex]);

  // Effect to handle losing focus on input
  useEffect(() => {
    const handleInputBlur = () => {
      if (focusedIndex === -1) {
        setFocusedIndex(0); // Return to first clip when input loses focus
      }
    };

    const input = inputRef.current;
    if (input) {
      input.addEventListener('blur', handleInputBlur);
      return () => input.removeEventListener('blur', handleInputBlur);
    }
  }, [focusedIndex]);

  // Update the arrow key handlers to handle input focus/blur
  useHotkeys(
    'up',
    (e) => {
      e.preventDefault();
      if (document.activeElement === inputRef.current) {
        // Moving up from feedback input, go to last preference dimension
        inputRef.current?.blur();
        setFocusedIndex(reviewItems.length + preferenceDimensions.length - 1);
        return;
      }
      if (focusedIndex <= 0) {
        // If at first clip, wrap to feedback input
        inputRef.current?.focus();
        setFocusedIndex(-1);
        return;
      }
      // Moving up normally, ensure input is blurred
      inputRef.current?.blur();
      setFocusedIndex(focusedIndex - 1);
    },
    [focusedIndex, reviewItems.length, preferenceDimensions.length],
    { enableOnFormTags: true }
  );

  useHotkeys(
    'down',
    (e) => {
      e.preventDefault();
      if (focusedIndex === -1) {
        // Moving down from feedback input, explicitly blur it
        inputRef.current?.blur();
      }
      setFocusedIndex((prev) => {
        const maxIndex = reviewItems.length + preferenceDimensions.length - 1;
        if (prev === -1) {
          // If in feedback, go to first clip
          inputRef.current?.blur();
          return 0;
        }
        if (prev >= maxIndex) {
          // If at last dimension, wrap to feedback input
          inputRef.current?.focus();
          return -1;
        }
        // Moving down normally, ensure input is blurred
        inputRef.current?.blur();
        return prev + 1;
      });
    },
    [reviewItems.length, preferenceDimensions.length, setFocusedIndex],
    { enableOnFormTags: true }
  );

  // Add hotkey for feedback input focus
  useHotkeys(
    'f',
    (e) => {
      if (isInputFocused()) return;
      e.preventDefault();
      if (isSubmitting) return;
      setFocusedIndex(-1);
      inputRef.current?.focus();
    },
    [isSubmitting],
    { enableOnFormTags: false }
  );

  // Only create audio element for audio layout
  const audioElement =
    layout === 'audio' ? (
      <audio
        ref={(element) => {
          if (element && !audioRef.current) {
            audioRef.current = element;
            setupAudioEventListeners(element);
          } else if (!element && audioRef.current) {
            audioRef.current = null;
            listenersAttachedRef.current = false;
          }
        }}
        onTimeUpdate={() => {}}
        onEnded={() => {}}
        preload='auto'
        loop
      />
    ) : null;

  return (
    <Modal
      isOpen={isOpen}
      onClose={handleClose}
      isCentered
      size={
        layout === 'video' ? '5xl' : hasMetadata ? '4xl' : '3xl' // Smaller when no metadata to display
      }
    >
      <ModalOverlay bg='blackAlpha.800' />
      <ModalContent
        bg='var(--color-background-primary)'
        borderRadius='xl'
        mx={0}
        px={0}
        position='relative'
        color='var(--color-foreground-primary)'
      >
        <Stack p={4} spacing={4} mx={5} my={3}>
          {/* Position credits absolutely */}
          {credits_per_annotation && (
            <Box position='absolute' top={4} right={4}>
              <Flex
                align='center'
                gap={1}
                bg='var(--color-background-secondary)'
                px={3}
                py={1}
                borderRadius='full'
              >
                <Text fontSize='sm' color='var(--color-text-secondary)'>
                  Earn
                </Text>
                <Text
                  fontSize='sm'
                  color='var(--color-accent-pink)'
                  fontWeight='bold'
                >
                  {credits_per_annotation} credits
                </Text>
              </Flex>
            </Box>
          )}

          {/* Keep title centered without justify-between */}
          <Text fontSize='2xl' fontWeight='bold' textAlign='center'>
            {question}
          </Text>

          <Text
            fontSize='sm'
            color='var(--color-text-secondary)'
            textAlign='center'
          >
            {instructions}
          </Text>

          {/* Just keep the divider */}
          <Box px={4}>
            <Box h='1px' bg='var(--color-border-primary)' w='100%' my={1} />
          </Box>

          {/* Comparison section */}
          {layout === 'video' ? (
            <VideoComparison
              items={reviewItems}
              playingClip={playingClip}
              onPlayPause={handlePlayPause}
              setProgressMap={setProgressMap}
              listenTimes={listenTimes}
              setListenTimes={setListenTimes}
              minListenTimeSeconds={minListenTimeSeconds}
              focusedIndex={focusedIndex}
              selections={selections}
              preferenceDimensions={preferenceDimensions}
              videoRefs={videoRefs}
            />
          ) : (
            // Existing audio layout
            <>
              <Flex gap={6} w='100%' justify='center' align='flex-start'>
                <Box
                  flex={hasMetadata ? '0 0 380px' : '1'}
                  minW='320px'
                  maxW={hasMetadata ? '420px' : '600px'}
                >
                  {reviewItems.map((item, index) => (
                    <Stack
                      key={item.key}
                      spacing={2}
                      mb={index < reviewItems.length - 1 ? 6 : 0}
                      onClick={() => {
                        // Only set focus to this clip, don't affect selections
                        setFocusedIndex(index);
                      }}
                      cursor='pointer'
                    >
                      {/* Update the clip title section */}
                      <Flex justify='space-between' align='center'>
                        <Text fontSize='xs' color='var(--color-text-secondary)'>
                          {item.name}
                        </Text>
                        {(smoothProgressMap[item.key] || 0) < 100 && (
                          <Box
                            flex='1'
                            mx={3}
                            bg='var(--color-background-secondary)'
                            h='2'
                            borderRadius='full'
                            overflow='hidden'
                            opacity={(() => {
                              const dimension =
                                preferenceDimensions[
                                  focusedIndex - reviewItems.length
                                ];
                              // If neither is selected for this dimension, show all progress bars
                              if (
                                dimension &&
                                selections[dimension.key] === 'neither'
                              ) {
                                return 1;
                              }
                              // If a clip is selected, only show its progress bar
                              if (dimension && selections[dimension.key]) {
                                return selections[dimension.key] === item.key
                                  ? 1
                                  : 0;
                              }
                              // Default: show all progress bars
                              return 1;
                            })()}
                            transition='opacity 0.2s'
                          >
                            <Box
                              bg='var(--color-accent-pink)'
                              h='100%'
                              w={`${smoothProgressMap[item.key] || 0}%`}
                              transition='width 0.016s linear'
                            />
                          </Box>
                        )}
                        <Flex
                          align='center'
                          gap={2}
                          minW='80px'
                          justify='flex-end'
                        >
                          {(smoothProgressMap[item.key] || 0) < 100 && (
                            <Text
                              fontSize='xs'
                              color='var(--color-foreground-secondary)'
                            >
                              {(listenTimes[item.key] || 0) >=
                              minListenTimeSeconds
                                ? `Listen time: ${listenTimes[item.key]}s`
                                : `Listen for ${minListenTimeSeconds - (listenTimes[item.key] || 0)}s more`}
                            </Text>
                          )}
                          <Box w='12px'>
                            {(listenTimes[item.key] || 0) >=
                              minListenTimeSeconds && (
                              <Box color='var(--color-accent-pink)'>
                                <CheckIcon width='12px' height='12px' />
                              </Box>
                            )}
                          </Box>
                        </Flex>
                      </Flex>

                      {/* Remove this progress bar section */}
                      {/* <Box w='full' bg='whiteAlpha.100' h='2' borderRadius='full' overflow='hidden'>
                      <Box
                        bg='var(--color-accent-pink)'
                        h='100%'
                        w={`${smoothProgressMap[item.key] || 0}%`}
                        transition='width 0.016s linear'
                      />
                    </Box> */}
                      <Flex
                        direction='row'
                        align='flex-start'
                        w='100%'
                        minW={0}
                        gap={2}
                        bg={
                          index === focusedIndex
                            ? 'whiteAlpha.100'
                            : 'transparent'
                        }
                        p={2}
                        borderRadius='lg'
                        transition='all 0.2s'
                        sx={{
                          // No border by default
                          border: 'none',
                          // If this clip section is active, show left border
                          ...(index === focusedIndex && {
                            borderLeft: '2px solid var(--color-accent-pink)',
                            paddingLeft: '2px',
                          }),
                          // If a preference dimension is active and this clip is selected for it, show full border
                          ...(focusedIndex >= reviewItems.length &&
                            focusedIndex <
                              reviewItems.length +
                                preferenceDimensions.length &&
                            selections[
                              preferenceDimensions[
                                focusedIndex - reviewItems.length
                              ].key
                            ] === item.key && {
                              border: '2px solid var(--color-accent-pink)',
                            }),
                        }}
                      >
                        <Box position='relative'>
                          {' '}
                          {/* Add relative positioning container */}
                          <Box
                            as='video'
                            src={
                              visualElements[index % visualElements.length]
                                ?.src || ORANGE_AURA_URL_WEB
                            }
                            autoPlay
                            loop
                            playsInline
                            h='56px'
                            w='56px'
                            minW='56px'
                            borderRadius='md'
                            objectFit='cover'
                            boxShadow='md'
                            filter={
                              visualElements[index % visualElements.length]
                                ?.color === 'orange'
                                ? 'brightness(1.2)'
                                : undefined
                            } // Make orange aura lighter
                          />
                          {/* Update the shortcut icon over the video to be more visible */}
                          <Text
                            as='span'
                            bg='blackAlpha.600' // Less dark background
                            px={2}
                            py={1}
                            borderRadius='md'
                            fontSize='xs'
                            color='white'
                            position='absolute'
                            top='50%'
                            left='50%'
                            transform='translate(-50%, -50%)'
                            textAlign='center'
                            minW='24px'
                            fontWeight='bold'
                            boxShadow='0 0 8px rgba(0,0,0,0.3)' // Lighter shadow
                          >
                            {String.fromCharCode(65 + index)} {/* A, B, C */}
                          </Text>
                        </Box>
                        <Box flex='1' minW={0}>
                          <PreferenceTrack
                            clipUrl={item.url}
                            clipKey={item.key}
                            isPlaying={playingClip === item.key}
                            onPlayPause={handlePlayPause}
                            progress={progressMap[item.key] || 0}
                            onSeek={(p) => handleSeek(item.key, p)}
                            forceLoading={isLoadingNextTask}
                          />
                        </Box>
                      </Flex>
                    </Stack>
                  ))}
                </Box>
                {/* Right pane: a bit smaller, hidden on mobile or when no metadata */}
                {hasMetadata && (
                  <Box
                    display={{ base: 'none', md: 'flex' }}
                    flex='1 1 0%'
                    minW={{ md: '260px' }}
                    maxW={{ md: '520px' }}
                    width={{ md: '38%' }}
                    alignSelf='stretch'
                    flexDirection='column'
                    ml={2}
                  >
                    <Box
                      display='flex'
                      flexDirection='column'
                      justifyContent={
                        syncPlayheads &&
                        !activeClip?.metadata?.prompt &&
                        !(showSingleTagsBox
                          ? uniqueTags[0]
                          : activeClip?.metadata?.tags) &&
                        !(showSingleTagsBox && activeClip?.metadata?.lyrics)
                          ? 'center'
                          : 'flex-start'
                      }
                      h='100%'
                    >
                      {/* Auto-switch toggle - only show if syncPlayheads is true */}
                      {/* NOTE: Disabled - will revisit after further experimentation 
                    {syncPlayheads && (
                      <Flex
                        role='button'
                        tabIndex={0}
                        aria-label={
                          isAutoSwitching
                            ? 'Stop auto-switching clips (Press S)'
                            : 'Start auto-switching clips (Press S)'
                        }
                        aria-pressed={isAutoSwitching}
                        justify='center'
                        align='center'
                        gap={2}
                        mb={2}
                        fontSize='sm'
                        color='var(--color-foreground-secondary)'
                        cursor='pointer'
                        onClick={() => {
                          if (isSubmitting) return;
                          setIsAutoSwitching((prev) => !prev);
                        }}
                        onKeyDown={(e) => {
                          if (e.key === 'Enter' || e.key === ' ') {
                            e.preventDefault();
                            if (isSubmitting) return;
                            setIsAutoSwitching((prev) => !prev);
                          }
                        }}
                        _hover={{ opacity: 0.8 }}
                      >
                        <Text
                          as='span'
                          bg='var(--color-background-secondary)'
                          px={2}
                          py={0.5}
                          borderRadius='md'
                        >
                          S
                        </Text>
                        <Text>
                          {isAutoSwitching ? 'Stop auto-switch' : 'Auto-switch'}
                        </Text>
                        {isAutoSwitching && (
                          <>
                            <Text>•</Text>
                            <Flex gap={2} align='center'>
                              {reviewItems.map((item, index) => (
                                <Box key={item.key} position='relative'>
                                  <Text
                                    as='span'
                                    bg='var(--color-background-secondary)'
                                    px={2}
                                    py={0.5}
                                    borderRadius='md'
                                    color='var(--color-foreground-secondary)'
                                  >
                                    {String.fromCharCode(65 + index)}
                                  </Text>
                                  {playingClip === item.key && (
                                    <Box
                                      position='absolute'
                                      top='-2px'
                                      right='-2px'
                                      w='8px'
                                      h='8px'
                                      bg='var(--color-accent-pink)'
                                      borderRadius='full'
                                      animation='pulse 1.5s infinite'
                                    />
                                  )}
                                </Box>
                              ))}
                            </Flex>
                          </>
                        )}
                      </Flex>
                    )} */}
                      {/* Prompt above tags/lyrics, if available */}
                      {activeClip?.metadata?.prompt && (
                        <Box
                          mb={2}
                          maxH='56px'
                          overflowY='auto'
                          bg='rgba(0,0,0,0.4)'
                          color='white'
                          fontSize='sm'
                          borderRadius='md'
                          px={3}
                          py={2}
                          whiteSpace='pre-line'
                          textAlign='left'
                          boxShadow='sm'
                        >
                          <Text
                            fontWeight='bold'
                            mb={1}
                            color='gray.200'
                            fontSize='sm'
                          >
                            Prompt
                          </Text>
                          {activeClip.metadata.prompt}
                        </Box>
                      )}
                      {/* Tags above lyrics, in a scrollable box */}
                      {(showSingleTagsBox
                        ? uniqueTags[0]
                        : activeClip?.metadata?.tags) && (
                        <Box
                          mb={2}
                          maxH='56px'
                          overflowY='auto'
                          bg='rgba(0,0,0,0.4)'
                          color='white'
                          fontSize='sm'
                          borderRadius='md'
                          px={3}
                          py={2}
                          whiteSpace='pre-line'
                          textAlign='left'
                          boxShadow='sm'
                        >
                          <Text
                            fontWeight='bold'
                            mb={1}
                            color='gray.200'
                            fontSize='sm'
                          >
                            Tags
                          </Text>
                          <Text fontSize='sm'>
                            {showSingleTagsBox
                              ? uniqueTags[0]
                              : activeClip?.metadata?.tags}
                          </Text>
                        </Box>
                      )}
                      {/* Lyrics box - only show if lyrics exist */}
                      {showSingleTagsBox && activeClip?.metadata?.lyrics && (
                        <Box
                          minHeight='165px' // Minimum height
                          maxHeight='285px' // Maximum height cap
                          height='auto' // Allow growing with content
                          bg='var(--color-background-secondary)'
                          color='var(--color-foreground-primary)'
                          fontSize='sm'
                          borderRadius='md'
                          px={4}
                          py={3}
                          whiteSpace='pre-line'
                          textAlign='left'
                          boxShadow='sm'
                          flex='0 0 auto'
                          display='flex'
                          flexDirection='column'
                          justifyContent='space-between'
                        >
                          <Box flex='1' overflowY='auto'>
                            <Text
                              fontWeight='bold'
                              mb={2}
                              color='var(--color-foreground-secondary)'
                              fontSize='sm'
                            >
                              Lyrics
                            </Text>
                            <Text fontSize='sm'>
                              {activeClip.metadata.lyrics}
                            </Text>
                          </Box>
                        </Box>
                      )}
                    </Box>
                  </Box>
                )}
              </Flex>
            </>
          )}

          {/* Only render audio element for audio layout */}
          {audioElement}

          {/* Dimensions section */}
          <Stack spacing={4} position='relative' mt={6}>
            {preferenceDimensions.map((dimension, index) => {
              const isDimensionFocused =
                index + reviewItems.length === focusedIndex;
              return (
                <Flex
                  key={dimension.key}
                  px={4} // This is 16px, so we match it above
                  py={2}
                  bg={
                    isDimensionFocused
                      ? 'var(--color-background-secondary)'
                      : 'var(--color-background-primary)'
                  }
                  borderRadius='lg'
                  align='center'
                  justify='space-between'
                  minH='64px'
                  gap={2}
                  transition='all 0.2s'
                  borderLeft={
                    isDimensionFocused
                      ? '2px solid var(--color-accent-pink)'
                      : 'none'
                  }
                  onClick={() => setFocusedIndex(index + reviewItems.length)}
                  cursor='pointer'
                  _hover={{
                    bg: isDimensionFocused
                      ? 'var(--color-background-secondary)'
                      : 'var(--color-background-primary)',
                  }}
                >
                  <Text fontSize='md' fontWeight='bold'>
                    {dimension.name}
                  </Text>
                  <Flex gap={8}>
                    {reviewItems.map((item, idx) => (
                      <Box
                        key={item.key}
                        px={2}
                        py={1}
                        bg={
                          selections[dimension.key] === item.key
                            ? 'var(--color-accent-pink)'
                            : 'var(--color-background-secondary)'
                        }
                        fontSize='xs'
                        borderRadius='md'
                        color={
                          selections[dimension.key] === item.key
                            ? 'white'
                            : 'var(--color-foreground-secondary)'
                        }
                        minW='24px'
                        textAlign='center'
                        transition='all 0.2s'
                        cursor='pointer'
                        onClick={(e) => {
                          e.stopPropagation();
                          handleSelectionChange(dimension.key, item.key);
                        }}
                        _hover={{ opacity: 0.8 }}
                      >
                        {String.fromCharCode(65 + idx)}
                      </Box>
                    ))}
                    <Box
                      px={3} // Slightly wider padding for "Neither"
                      py={1}
                      bg={
                        selections[dimension.key] === 'neither'
                          ? 'var(--color-accent-pink)'
                          : 'var(--color-background-secondary)'
                      }
                      fontSize='xs'
                      borderRadius='md'
                      color={
                        selections[dimension.key] === 'neither'
                          ? 'white'
                          : 'var(--color-foreground-secondary)'
                      }
                      minW='24px'
                      textAlign='center'
                      transition='all 0.2s'
                      cursor='pointer'
                      onClick={(e) => {
                        e.stopPropagation();
                        handleSelectionChange(dimension.key, 'neither');
                      }}
                      _hover={{ opacity: 0.8 }}
                    >
                      Neither
                    </Box>
                  </Flex>
                </Flex>
              );
            })}
          </Stack>

          {/* Feedback and submit buttons */}
          <Flex gap={4} align='flex-end'>
            <Flex
              flex={1}
              border='1px solid'
              borderColor='var(--color-border-primary)'
              borderRadius='md'
              transition='all 0.2s'
              bg={focusedIndex === -1 ? 'whiteAlpha.100' : 'transparent'}
              borderLeft={
                focusedIndex === -1 ? '2px solid var(--color-accent-pink)' : ''
              }
              pl={focusedIndex === -1 ? 2 : 0}
              align='center'
              onClick={() => setFocusedIndex(-1)}
              cursor='pointer'
            >
              <Input
                ref={inputRef}
                value={feedback}
                onChange={(e) => setFeedback(e.target.value)}
                placeholder='Optional: explain your selection(s)'
                border='none'
                flex={1}
                bg='transparent'
                _focus={{
                  boxShadow: 'none',
                }}
                onKeyDown={(e) => {
                  if (
                    e.key === 'Enter' &&
                    Object.keys(selections).length ===
                      preferenceDimensions.length &&
                    !isSubmitting &&
                    reviewItems.every(
                      (item) =>
                        (listenTimes[item.key] || 0) >= minListenTimeSeconds
                    )
                  ) {
                    e.preventDefault();
                    handleSubmit();
                  }
                }}
              />
              <Text
                px={2}
                py={1}
                mx={2}
                fontSize='xs'
                color='var(--color-foreground-secondary)'
                borderColor='var(--color-border-primary)'
                bg='var(--color-background-secondary)'
                h='100%'
                display='flex'
                alignItems='center'
                minW='24px'
                textAlign='center'
                justifyContent='center'
              >
                F
              </Text>
            </Flex>
            <Button
              onClick={handleSubmit}
              disabled={
                Object.keys(selections).length < preferenceDimensions.length ||
                isSubmitting ||
                !reviewItems.every(
                  (item) => (listenTimes[item.key] || 0) >= minListenTimeSeconds
                )
              }
              variant={ButtonVariant.Primary}
              iconStart={isSubmitting ? <SpinnerSVG /> : undefined}
              className={clsx(
                'transition-opacity duration-200',
                Object.keys(selections).length < preferenceDimensions.length ||
                  !reviewItems.every(
                    (item) =>
                      (listenTimes[item.key] || 0) >= minListenTimeSeconds
                  )
                  ? 'opacity-70'
                  : 'opacity-100'
              )}
            >
              {isSubmitting ? (
                'Submitting...'
              ) : (
                <>
                  Submit
                  <Text
                    as='span'
                    ml={2}
                    px={1.5}
                    py={0.5}
                    bg='var(--color-foreground-secondary)'
                    fontSize='xs'
                    borderRadius='md'
                    color='var(--color-background-secondary)'
                  >
                    ↵
                  </Text>
                </>
              )}
            </Button>
            <Button
              onClick={handleSkip}
              variant={ButtonVariant.Tertiary}
              disabled={isSubmitting}
            >
              Skip
              <Text
                as='span'
                ml={2}
                px={2}
                py={1}
                bg='var(--color-background-secondary)'
                fontSize='xs'
                borderRadius='md'
                color='var(--color-foreground-secondary)'
                minW='24px'
                textAlign='center'
              >
                X
              </Text>
            </Button>
          </Flex>

          {/* Update the footer with more transparent styling */}
          <Flex
            justify='center'
            gap={3}
            mt={2}
            fontSize='sm'
            color='var(--color-foreground-secondary)'
          >
            {' '}
            {/* More opaque text */}
            {/* Show space shortcut only when a clip is focused */}
            {focusedIndex >= 0 && focusedIndex < reviewItems.length && (
              <>
                <Text
                  as='span'
                  bg='var(--color-background-secondary)'
                  px={2}
                  py={0.5}
                  borderRadius='md'
                >
                  Space
                </Text>{' '}
                {/* More opaque background */}
                <Text>play/pause</Text>
                <Text>•</Text>
              </>
            )}
            {/* Show A/B/C shortcuts only when a preference dimension is focused */}
            {focusedIndex >= reviewItems.length &&
              focusedIndex <
                reviewItems.length + preferenceDimensions.length && (
                <>
                  <Text
                    as='span'
                    bg='var(--color-background-secondary)'
                    px={2}
                    py={0.5}
                    borderRadius='md'
                  >
                    {reviewItems.length === 2
                      ? 'A/B'
                      : reviewItems.length === 3
                        ? 'A/B/C'
                        : 'A'}
                  </Text>
                  <Text>select</Text>
                  <Text>•</Text>
                  <Text
                    as='span'
                    bg='var(--color-background-secondary)'
                    px={2}
                    py={0.5}
                    borderRadius='md'
                  >
                    N
                  </Text>
                  <Text>neither</Text>
                  <Text>•</Text>
                </>
              )}
            {/* Always show navigation arrows */}
            <Text
              as='span'
              bg='whiteAlpha.100'
              px={2}
              py={0.5}
              borderRadius='md'
            >
              ↑/↓
            </Text>
            <Text>navigate</Text>
          </Flex>
        </Stack>
      </ModalContent>
    </Modal>
  );
};

export default PreferenceModal;
