import React, { useState, useEffect, useCallback } from 'react';
import { Modal, ModalHeader, ModalBody, ModalFooter, Button } from 'reactstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faTimes } from '@fortawesome/free-solid-svg-icons';
import './JKSessionMetronomePlayer.css';

const METRO_SOUND_LOOKUP = {
  0: "BuiltIn",
  1: "SineWave",
  2: "Beep",
  3: "Click",
  4: "Kick",
  5: "Snare",
  6: "MetroFile"
};

const METRO_SOUND_REVERSE_LOOKUP = {
  "BuiltIn": 0,
  "SineWave": 1,
  "Beep": 2,
  "Click": 3,
  "Kick": 4,
  "Snare": 5,
  "MetroFile": 6
};

const JKSessionMetronomePlayer = ({
  isOpen,
  onClose,
  metronomeState,
  jamClient,
  session,
  currentUser,
  isPopup = false
}) => {
  // Local state for controls
  const [bpm, setBpm] = useState(120);
  const [sound, setSound] = useState(2); // Default: Beep
  const [meter, setMeter] = useState(1);
  const [cricket, setCricket] = useState(false);
  const [isPlaying, setIsPlaying] = useState(false);
  const [error, setError] = useState(null);

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

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

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

  // Initialize state from metronomeState prop
  useEffect(() => {
    if (metronomeState) {
      console.log('[Metronome] Initializing from state:', metronomeState);
      if (metronomeState.bpm != null) setBpm(metronomeState.bpm);
      if (metronomeState.sound != null) setSound(metronomeState.sound);
      if (metronomeState.meter != null) setMeter(metronomeState.meter);
      if (metronomeState.cricket != null) setCricket(metronomeState.cricket);
    }
  }, [metronomeState]);

  // Handle BPM change - apply immediately if playing
  const handleBpmChange = useCallback(async (value) => {
    const numValue = parseInt(value, 10);
    if (!isNaN(numValue) && numValue >= 40 && numValue <= 300) {
      setBpm(numValue);

      // Apply change immediately if metronome is playing
      if (isPlaying && jamClient) {
        try {
          await jamClient.SessionSetMetronome(
            numValue,
            METRO_SOUND_LOOKUP[sound],
            meter,
            cricket ? 1 : 0
          );
        } catch (err) {
          console.error('[Metronome] Error updating BPM:', err);
        }
      }
    }
  }, [isPlaying, jamClient, sound, meter, cricket]);

  // Handle sound change - apply immediately if playing
  const handleSoundChange = useCallback(async (value) => {
    const numValue = parseInt(value, 10);
    if (!isNaN(numValue)) {
      setSound(numValue);

      // Apply change immediately if metronome is playing
      if (isPlaying && jamClient) {
        try {
          await jamClient.SessionSetMetronome(
            bpm,
            METRO_SOUND_LOOKUP[numValue],
            meter,
            cricket ? 1 : 0
          );
        } catch (err) {
          console.error('[Metronome] Error updating sound:', err);
        }
      }
    }
  }, [isPlaying, jamClient, bpm, meter, cricket]);

  // Handle meter change - apply immediately if playing
  const handleMeterChange = useCallback(async (value) => {
    const numValue = parseInt(value, 10);
    if (!isNaN(numValue) && numValue >= 1 && numValue <= 12) {
      setMeter(numValue);

      // Apply change immediately if metronome is playing
      if (isPlaying && jamClient) {
        try {
          await jamClient.SessionSetMetronome(
            bpm,
            METRO_SOUND_LOOKUP[sound],
            numValue,
            cricket ? 1 : 0
          );
        } catch (err) {
          console.error('[Metronome] Error updating meter:', err);
        }
      }
    }
  }, [isPlaying, jamClient, bpm, sound, cricket]);

  // Play metronome
  const handlePlay = useCallback(async () => {
    if (!jamClient) {
      setError('Audio engine not available');
      return;
    }

    setError(null);

    try {
      console.log('[Metronome] Starting metronome:', {
        bpm,
        sound: METRO_SOUND_LOOKUP[sound],
        meter,
        cricket: cricket ? 1 : 0
      });

      // Stop any current playback first
      await jamClient.SessionStopPlay();

      // Start the metronome
      await jamClient.SessionOpenMetronome(
        bpm,
        METRO_SOUND_LOOKUP[sound],
        meter,
        cricket ? 1 : 0
      );

      setIsPlaying(true);
      console.log('[Metronome] Metronome started successfully');
    } catch (err) {
      console.error('[Metronome] Error starting metronome:', err);
      setError('Failed to start metronome');
    }
  }, [jamClient, bpm, sound, meter, cricket]);

  // Stop metronome
  const handleStop = useCallback(async () => {
    if (!jamClient) {
      setError('Audio engine not available');
      return;
    }

    setError(null);

    try {
      console.log('[Metronome] Stopping metronome');

      // Use SessionStopPlay to pause metronome without destroying it
      // This allows Play to work again without reinitializing
      await jamClient.SessionStopPlay();

      setIsPlaying(false);
      console.log('[Metronome] Metronome stopped successfully');
    } catch (err) {
      console.error('[Metronome] Error stopping metronome:', err);
      setError('Failed to stop metronome');
    }
  }, [jamClient]);

  // Handle close
  const handleClose = useCallback(() => {
    console.log('[Metronome] Closing player');
    if (onClose) {
      onClose();
    }
  }, [onClose]);

  // Generate BPM options (common BPM values)
  const bpmOptions = [];
  for (let i = 40; i <= 208; i += 4) {
    bpmOptions.push(i);
  }
  // Add additional common BPMs
  [220, 240, 260, 280, 300].forEach(val => bpmOptions.push(val));

  // Render controls
  const renderControls = () => (
    <div className="metronome-player-controls">
      {/* Error display */}
      {error && (
        <div className="metronome-error">
          {error}
        </div>
      )}

      {/* Main content area with playback buttons and form */}
      <div className="metronome-main-content">
        {/* Play/Stop buttons - circular icons on the left */}
        <div className="metronome-playback-buttons">
          <button
            onClick={handlePlay}
            disabled={isPlaying}
            className={`metronome-icon-btn metronome-play-icon ${isPlaying ? 'disabled' : ''}`}
            title="Play"
          >
            <span className="play-icon">▶</span>
          </button>
          <button
            onClick={handleStop}
            disabled={!isPlaying}
            className={`metronome-icon-btn metronome-stop-icon ${!isPlaying ? 'disabled' : ''}`}
            title="Stop"
          >
            <span className="stop-icon">■</span>
          </button>
        </div>

        {/* Form layout: labels on left, controls on right */}
        <div className="metronome-form-controls">
          {/* Feature row - always shows "Metronome" */}
          <div className="metronome-form-row">
            <label className="metronome-form-label">Feature:</label>
            <select className="metronome-select" value="metronome" disabled>
              <option value="metronome">Metronome</option>
            </select>
          </div>

          {/* Sound selector */}
          <div className="metronome-form-row">
            <label className="metronome-form-label">Sound:</label>
            <select
              className="metronome-select"
              value={sound}
              onChange={(e) => handleSoundChange(e.target.value)}
            >
              <option value={0}>Built-in</option>
              <option value={1}>Sine Wave</option>
              <option value={2}>Beep</option>
              <option value={3}>Click</option>
              <option value={4}>Kick</option>
              <option value={5}>Snare</option>
            </select>
          </div>

          {/* Tempo (BPM) selector */}
          <div className="metronome-form-row">
            <label className="metronome-form-label">Tempo:</label>
            <select
              className="metronome-select"
              value={bpm}
              onChange={(e) => handleBpmChange(e.target.value)}
            >
              {bpmOptions.map(value => (
                <option key={value} value={value}>{value}</option>
              ))}
            </select>
          </div>
        </div>
      </div>

      {/* Close button centered at bottom */}
      <div className="metronome-close-container">
        <button
          onClick={handleClose}
          className="metronome-close-button"
        >
          Close
        </button>
      </div>
    </div>
  );

  // If popup mode, render directly (for WindowPortal)
  if (isPopup) {
    return (
      <div className="metronome-player-popup">
        {/* <div className="metronome-player-header">
          <h3>Metronome Controls</h3>
          <button
            className="metronome-close-btn"
            onClick={handleClose}
            title="Close"
          >
            <FontAwesomeIcon icon={faTimes} />
          </button>
        </div> */}
        <div style={{
                color: '#666',
                fontSize: '16px',
                fontWeight: 'normal'
              }}>
                <span>Metronome</span>
              
              </div>
        <div className="metronome-player-body">
          {renderControls()}
        </div>
      </div>
    );
  }

  // Otherwise, render as Modal (fallback)
  return (
    <Modal isOpen={isOpen} toggle={handleClose} className="metronome-player-modal">
      <ModalHeader toggle={handleClose}>
        Metronome Controls
      </ModalHeader>
      <ModalBody>
        {renderControls()}
      </ModalBody>
    </Modal>
  );
};

export default JKSessionMetronomePlayer;
