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

const STORAGE_KEY = 'deckhearth:scanner-sound';

function isMobileViewport() {
  if (typeof window === 'undefined') return false;
  return window.matchMedia('(max-width: 768px)').matches;
}

function readPersistedPreference() {
  if (typeof window === 'undefined') return null;
  try {
    const stored = localStorage.getItem(STORAGE_KEY);
    if (stored === 'true') return true;
    if (stored === 'false') return false;
  } catch {
    // localStorage unavailable (e.g. private browsing on some browsers)
  }
  return null;
}

/**
 * Scan sound feedback via the Web Audio API.
 *
 * - Persists the enabled/disabled preference to localStorage.
 * - Defaults to ON on mobile, OFF on desktop.
 * - AudioContext created lazily on first playback (browser autoplay policy).
 */
export function useScannerSound() {
  const [enabled, setEnabledState] = useState(() => {
    const persisted = readPersistedPreference();
    return persisted ?? isMobileViewport();
  });

  const audioCtxRef = useRef(null);

  const setEnabled = useCallback((value) => {
    setEnabledState((prev) => {
      const next = typeof value === 'function' ? value(prev) : value;
      try {
        localStorage.setItem(STORAGE_KEY, String(next));
      } catch {
        // ignore
      }
      return next;
    });
  }, []);

  const getAudioContext = useCallback(() => {
    if (!audioCtxRef.current) {
      const AudioCtx = window.AudioContext || window.webkitAudioContext;
      if (!AudioCtx) return null;
      audioCtxRef.current = new AudioCtx();
    }
    if (audioCtxRef.current.state === 'suspended') {
      audioCtxRef.current.resume().catch(() => {});
    }
    return audioCtxRef.current;
  }, []);

  const playTone = useCallback(
    (frequency, durationMs) => {
      if (!enabled) return;
      const ctx = getAudioContext();
      if (!ctx) return;

      const oscillator = ctx.createOscillator();
      const gain = ctx.createGain();

      oscillator.type = 'sine';
      oscillator.frequency.setValueAtTime(frequency, ctx.currentTime);

      gain.gain.setValueAtTime(0.3, ctx.currentTime);
      gain.gain.exponentialRampToValueAtTime(
        0.001,
        ctx.currentTime + durationMs / 1000
      );

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

      oscillator.start(ctx.currentTime);
      oscillator.stop(ctx.currentTime + durationMs / 1000);
    },
    [enabled, getAudioContext]
  );

  const playSuccess = useCallback(() => playTone(880, 50), [playTone]);
  const playError = useCallback(() => playTone(440, 80), [playTone]);

  useEffect(() => {
    return () => {
      if (audioCtxRef.current) {
        audioCtxRef.current.close().catch(() => {});
        audioCtxRef.current = null;
      }
    };
  }, []);

  return { enabled, setEnabled, playSuccess, playError };
}
