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

type NoiseType = 'white' | 'pink' | 'brown' | 'rain' | 'cafe';

const NOISE_PRESETS: { id: NoiseType; label: string; icon: string }[] = [
  { id: 'white', label: 'White', icon: '⚪' },
  { id: 'pink', label: 'Pink', icon: '🌸' },
  { id: 'brown', label: 'Brown', icon: '🤎' },
  { id: 'rain', label: 'Rain', icon: '🌧️' },
  { id: 'cafe', label: 'Cafe', icon: '☕' },
];

export default function WhiteNoise() {
  const [active, setActive] = useState<NoiseType | null>(null);
  const [volume, setVolume] = useState(0.25);
  const audioCtxRef = useRef<AudioContext | null>(null);
  const noiseSourceRef = useRef<AudioBufferSourceNode | null>(null);
  const gainRef = useRef<GainNode | null>(null);
  const filterRef = useRef<BiquadFilterNode | null>(null);

  const stopNoise = useCallback(() => {
    if (noiseSourceRef.current) {
      try { noiseSourceRef.current.stop(); } catch {}
      noiseSourceRef.current = null;
    }
    if (audioCtxRef.current) {
      // keep context for reuse
    }
    setActive(null);
  }, []);

  const startNoise = useCallback((type: NoiseType) => {
    stopNoise();

    const ctx = audioCtxRef.current || new (window.AudioContext || (window as any).webkitAudioContext)();
    audioCtxRef.current = ctx;

    const bufferSize = 2 * ctx.sampleRate;
    const buffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate);
    const data = buffer.getChannelData(0);

    // Generate noise
    let lastOut = 0;
    for (let i = 0; i < bufferSize; i++) {
      let white = Math.random() * 2 - 1;
      if (type === 'pink') {
        // Pink noise approx
        data[i] = (lastOut + (0.02 * white)) / 1.02;
        lastOut = data[i];
        data[i] *= 3.5; // gain
      } else if (type === 'brown') {
        // Brown/red noise
        data[i] = (lastOut + (0.02 * white)) / 1.02;
        lastOut = data[i];
        data[i] *= 3.5;
      } else {
        data[i] = white;
      }
    }

    const source = ctx.createBufferSource();
    source.buffer = buffer;
    source.loop = true;

    const gain = ctx.createGain();
    gain.gain.value = volume;

    let node: AudioNode = source;

    if (type === 'rain' || type === 'cafe') {
      const filter = ctx.createBiquadFilter();
      filter.type = type === 'rain' ? 'lowpass' : 'bandpass';
      filter.frequency.value = type === 'rain' ? 800 : 1200;
      filter.Q.value = type === 'rain' ? 0.7 : 1.5;
      node.connect(filter);
      node = filter;
      filterRef.current = filter;
    }

    node.connect(gain);
    gain.connect(ctx.destination);

    source.start();
    noiseSourceRef.current = source;
    gainRef.current = gain;

    setActive(type);
  }, [volume, stopNoise]);

  const toggle = (type: NoiseType) => {
    if (active === type) {
      stopNoise();
    } else {
      startNoise(type);
    }
  };

  const changeVolume = (v: number) => {
    setVolume(v);
    if (gainRef.current) {
      gainRef.current.gain.value = v;
    }
  };

  return (
    <div className="p-4">
      <h3 className="text-sm font-bold text-kira-plum mb-3 flex items-center gap-2">
        <span>🌬️</span> White Noise
      </h3>

      <div className="flex flex-wrap gap-2 mb-3">
        {NOISE_PRESETS.map((p) => (
          <button
            key={p.id}
            onClick={() => toggle(p.id)}
            className={`text-xs px-3 py-1.5 rounded-full transition-all flex items-center gap-1 ${
              active === p.id
                ? 'bg-kira-pink text-white shadow'
                : 'bg-white/50 text-kira-plum/70 hover:bg-kira-glow'
            }`}
          >
            <span>{p.icon}</span>
            <span>{p.label}</span>
          </button>
        ))}
      </div>

      <div className="flex items-center gap-2 text-xs text-kira-plum/60">
        <span>Vol</span>
        <input
          type="range"
          min={0}
          max={0.6}
          step={0.02}
          value={volume}
          onChange={(e) => changeVolume(parseFloat(e.target.value))}
          className="flex-1 accent-kira-pink"
        />
        <span className="tabular-nums w-8 text-right">{Math.round(volume * 100)}%</span>
      </div>

      {active && (
        <div className="mt-2 text-[10px] text-kira-mint/70">Playing {active} noise — body double approved ✨</div>
      )}
    </div>
  );
}
