import React, { useState, useRef, useEffect } from 'react';
import { KGTrack } from '../../core/track/KGTrack';
import { KGMidiTrack } from '../../core/track/KGMidiTrack';
import { useProjectStore } from '../../stores/projectStore';
import { TbPiano } from 'react-icons/tb';
import { TbSettings } from 'react-icons/tb';
import KGDropdown from '../common/KGDropdown';
import { FLUIDR3_INSTRUMENT_MAP } from '../../constants/generalMidiConstants';
import { DEBUG_MODE } from '../../constants/uiConstants';
import { KGAudioInterface } from '../../core/audio-interface/KGAudioInterface';
import { AUDIO_INTERFACE_CONSTANTS } from '../../constants/coreConstants';
interface TrackInfoItemProps {
  track: KGTrack;
  index: number;
  isDragging: boolean;
  isDragOver: boolean;
  onTrackClick?: () => void;
  onTrackNameEdit: (track: KGTrack, newName: string) => void; // eslint-disable-line no-unused-vars
  onDragStart: (e: React.DragEvent<HTMLDivElement>, index: number) => void; // eslint-disable-line no-unused-vars
  onDragOver: (e: React.DragEvent<HTMLDivElement>, index: number) => void; // eslint-disable-line no-unused-vars
  onDrop: (e: React.DragEvent<HTMLDivElement>) => void; // eslint-disable-line no-unused-vars
  onDragEnd: (e: React.DragEvent<HTMLDivElement>) => void; // eslint-disable-line no-unused-vars
}

const TrackInfoItem: React.FC<TrackInfoItemProps> = ({
  track,
  index,
  isDragging,
  isDragOver,
  onTrackClick,
  onTrackNameEdit,
  onDragStart,
  onDragOver,
  onDrop,
  onDragEnd
}) => {
  const { selectedTrackId, setSelectedTrack, removeTrack, toggleInstrumentSelectionForTrack, tracks: allTracks } = useProjectStore();
  const isSelected = selectedTrackId === track.getId().toString();
  // Inline instrument dropdown removed; use InstrumentSelection panel instead
  
  // Initialize current instrument from track data
  const getTrackInstrument = () => {
    if (track instanceof KGMidiTrack) {
      return track.getInstrument();
    }
    return 'acoustic_grand_piano'; // Default fallback
  };
  
  const [currentInstrument, setCurrentInstrument] = useState(getTrackInstrument());
  const [showSettingsDropdown, setShowSettingsDropdown] = useState(false);
  const settingsDropdownRef = useRef<HTMLDivElement>(null);
  const suppressDragRef = useRef(false);
  const [volume, setVolume] = useState(track.getVolume());
  // Local flag to track slider interaction; not used for rendering
  const isAdjustingVolumeRef = useRef(false);
  const [muted, setMuted] = useState(false);
  const [solo, setSolo] = useState(false);

  // Close dropdown when clicking outside
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (
        showSettingsDropdown && 
        settingsDropdownRef.current && 
        !settingsDropdownRef.current.contains(event.target as Node)
      ) {
        setShowSettingsDropdown(false);
      }
    };
    
    document.addEventListener('mousedown', handleClickOutside);
    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, [showSettingsDropdown]);

  // Sync currentInstrument state with actual track instrument value
  const instrumentFromTrack = track instanceof KGMidiTrack ? track.getInstrument() : 'acoustic_grand_piano';
  useEffect(() => {
    setCurrentInstrument(instrumentFromTrack);
  }, [instrumentFromTrack]);

  // Sync volume UI with model when tracks state changes (e.g., load, undo/redo, external updates)
  useEffect(() => {
    setVolume(track.getVolume());
  }, [allTracks, track]);

  // Sync mute/solo UI with audio interface state on track/project changes
  useEffect(() => {
    setMuted(false);
    setSolo(false);
  }, [allTracks, track]);
  
  // Handle track name edit within the component
  const handleTrackNameClick = (e: React.MouseEvent) => {
    e.stopPropagation(); // Prevent opening piano roll when clicking track name
    
    const newName = prompt("Enter track name:", track.getName());
    if (newName) {
      // Call the parent handler with the new name
      onTrackNameEdit(track, newName);
    }
  };

  // Prevent drag reordering when interacting with interactive controls
  const handleMouseDownCapture = (e: React.MouseEvent<HTMLDivElement>) => {
    const target = e.target as HTMLElement;
    const isInteractive = !!target.closest(
      'input, button, .volume-slider, .instrument-dropdown, .settings-dropdown'
    );
    suppressDragRef.current = isInteractive;
  };

  const handleDragStartWrapper = (e: React.DragEvent<HTMLDivElement>) => {
    if (suppressDragRef.current) {
      e.preventDefault();
      e.stopPropagation();
      suppressDragRef.current = false;
      return;
    }
    onDragStart(e, index);
  };

  const handleVolumeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    e.stopPropagation();
    const next = Number(e.target.value) / 100;
    isAdjustingVolumeRef.current = true;
    setVolume(next);
    try {
      // Live preview: update audio only while sliding
      KGAudioInterface.instance().setTrackVolume(track.getId().toString(), next);
    } catch (err) {
      console.error('Failed to update live volume:', err);
    }
  };

  const commitVolumeChange = () => {
    // Only commit if value actually changed from model to avoid extra commands
    const modelVolume = track.getVolume();
    if (Math.abs(modelVolume - volume) < 1e-6) {
      isAdjustingVolumeRef.current = false;
      return;
    }
    try {
      useProjectStore.getState().updateTrackProperties(track.getId(), { volume });
    } catch (err) {
      console.error('Failed to persist volume:', err);
    } finally {
      isAdjustingVolumeRef.current = false;
    }
  };

  const handleResetVolume = (e: React.MouseEvent<HTMLButtonElement>) => {
    e.stopPropagation();
    const defaultVolume = AUDIO_INTERFACE_CONSTANTS.DEFAULT_TRACK_VOLUME;
    setVolume(defaultVolume);
    try {
      useProjectStore.getState().updateTrackProperties(track.getId(), { volume: defaultVolume });
    } catch (err) {
      console.error('Failed to reset volume:', err);
    }
  };

  const handleToggleMute = (e: React.MouseEvent<HTMLButtonElement>) => {
    e.stopPropagation();
    const next = !muted;
    setMuted(next);
    try {
      KGAudioInterface.instance().setTrackMute(track.getId().toString(), next);
    } catch (err) {
      console.error('Failed to toggle mute:', err);
    }
  };

  const handleToggleSolo = (e: React.MouseEvent<HTMLButtonElement>) => {
    e.stopPropagation();
    const next = !solo;
    setSolo(next);
    try {
      KGAudioInterface.instance().setTrackSolo(track.getId().toString(), next);
    } catch (err) {
      console.error('Failed to toggle solo:', err);
    }
  };

  // Handle track click
  const handleTrackClick = () => {
    // Select this track when clicked
    setSelectedTrack(track.getId().toString());
    
    if (onTrackClick) {
      onTrackClick();
    }
  };

  // Inline instrument change removed; handled by InstrumentSelection panel

  // Handle piano button click
  const handlePianoButtonClick = (e: React.MouseEvent) => {
    e.stopPropagation();
    // Select this track as active when opening instrument panel
    setSelectedTrack(track.getId().toString());
    // Toggle global InstrumentSelection panel (it follows selectedTrackId)
    toggleInstrumentSelectionForTrack();
  };

  // Handle settings button click
  const handleSettingsButtonClick = (e: React.MouseEvent) => {
    e.stopPropagation();
    setShowSettingsDropdown(!showSettingsDropdown);
  };

  // Handle settings action
  const handleSettingsAction = async (action: string) => {
    if (action === 'Delete Track') {
      const confirmed = window.confirm(`Are you sure you want to delete track "${track.getName()}"?`);
      if (confirmed) {
        try {
          if (DEBUG_MODE.TRACK_INFO) {
            console.log('Delete track confirmed for:', track.getName());
          }

          // Clear selection if this track is selected
          // if (selectedTrackId === track.getId().toString()) {
          //   setSelectedTrack(null);
          // }

          // Delete the track using the command system
          await removeTrack(track.getId());
          
          // Close the settings dropdown
          setShowSettingsDropdown(false);
        } catch (error) {
          console.error('Failed to delete track:', error);
          alert('Failed to delete track. Please try again.');
        }
      }
    }
  };

  return (
    <div 
      className={`track-info ${isDragOver ? 'drag-over' : ''} ${isDragging ? 'dragging' : ''} ${isSelected ? 'selected' : ''}`}
      data-test-id={`track-info-${track.getId()}`}
      onClick={handleTrackClick}
      onMouseDownCapture={handleMouseDownCapture}
      draggable={true}
      onDragStart={handleDragStartWrapper}
      onDragOver={(e) => onDragOver(e, index)}
      onDrop={onDrop}
      onDragEnd={onDragEnd}
    >
      <div className="track-controls">
        <div className="track-name-and-volume">
          <div className="instrument-image">
            <img 
              src={`${import.meta.env.BASE_URL}resources/instruments/${String(FLUIDR3_INSTRUMENT_MAP[currentInstrument as keyof typeof FLUIDR3_INSTRUMENT_MAP]?.image || 'piano.png')}`} 
              alt={String(FLUIDR3_INSTRUMENT_MAP[currentInstrument as keyof typeof FLUIDR3_INSTRUMENT_MAP]?.displayName || currentInstrument)}
              width="64"
              height="64"
            />
          </div>
          <div className="track-name-and-controls">
            <div 
              className="track-name"
              onClick={handleTrackNameClick}
            >
              {track.getName()}
            </div>
            <div className="volume-slider">
              <input
                type="range"
                min="0"
                max="100"
                value={Math.round(volume * 100)}
                onChange={handleVolumeChange}
                onMouseDown={(e) => { e.stopPropagation(); isAdjustingVolumeRef.current = true; }}
                onMouseUp={(e) => { e.stopPropagation(); commitVolumeChange(); }}
                onTouchStart={(e) => { e.stopPropagation(); isAdjustingVolumeRef.current = true; }}
                onTouchEnd={(e) => { e.stopPropagation(); commitVolumeChange(); }}
                onBlur={commitVolumeChange}
                onClick={(e) => e.stopPropagation()}
              />
              <button
                className="reset-volume"
                title="Reset volume"
                aria-label="Reset volume"
                onClick={handleResetVolume}
              >
                ↺
              </button>
            </div>
          </div>
        </div>
        <div className="pan-controls">
          <button className={`solo${solo ? ' active' : ''}`} onClick={handleToggleSolo}>S</button>
          <button className={`mute${muted ? ' active' : ''}`} onClick={handleToggleMute}>M</button>
          <div>
            <button className="instrument" onClick={handlePianoButtonClick}>
              <TbPiano />
            </button>
          </div>
          <div style={{ position: 'relative' }} ref={settingsDropdownRef}>
            <button className="settings" onClick={handleSettingsButtonClick}>
              <TbSettings />
            </button>
            <div style={{ position: 'absolute', top: '100%', left: 0, zIndex: 10000 }}>
              <KGDropdown
                options={['Delete Track']}
                value={''}
                onChange={handleSettingsAction}
                label="Settings"
                hideButton={true}
                isOpen={showSettingsDropdown}
                onToggle={setShowSettingsDropdown}
                className="settings-dropdown"
              />
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

export default TrackInfoItem; 