import { useRef, useState, useEffect } from 'react';

export function RetroSoundTest() {
  const audioCtxRef = useRef<AudioContext | null>(null);
  const [isRepeating, setIsRepeating] = useState(false);
  const repeatTimeoutRef = useRef<number | null>(null);

  const getAudioCtx = () => {
    if (!audioCtxRef.current) {
      audioCtxRef.current = new (window.AudioContext || (window as any).webkitAudioContext)();
    }
    if (audioCtxRef.current.state === 'suspended') {
      audioCtxRef.current.resume();
    }
    return audioCtxRef.current;
  };

  // Helper: Create audio chain (oscillator → filter → gain → output)
  const createFilteredOscillator = (
    ctx: AudioContext,
    startTime: number,
    hz: number,
    volume: number,
    oscType: OscillatorType,
    filterFreq: number
  ) => {
    const osc = ctx.createOscillator();
    const gain = ctx.createGain();
    const filter = ctx.createBiquadFilter();
    
    osc.type = oscType;
    osc.frequency.setValueAtTime(hz, startTime);
    
    filter.type = 'lowpass';
    filter.frequency.setValueAtTime(filterFreq, startTime);
    filter.Q.setValueAtTime(1, startTime);
    
    gain.gain.setValueAtTime(volume, startTime);
    
    osc.connect(filter).connect(gain).connect(ctx.destination);
    
    return { osc, gain };
  };

  const playSound = (
    freq: number, 
    type: OscillatorType, 
    duration: number, 
    vol: number, 
    fade: boolean = false,
    useFilter: boolean = false,
    filterFreq: number = 800
  ) => {
    const ctx = getAudioCtx();
    const startTime = ctx.currentTime;

    if (useFilter) {
      const { osc, gain } = createFilteredOscillator(ctx, startTime, freq, vol, type, filterFreq);
      if (fade) {
        gain.gain.exponentialRampToValueAtTime(0.0001, startTime + duration);
      }
      osc.start(startTime);
      osc.stop(startTime + duration);
    } else {
      const osc = ctx.createOscillator();
      const gain = ctx.createGain();
      
      osc.type = type;
      osc.frequency.setValueAtTime(freq, startTime);
      gain.gain.setValueAtTime(vol, startTime);
      
      if (fade) {
        gain.gain.exponentialRampToValueAtTime(0.0001, startTime + duration);
      }
      
      osc.connect(gain).connect(ctx.destination);
      osc.start(startTime);
      osc.stop(startTime + duration);
    }
  };

  // White noise (for 8-bit style noise)
  const playNoise = (duration: number, vol: number, fade: boolean = false) => {
    const ctx = getAudioCtx();
    const bufferSize = ctx.sampleRate * duration;
    const buffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate);
    const output = buffer.getChannelData(0);
    
    for (let i = 0; i < bufferSize; i++) {
      output[i] = Math.random() * 2 - 1;
    }
    
    const noise = ctx.createBufferSource();
    noise.buffer = buffer;
    
    const gain = ctx.createGain();
    gain.gain.setValueAtTime(vol, ctx.currentTime);
    if (fade) {
      gain.gain.exponentialRampToValueAtTime(0.0001, ctx.currentTime + duration);
    }
    
    noise.connect(gain);
    gain.connect(ctx.destination);
    noise.start();
  };

  // Play sound repeatedly with random delays
  const playRepeating = () => {
    // Play the sound - triangle wave with low-pass filter for dull, machine-like tone
    playSound(1000, 'triangle', 0.08, 0.1, false, true, 800);
    playNoise(0.09, 0.02);
    
    // Schedule next play with random delay (0-1000ms)
    const randomDelay = Math.random() * 900;
    repeatTimeoutRef.current = window.setTimeout(playRepeating, randomDelay);
  };

  // Toggle repeating sound
  const toggleRepeat = () => {
    if (isRepeating) {
      // Stop repeating
      if (repeatTimeoutRef.current !== null) {
        clearTimeout(repeatTimeoutRef.current);
        repeatTimeoutRef.current = null;
      }
      setIsRepeating(false);
    } else {
      // Start repeating
      setIsRepeating(true);
      playRepeating();
    }
  };

  // Cleanup on unmount
  useEffect(() => {
    return () => {
      if (repeatTimeoutRef.current !== null) {
        clearTimeout(repeatTimeoutRef.current);
      }
    };
  }, []);

  // Beep composer - creates sequential beeps with automatic timing
  const createBeepSequence = () => {
    const ctx = getAudioCtx();
    let currentTime = ctx.currentTime;
    
    return {
      beep: (
        hz: number, 
        duration: number, 
        fade: boolean = false, 
        autoOffset: boolean = true, 
        oscType: OscillatorType = 'triangle',
        volume: number = 0.12,
        filterFreq: number = 800,
        addNoise: boolean = false
      ) => {
        const { osc, gain } = createFilteredOscillator(ctx, currentTime, hz, volume, oscType, filterFreq);
        
        if (fade) {
          gain.gain.exponentialRampToValueAtTime(0.0001, currentTime + duration);
        }
        
        osc.start(currentTime);
        osc.stop(currentTime + duration + 0.05);
        
        // Add vintage noise/hiss for realism
        if (addNoise) {
          const noiseBufferSize = ctx.sampleRate * duration;
          const noiseBuffer = ctx.createBuffer(1, noiseBufferSize, ctx.sampleRate);
          const noiseOutput = noiseBuffer.getChannelData(0);
          
          for (let i = 0; i < noiseBufferSize; i++) {
            noiseOutput[i] = (Math.random() * 2 - 1) * 0.02; // Low-level noise
          }
          
          const noiseSource = ctx.createBufferSource();
          noiseSource.buffer = noiseBuffer;
          
          const noiseGain = ctx.createGain();
          noiseGain.gain.setValueAtTime(0.8, currentTime);
          
          noiseSource.connect(noiseGain).connect(ctx.destination);
          noiseSource.start(currentTime);
        }
        
        if (autoOffset) currentTime += duration;
        return currentTime;
      },

      // Multi-tone beep (plays multiple frequencies simultaneously)
      multiBeep: (
        frequencies: number[],
        duration: number,
        fade: boolean = false,
        autoOffset: boolean = true,
        oscType: OscillatorType | OscillatorType[] = 'square',
        volume: number = 0.08,
        filterFreq: number = 1200,
        addNoise: boolean = true
      ) => {
        // Play multiple oscillators at once
        frequencies.forEach((hz, index) => {
          const vol = volume * (index === 0 ? 1 : 0.7); // First tone louder
          const type = Array.isArray(oscType) ? oscType[index] || oscType[0] : oscType;
          const { osc, gain } = createFilteredOscillator(ctx, currentTime, hz, vol, type, filterFreq);
          
          if (fade) {
            gain.gain.exponentialRampToValueAtTime(0.0001, currentTime + duration);
          }
          
          osc.start(currentTime);
          osc.stop(currentTime + duration + 0.05);
        });

        // Add noise
        if (addNoise) {
          const noiseBufferSize = ctx.sampleRate * duration;
          const noiseBuffer = ctx.createBuffer(1, noiseBufferSize, ctx.sampleRate);
          const noiseOutput = noiseBuffer.getChannelData(0);
          
          for (let i = 0; i < noiseBufferSize; i++) {
            noiseOutput[i] = (Math.random() * 2 - 1) * 0.006; // Much quieter vintage hiss
          }
          
          const noiseSource = ctx.createBufferSource();
          noiseSource.buffer = noiseBuffer;
          
          const noiseGain = ctx.createGain();
          noiseGain.gain.setValueAtTime(0.3, currentTime); // Reduced from 1.0
          
          noiseSource.connect(noiseGain).connect(ctx.destination);
          noiseSource.start(currentTime);
        }

        if (autoOffset) currentTime += duration;
        return currentTime;
      },
      
      gap: (duration: number) => {
        currentTime += duration;
        return currentTime;
      },
      
      getTime: () => currentTime,
      setTime: (time: number) => { currentTime = time; }
    };
  };

  // Patlabor notification pattern - authentic multi-tone from spectrum analysis
  const patlaborPattern = () => {
    const seq = createBeepSequence();
    // Timing from spectrogram: 0.8s beep, 0.1s gap, 0.8s beep, 0.1s gap, 1.5s beep
    seq.multiBeep([1000, 3000], 0.7, false, true, 'sawtooth'); // First beep with dual tones
    seq.multiBeep([800, 2500], 0.35, false, true, 'sawtooth');
    seq.multiBeep([1000, 3000], 0.7, false, true, 'sawtooth');
    seq.multiBeep([800, 2500], 0.35, false, true, 'sawtooth');
    seq.multiBeep([1000, 3000], 2.85, false, true, 'sawtooth');
  };

  // Custom demo pattern (high-low-high with square waves)
  const customPattern = () => {
    const seq = createBeepSequence();
    seq.beep(1400, 0.6, false, true, 'square');
    seq.gap(0.2);
    seq.beep(700, 0.6, false, true, 'square');
    seq.gap(0.2);
    seq.beep(1400, 1.0, true, true, 'square');
  };

  // Rising beeps sweep
  const risingBeeps = () => {
    for (let i = 0; i < 8; i++) {
      setTimeout(() => {
        playSound(1800 + i * 50, 'square', 0.03, 0.08);
        playNoise(0.03, 0.015);
      }, i * 40);
    }
  };

  return (
    <div style={{ padding: '20px', fontFamily: 'monospace', maxWidth: '900px' }}>
      <h1>🔊 8-Bit & Industrial Buzzer Generator</h1>
      <p style={{ color: '#7f8c8d', fontSize: '14px', marginTop: '5px' }}>
        Harsh, digital, lo-fi sounds with noise and dissonance - NOT musical tones
      </p>
      
      {/* Single Preset */}
      <div style={{ marginTop: '20px', padding: '15px', backgroundColor: '#ecf0f1', borderRadius: '8px' }}>
        <h3 style={{ margin: '0 0 10px 0' }}>Preset Sound</h3>
        <button 
          style={{ padding: '10px 20px', backgroundColor: '#7f8c8d', color: 'white', border: 'none', borderRadius: '4px', cursor: 'pointer', fontWeight: 'bold' }}
          onClick={risingBeeps}
        >
          RISING BEEPS (sweep)
        </button>
      </div>

      {/* Repeating Sound Toggle */}
      <div style={{ marginTop: '20px', padding: '15px', backgroundColor: isRepeating ? '#e74c3c' : '#27ae60', borderRadius: '8px' }}>
        <h3 style={{ margin: '0 0 10px 0', color: 'white' }}>🔁 Test</h3>
        <button 
          style={{ 
            padding: '12px 24px', 
            backgroundColor: isRepeating ? '#c0392b' : '#229954', 
            color: 'white', 
            border: '2px solid white',
            borderRadius: '4px', 
            cursor: 'pointer', 
            fontWeight: 'bold',
            fontSize: '16px'
          }}
          onClick={toggleRepeat}
        >
          {isRepeating ? '⏹ STOP' : '▶ START'} Random Buzzer
        </button>
        <h3 style={{ margin: '15px 0 10px 0', color: 'white' }}>🤖 Patlabor Notify Pattern</h3>
        <p style={{ fontSize: '12px', color: 'white', margin: '0 0 10px 0' }}>
          0.8s → 0.1s gap → 0.8s → 0.1s gap → 1.5s | 1000Hz+3000Hz | Total: 3.3s
        </p>
        <div style={{ display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
          <button 
            style={{ 
              padding: '12px 24px', 
              backgroundColor: '#1e5a8e', 
              color: 'white', 
              border: '2px solid #3498db',
              borderRadius: '4px', 
              cursor: 'pointer', 
              fontWeight: 'bold',
              fontSize: '16px'
            }}
            onClick={patlaborPattern}
          >
            🔔 Pattern Notify
          </button>
          
          <button 
            style={{ 
              padding: '12px 24px', 
              backgroundColor: '#2e7d32', 
              color: 'white', 
              border: '2px solid #4caf50',
              borderRadius: '4px', 
              cursor: 'pointer', 
              fontWeight: 'bold',
              fontSize: '16px'
            }}
            onClick={customPattern}
          >
            🎵 Custom Pattern
          </button>
        </div>
      </div>

      {/* Raw Noise Test */}
      <div style={{ marginTop: '20px', padding: '15px', backgroundColor: '#2c3e50', borderRadius: '8px', color: 'white' }}>
        <h3 style={{ margin: '0 0 10px 0' }}>🎛️ Raw Sound Elements</h3>
        <div style={{ display: 'flex', gap: '10px', flexWrap: 'wrap' }}>
          {[320,1000].map(freq => (
            <button 
              key={freq}
              style={{ padding: '8px 15px', backgroundColor: '#34495e', color: 'white', border: 'none', borderRadius: '4px' }}
              onClick={() => {
                playSound(freq, 'triangle', 2, 0.1, false, true, 800);
              }}
            >
              {freq} Hz triangle+filter
            </button>
          ))}
        </div>
      </div>
    </div>
  );
}