import React, { useState, useEffect, useRef, useMemo, useCallback } from 'react';
import { Modal, ModalHeader, ModalBody, ModalFooter, Button } from 'reactstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faPlay, faPause, faStop } from '@fortawesome/free-solid-svg-icons';
import useMediaActions from '../../hooks/useMediaActions';
import playIcon from '../../assets/img/client/play.svg';
import stopIcon from '../../assets/img/client/stop.svg';

const JKSessionBackingTrackPlayer = ({
  isOpen,
  onClose,
  backingTrack,
  jamClient,
  session,
  currentUser,
  isPopup = false
}) => {
  const { closeMedia } = useMediaActions();

  const [isPlaying, setIsPlaying] = useState(false);
  const [isLooping, setIsLooping] = useState(false);
  const [currentTime, setCurrentTime] = useState('0:00');
  const [duration, setDuration] = useState('0:00');
  const [currentPositionMs, setCurrentPositionMs] = useState(0);
  const [durationMs, setDurationMs] = useState(0);

  // Error handling state
  const [error, setError] = useState(null);
  const [errorType, setErrorType] = useState(null); // 'file', 'network', 'playback', 'general'

  // Loading states
  const [isLoadingDuration, setIsLoadingDuration] = useState(true);
  const [isOperating, setIsOperating] = useState(false); // Operation in progress

  // Visibility tracking for performance optimization
  const [isVisible, setIsVisible] = useState(true);

  // UAT-003 Investigation: Track seek attempts while paused
  const pendingSeekPositionRef = useRef(null);

  // Error tracking for polling
  const consecutivePollingErrorsRef = useRef(0);

  // Track page visibility for performance optimization
  useEffect(() => {
    const handleVisibilityChange = () => {
      setIsVisible(!document.hidden);
    };

    document.addEventListener('visibilitychange', handleVisibilityChange);
    return () => document.removeEventListener('visibilitychange', handleVisibilityChange);
  }, []);

  // Utility function to format milliseconds to M:SS format
  const formatTime = useCallback((ms) => {
    // Handle undefined, null, or NaN values
    if (ms == null || isNaN(ms) || ms < 0) {
      return '0:00';
    }
    const seconds = Math.floor(ms / 1000);
    const minutes = Math.floor(seconds / 60);
    const remainingSeconds = seconds % 60;
    return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
  }, []);

  // Error handling utilities
  const handleError = useCallback((type, message, err) => {
    console.error(`[BTP] ${type}:`, message, err);
    setError(message);
    setErrorType(type);
  }, []);

  const clearError = useCallback(() => {
    setError(null);
    setErrorType(null);
  }, []);

  const retryOperation = useCallback(() => {
    clearError();
    // Specific retry logic handled by individual operations
  }, [clearError]);

  // Helper to get backing track path (handles both string and object formats)
  const getBackingTrackPath = useCallback((backingTrack) => {
    if (!backingTrack) return null;
    // If backingTrack is a string, it's the path itself (popup mode)
    if (typeof backingTrack === 'string') return backingTrack;
    // If it's an object, extract the path property (modal mode)
    return backingTrack.path || null;
  }, []);

  useEffect(() => {
    let ignore = false;

    // For popup mode, treat as always "open" since the popup window itself indicates open state
    const shouldInitialize = (isOpen || isPopup) && backingTrack && jamClient;

    if (shouldInitialize) {
      // Initialize player state when opened
      setIsPlaying(false);
      setCurrentTime('0:00');
      setCurrentPositionMs(0);

      // Fetch and set duration immediately when track loads (async)
      const fetchDuration = async () => {
        if (ignore) return;
        setIsLoadingDuration(true);

        try {
          if (!jamClient) {
            if (!ignore) {
              handleError('general', 'Audio engine not available', null);
              setIsLoadingDuration(false);
            }
            return;
          }

          const durationInMs = await jamClient.SessionGetTracksPlayDurationMs();

          // Check ignore AFTER async operation
          if (ignore) return;

          // Convert string to number (jamClient returns string values)
          const validDuration = parseInt(durationInMs, 10) || 0;

          // Check for invalid duration (file error)
          if (validDuration === 0 || isNaN(validDuration)) {
            handleError('file', 'Failed to load track duration. The file may be invalid or unsupported.', null);
            setDuration('0:00');
            setDurationMs(0);
            setIsLoadingDuration(false);
            return;
          }

          // File format validation (silent - errors handled elsewhere)
          const tenHoursMs = 10 * 60 * 60 * 1000; // 10 hours
          const oneSecondMs = 1000;
          // Validation logic exists but logs removed for production

          setDurationMs(validDuration);
          setDuration(formatTime(validDuration));
          clearError(); // Clear any previous errors
          setIsLoadingDuration(false);
        } catch (error) {
          if (!ignore) {
            handleError('file', 'Failed to load track duration', error);
            setDuration('0:00');
            setDurationMs(0);
            setIsLoadingDuration(false);
          }
        }
      };

      fetchDuration();
    }

    return () => {
      ignore = true;
    };
  }, [isOpen, isPopup, backingTrack, jamClient, handleError, formatTime, clearError]);

  // Playback monitoring with visibility-aware polling
  useEffect(() => {
    let intervalId = null;

    if (isPlaying && jamClient) {
      // Determine polling frequency based on visibility
      // 500ms when visible, 2000ms when hidden (reduce CPU usage)
      const pollingInterval = isVisible ? 500 : 2000;

      // Start polling when playing (async)
      intervalId = setInterval(async () => {
        try {
          if (!jamClient) return;

          // Await all async jamClient calls
          const positionMs = await jamClient.SessionCurrrentPlayPosMs();
          const durationInMs = await jamClient.SessionGetTracksPlayDurationMs();
          const trackIsPlayingRaw = await jamClient.isSessionTrackPlaying();

          // Convert strings to numbers (jamClient returns string values)
          const validPosition = parseInt(positionMs, 10) || 0;
          const validDuration = parseInt(durationInMs, 10) || 0;
          // Convert to boolean (jamClient may return string "true"/"false" or number 1/0)
          const trackIsPlaying = trackIsPlayingRaw === true || trackIsPlayingRaw === 'true' || trackIsPlayingRaw === 1;

          // Check if track reached the end OR position reset (native client auto-looped)
          // Native client may reset position to 0 when track ends, even if isPlaying is still true
          const positionReset = currentPositionMs > validDuration * 0.8 && validPosition < validDuration * 0.2;
          const atEnd = validPosition >= validDuration && validDuration > 0;

          if ((atEnd || positionReset) && validDuration > 0) {
            if (isLooping) {
              // Loop enabled: restart playback from beginning
              await jamClient.SessionStopPlay();
              await jamClient.SessionTrackSeekMs(0);
              await jamClient.SessionStartPlay(1);
              setCurrentPositionMs(0);
              setCurrentTime('0:00');
              // Keep isPlaying true since we're continuing
              consecutivePollingErrorsRef.current = 0;
              return;
            } else {
              // Loop disabled: stop playback and reset
              await jamClient.SessionStopPlay();
              await jamClient.SessionTrackSeekMs(0);
              setIsPlaying(false);
              setCurrentPositionMs(0);
              setCurrentTime('0:00');
              consecutivePollingErrorsRef.current = 0;
              return;
            }
          }

          // Only update state if values actually changed (lazy updates)
          if (validPosition !== currentPositionMs) {
            setCurrentPositionMs(validPosition);
            setCurrentTime(formatTime(validPosition));
          }

          if (validDuration !== durationMs) {
            setDurationMs(validDuration);
            setDuration(formatTime(validDuration));
          }

          // Sync playing state if changed
          if (trackIsPlaying !== isPlaying) {
            setIsPlaying(trackIsPlaying);
          }

          // Reset error counter on successful poll
          consecutivePollingErrorsRef.current = 0;
        } catch (error) {
          console.error('[BTP] Error polling playback status:', error);
          consecutivePollingErrorsRef.current += 1;

          // After 3 consecutive failures, show error and stop polling
          if (consecutivePollingErrorsRef.current >= 3) {
            handleError('network', 'Lost connection to audio engine', error);
            setIsPlaying(false);
            if (intervalId) {
              clearInterval(intervalId);
            }
          }
        }
      }, pollingInterval);
    }

    // Cleanup: clear interval on pause/stop or unmount
    return () => {
      if (intervalId) {
        clearInterval(intervalId);
      }
    };
  }, [isPlaying, jamClient, backingTrack, isVisible, currentPositionMs, durationMs, isLooping, formatTime, handleError]);

  // Cleanup on unmount: stop playback to prevent stale state
  useEffect(() => {
    return () => {
      // Stop playback when component unmounts
      if (jamClient && isPlaying) {
        jamClient.SessionStopPlay().catch((err) => {
          console.error('[BTP] Error stopping playback on unmount:', err);
        });
      }
    };
  }, [jamClient, isPlaying]);

  const handlePlay = useCallback(async () => {
    if (isOperating) {
      return; // Prevent rapid clicks
    }
    setIsOperating(true);

    try {
      if (!jamClient) {
        handleError('general', 'Audio engine not available', null);
        return;
      }

      clearError(); // Clear any previous errors

      if (isPlaying) {
        // Pause
        await jamClient.SessionPausePlay();
        setIsPlaying(false);
      } else {
        // UAT-003 Fix: Apply pending seek position before resuming
        if (pendingSeekPositionRef.current !== null) {
          // Stop, seek, then play
          await jamClient.SessionStopPlay();
          await jamClient.SessionTrackSeekMs(pendingSeekPositionRef.current);

          // Update UI state
          setCurrentPositionMs(pendingSeekPositionRef.current);
          setCurrentTime(formatTime(pendingSeekPositionRef.current));

          // Clear pending seek
          pendingSeekPositionRef.current = null;
        }

        // Check if we're at the very end (within 50ms to avoid false positives from slider dragging)
        const atEnd = currentPositionMs >= durationMs - 50 && durationMs > 0;
        // Check if we're at the beginning (position 0 or very close)
        const atBeginning = currentPositionMs < 100;

        if (atEnd || atBeginning) {
          // Native client needs Stop -> Seek -> Play sequence to reliably start
          // This handles both "at end" and "at beginning after track finished" cases
          await jamClient.SessionStopPlay();
          await jamClient.SessionTrackSeekMs(0);
          setCurrentPositionMs(0);
          setCurrentTime('0:00');
        }

        // Play (1 = normal playback mode)
        await jamClient.SessionStartPlay(1);

        // Verify playback actually started (small delay to let native client update)
        await new Promise(resolve => setTimeout(resolve, 100));
        const actuallyPlayingRaw = await jamClient.isSessionTrackPlaying();
        // Convert to boolean (jamClient may return string "true"/"false" or number 1/0)
        const actuallyPlaying = actuallyPlayingRaw === true || actuallyPlayingRaw === 'true' || actuallyPlayingRaw === 1;

        setIsPlaying(actuallyPlaying);
      }
    } catch (error) {
      handleError('playback', 'Failed to start playback', error);
      // Reset isPlaying to ensure UI is consistent
      setIsPlaying(false);
    } finally {
      setIsOperating(false);
    }
  }, [isOperating, jamClient, isPlaying, currentPositionMs, durationMs, formatTime, handleError, clearError]);

  const handleStop = useCallback(async () => {
    if (isOperating) return; // Prevent rapid clicks
    setIsOperating(true);

    try {
      if (!jamClient) {
        handleError('general', 'Audio engine not available', null);
        return;
      }

      await jamClient.SessionStopPlay();
      setIsPlaying(false);
      setCurrentTime('0:00');
      setCurrentPositionMs(0);

      // UAT-003: Clear any pending seek position when stopping
      pendingSeekPositionRef.current = null;
      clearError(); // Clear any previous errors
    } catch (error) {
      handleError('playback', 'Failed to stop playback', error);
      // Force reset UI state anyway
      setIsPlaying(false);
      setCurrentTime('0:00');
      setCurrentPositionMs(0);
      pendingSeekPositionRef.current = null;
    } finally {
      setIsOperating(false);
    }
  }, [isOperating, jamClient, handleError, clearError]);

  const handleLoopChange = useCallback(async (e) => {
    const shouldLoop = e.target.checked;
    const previousLoop = isLooping;
    setIsLooping(shouldLoop);

    try {
      if (!jamClient) {
        handleError('general', 'Audio engine not available', null);
        setIsLooping(previousLoop); // Revert checkbox
        return;
      }

      // Set loop state using SessionSetBackingTrackFileLoop
      // This requires the file path and loop boolean
      const trackPath = getBackingTrackPath(backingTrack);
      if (!trackPath) {
        handleError('playback', 'No backing track available for loop change', null);
        setIsLooping(previousLoop); // Revert checkbox
        return;
      }

      await jamClient.SessionSetBackingTrackFileLoop(trackPath, shouldLoop);
    } catch (error) {
      handleError('playback', 'Failed to toggle loop', error);
      setIsLooping(previousLoop); // Revert checkbox on error
    }
  }, [isLooping, jamClient, backingTrack, handleError, getBackingTrackPath]);

  /*
   * UAT-003 Fix: Seek while paused limitation workaround
   *
   * Problem: jamClient.SessionTrackSeekMs() doesn't register when track is paused.
   *
   * Solution: State machine approach
   * - When seeking while paused, verify if position changed
   * - If not, store pending seek position in pendingSeekPositionRef
   * - Before resuming playback, apply pending seek with:
   *   SessionStopPlay() → SessionTrackSeekMs() → SessionStartPlay()
   *
   * This provides consistent UX: seek works whether playing or paused.
   *
   * See: .planning/phases/02-backing-track-seek-controls/02-01-ISSUES.md (UAT-003)
   */
  const handleSeek = useCallback(async (e) => {
    const seekPositionMs = parseInt(e.target.value);
    const previousPosition = currentPositionMs;

    // Update local state immediately for responsive UI (don't block on isOperating)
    setCurrentPositionMs(seekPositionMs);
    setCurrentTime(formatTime(seekPositionMs));

    try {
      if (!jamClient) {
        handleError('general', 'Audio engine not available', null);
        return;
      }

      // Seek the native client to the new position
      await jamClient.SessionTrackSeekMs(seekPositionMs);

      // If seeking while playing, verify playback is still active
      // (native client may auto-stop when seeking to end of track)
      if (isPlaying) {
        // Small delay to let native client process the seek
        await new Promise(resolve => setTimeout(resolve, 50));
        const stillPlayingRaw = await jamClient.isSessionTrackPlaying();
        // Convert to boolean (jamClient may return string "true"/"false" or number 1/0)
        const stillPlaying = stillPlayingRaw === true || stillPlayingRaw === 'true' || stillPlayingRaw === 1;
        if (!stillPlaying) {
          setIsPlaying(false);
          // If we're at the end, reset position for clean state
          if (seekPositionMs >= durationMs - 50 && durationMs > 0) {
            await jamClient.SessionTrackSeekMs(0);
            setCurrentPositionMs(0);
            setCurrentTime('0:00');
          }
        }
      } else {
        // UAT-003: Verify position after seek (especially when paused)
        const positionAfterSeek = await jamClient.SessionCurrrentPlayPosMs();
        const parsedPosition = parseInt(positionAfterSeek, 10) || 0;

        // If paused and position didn't change, store for application on resume
        if (parsedPosition !== seekPositionMs) {
          pendingSeekPositionRef.current = seekPositionMs;
        } else {
          pendingSeekPositionRef.current = null;
        }
      }
    } catch (error) {
      handleError('playback', 'Failed to seek to position', error);
      // Revert UI position to last known good
      setCurrentPositionMs(previousPosition);
      setCurrentTime(formatTime(previousPosition));
    }
  }, [currentPositionMs, formatTime, jamClient, isPlaying, durationMs, handleError]);

  const handleClose = useCallback(async () => {
    try {
      // Stop the backing track when closing
      await handleStop();
      // Close media through context to update global state
      await closeMedia();
    } catch (error) {
      console.error('Error closing backing track player:', error);
    } finally {
      // Always close via onClose callback - this triggers proper cleanup
      // For popup mode: unmounts WindowPortal which closes the window
      // For modal mode: closes the modal
      onClose();
    }
  }, [handleStop, closeMedia, onClose]);

  const getFileName = useCallback((backingTrack) => {
    if (!backingTrack) return 'Unknown File';

    // Get the path first
    const path = getBackingTrackPath(backingTrack);
    if (path) {
      return path.split('/').pop().split('\\').pop();
    }

    // Fallback to name if it's an object
    if (typeof backingTrack === 'object' && backingTrack.name) {
      return backingTrack.name;
    }
    return 'Audio File';
  }, [getBackingTrackPath]);



  // Render popup version
  if (isPopup) {
    return (
      <div style={{
        width: '100vw',
        height: '100vh',
        display: 'flex',
        flexDirection: 'column',
        // fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", sans-serif',
        backgroundColor: '#f8f9fa'
      }}>
        
        {/* Popup Content */}
        <div style={{
          flex: 1,
          padding: '20px',
          overflow: 'auto',
          display: 'flex',
          flexDirection: 'column',
          // alignItems: 'center',
          // justifyContent: 'center'
        }}>
          <div style={{ maxWidth: '420px', width: '100%' }}>
            <div style={{ display: 'flex', flexDirection: 'column', gap: '20px' }}>
              {/* Title */}
              <div style={{
                color: '#666',
                fontSize: '14px',
                fontWeight: 'normal'
              }}>
                <span>Backing Track: </span>
                {getFileName(backingTrack)}
              </div>

              {/* Error Display */}
              {error && (
                <div style={{
                  padding: '12px',
                  backgroundColor: errorType === 'file' || errorType === 'network' ? '#f8d7da' : '#fff3cd',
                  color: errorType === 'file' || errorType === 'network' ? '#721c24' : '#856404',
                  border: `1px solid ${errorType === 'file' || errorType === 'network' ? '#f5c6cb' : '#ffeaa7'}`,
                  borderRadius: '4px',
                  display: 'flex',
                  flexDirection: 'column',
                  gap: '8px'
                }}>
                  <div>{error}</div>
                  <div style={{ display: 'flex', gap: '8px' }}>
                    <Button size="sm" color="secondary" onClick={clearError}>
                      Dismiss
                    </Button>
                    {(errorType === 'network' || errorType === 'file') && (
                      <Button size="sm" color="primary" onClick={retryOperation}>
                        Retry
                      </Button>
                    )}
                  </div>
                </div>
              )}

              {/* Loading indicator */}
              {isLoadingDuration && (
                <div style={{ textAlign: 'center', color: '#6c757d', fontSize: '14px' }}>
                  Loading track...
                </div>
              )}

              {/* Controls Section */}
              <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
                {/* Circular Buttons and Seek Bar */}
                <div style={{ display: 'flex', alignItems: 'center', gap: '3px' }}>
                  {/* Play Button - Circular */}
                  <button
                    onClick={handlePlay}
                    disabled={!backingTrack || isLoadingDuration || isOperating || error}
                    style={{
                      width: '44px',
                      height: '44px',
                      borderRadius: '50%',
                      border: 'none',
                      //backgroundColor: isPlaying ? '#6c757d' : '#5b9bd5',
                      backgroundColor: '#eceff9',
                      //color: 'white',
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                      cursor: (!backingTrack || isLoadingDuration || isOperating || error) ? 'not-allowed' : 'pointer',
                      opacity: (!backingTrack || isLoadingDuration || isOperating || error) ? 0.5 : 1,
                      outline: 'none',
                      flexShrink: 0
                    }}
                  >
                    {/* <FontAwesomeIcon icon={isPlaying ? faPause : faPlay} style={{ fontSize: '14px' }} /> */}
                    { isPlaying ? (
                      <FontAwesomeIcon icon={faPause} style={{ fontSize: '14px' }} /> 
                    ) : (
                      <img src={playIcon} alt='play' />
                    ) }
                    
                  </button>

                  {/* Stop Button - Circular */}
                  <button
                    onClick={handleStop}
                    disabled={!backingTrack || isLoadingDuration || isOperating}
                    style={{
                      width: '44px',
                      height: '44ßpx',
                      borderRadius: '50%',
                      border: 'none',
                      backgroundColor: '#eceff9',
                      color: 'white',
                      display: 'flex',
                      alignItems: 'center',
                      justifyContent: 'center',
                      cursor: (!backingTrack || isLoadingDuration || isOperating) ? 'not-allowed' : 'pointer',
                      opacity: (!backingTrack || isLoadingDuration || isOperating) ? 0.5 : 1,
                      outline: 'none',
                      flexShrink: 0
                    }}
                  >
                    {/* <FontAwesomeIcon icon={faStop} style={{ fontSize: '12px' }} /> */}
                    <img src={stopIcon} alt="stop" />
                  </button>

                  {/* Time and Seek Bar */}
                  <div style={{ display: 'flex', alignItems: 'center', flex: 1, gap: '8px' }}>
                    <span style={{ fontSize: '14px', color: '#666', minWidth: '35px' }}>{currentTime}</span>
                    <input
                      type="range"
                      min="0"
                      max={durationMs || 100}
                      value={currentPositionMs}
                      onChange={handleSeek}
                      disabled={!backingTrack || isLoadingDuration}
                      style={{
                        flex: 1,
                        height: '4px',
                        borderRadius: '2px',
                        outline: 'none',
                        background: `linear-gradient(to right, #5b9bd5 0%, #5b9bd5 ${(currentPositionMs / (durationMs || 1)) * 100}%, #ddd ${(currentPositionMs / (durationMs || 1)) * 100}%, #ddd 100%)`,
                        WebkitAppearance: 'none',
                        cursor: (!backingTrack || isLoadingDuration) ? 'not-allowed' : 'pointer'
                      }}
                    />
                    <span style={{ fontSize: '14px', color: '#666', minWidth: '35px' }}>{duration}</span>
                  </div>
                </div>

                {/* Loop Checkbox */}
                <div style={{ display: 'flex', justifyContent: 'flex-start', paddingLeft: '0px' }}>
                  <label style={{
                    display: 'flex',
                    alignItems: 'center',
                    cursor: 'pointer',
                    fontSize: '14px',
                    color: '#666',
                    userSelect: 'none'
                  }}>
                    <input
                      type="checkbox"
                      checked={isLooping}
                      onChange={handleLoopChange}
                      style={{ marginRight: '8px', cursor: 'pointer' }}
                    />
                    Loop playback
                  </label>
                </div>
              </div>

              {/* Close Button */}
              <div style={{ display: 'flex', justifyContent: 'center', marginTop: '8px' }}>
                <button
                  onClick={handleClose}
                  style={{
                    padding: '8px 24px',
                    border: '1px solid #ccc',
                    borderRadius: '4px',
                    backgroundColor: 'white',
                    color: '#666',
                    cursor: 'pointer',
                    fontSize: '14px',
                    outline: 'none'
                  }}
                >
                  Close
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  }

  // Render modal version (original)
  return (
    <Modal isOpen={isOpen} toggle={onClose} size="md" centered>
      <ModalHeader toggle={onClose}>
        Backing Track Player
      </ModalHeader>

      <ModalBody>
        <div style={{ display: 'flex', flexDirection: 'column', gap: '10px' }}>
          {/* Title */}
          <div style={{
            color: '#666',
            fontSize: '14px',
            fontWeight: 'normal'
          }}>
            <span style={{ color: '#999' }}>Backing Track: </span>
            {getFileName(backingTrack)}
          </div>

          {/* Error Display */}
          {error && (
            <div style={{
              padding: '12px',
              backgroundColor: errorType === 'file' || errorType === 'network' ? '#f8d7da' : '#fff3cd',
              color: errorType === 'file' || errorType === 'network' ? '#721c24' : '#856404',
              border: `1px solid ${errorType === 'file' || errorType === 'network' ? '#f5c6cb' : '#ffeaa7'}`,
              borderRadius: '4px',
              display: 'flex',
              flexDirection: 'column',
              gap: '8px'
            }}>
              <div>{error}</div>
              <div style={{ display: 'flex', gap: '8px' }}>
                <button
                  onClick={clearError}
                  style={{
                    padding: '4px 12px',
                    border: '1px solid #ccc',
                    borderRadius: '4px',
                    backgroundColor: 'white',
                    cursor: 'pointer',
                    fontSize: '12px'
                  }}
                >
                  Dismiss
                </button>
                {(errorType === 'network' || errorType === 'file') && (
                  <button
                    onClick={retryOperation}
                    style={{
                      padding: '4px 12px',
                      border: '1px solid #5b9bd5',
                      borderRadius: '4px',
                      backgroundColor: '#5b9bd5',
                      color: 'white',
                      cursor: 'pointer',
                      fontSize: '12px'
                    }}
                  >
                    Retry
                  </button>
                )}
              </div>
            </div>
          )}

          {/* Loading indicator */}
          {isLoadingDuration && (
            <div style={{ textAlign: 'center', color: '#6c757d', fontSize: '14px' }}>
              Loading track...
            </div>
          )}

          {/* Controls Section */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
            {/* Circular Buttons and Seek Bar */}
            <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
              {/* Play Button - Circular */}
              <button
                onClick={handlePlay}
                disabled={!backingTrack || isLoadingDuration || isOperating || error}
                style={{
                  width: '36px',
                  height: '36px',
                  borderRadius: '50%',
                  border: 'none',
                  backgroundColor: isPlaying ? '#6c757d' : '#5b9bd5',
                  color: 'white',
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'center',
                  cursor: (!backingTrack || isLoadingDuration || isOperating || error) ? 'not-allowed' : 'pointer',
                  opacity: (!backingTrack || isLoadingDuration || isOperating || error) ? 0.5 : 1,
                  outline: 'none',
                  flexShrink: 0
                }}
              >
                <FontAwesomeIcon icon={isPlaying ? faPause : faPlay} style={{ fontSize: '14px' }} />
              </button>

              {/* Stop Button - Circular */}
              <button
                onClick={handleStop}
                disabled={!backingTrack || isLoadingDuration || isOperating}
                style={{
                  width: '36px',
                  height: '36px',
                  borderRadius: '50%',
                  border: 'none',
                  backgroundColor: '#b0b0b0',
                  color: 'white',
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'center',
                  cursor: (!backingTrack || isLoadingDuration || isOperating) ? 'not-allowed' : 'pointer',
                  opacity: (!backingTrack || isLoadingDuration || isOperating) ? 0.5 : 1,
                  outline: 'none',
                  flexShrink: 0
                }}
              >
                <FontAwesomeIcon icon={faStop} style={{ fontSize: '12px' }} />
              </button>

              {/* Time and Seek Bar */}
              <div style={{ display: 'flex', alignItems: 'center', flex: 1, gap: '8px' }}>
                <span style={{ fontSize: '14px', color: '#666', minWidth: '35px', fontFamily: 'monospace' }}>{currentTime}</span>
                <input
                  type="range"
                  min="0"
                  max={durationMs || 100}
                  value={currentPositionMs}
                  onChange={handleSeek}
                  disabled={!backingTrack || isLoadingDuration}
                  style={{
                    flex: 1,
                    height: '4px',
                    borderRadius: '2px',
                    outline: 'none',
                    background: `linear-gradient(to right, #5b9bd5 0%, #5b9bd5 ${(currentPositionMs / (durationMs || 1)) * 100}%, #ddd ${(currentPositionMs / (durationMs || 1)) * 100}%, #ddd 100%)`,
                    WebkitAppearance: 'none',
                    cursor: (!backingTrack || isLoadingDuration) ? 'not-allowed' : 'pointer'
                  }}
                />
                <span style={{ fontSize: '14px', color: '#666', minWidth: '35px', fontFamily: 'monospace' }}>{duration}</span>
              </div>
            </div>

            {/* Loop Checkbox */}
            <div style={{ display: 'flex', justifyContent: 'flex-start', paddingLeft: '0px' }}>
              <label style={{
                display: 'flex',
                alignItems: 'center',
                cursor: 'pointer',
                fontSize: '14px',
                color: '#666',
                userSelect: 'none'
              }}>
                <input
                  type="checkbox"
                  checked={isLooping}
                  onChange={handleLoopChange}
                  style={{ marginRight: '8px', cursor: 'pointer' }}
                />
                Loop playback
              </label>
            </div>
          </div>
        </div>
      </ModalBody>

      <ModalFooter>
        <button
          onClick={onClose}
          style={{
            padding: '8px 24px',
            border: '1px solid #ccc',
            borderRadius: '4px',
            backgroundColor: 'white',
            color: '#666',
            cursor: 'pointer',
            fontSize: '14px',
            outline: 'none'
          }}
        >
          Close
        </button>
      </ModalFooter>
    </Modal>
  );
};

export default JKSessionBackingTrackPlayer;
