'use client';

/**
 * HybridAudioProvider - Context provider for hybrid audio player.
 *
 * Provides audio state, controls, and analysis data to child components.
 * Uses native HTML5 audio for playback with Web Audio API for visualization only.
 */

import { createContext, useContext, useMemo, useEffect, useRef, type ReactNode } from 'react';
import {
  useHybridAudio,
  type UseHybridAudioOptions,
  type HybridAudioState,
  type HybridAudioControls,
  type HybridWebAudioAPI,
} from '../hooks/useHybridAudio';
import { useHybridAudioAnalysis } from '../hooks/useHybridAudioAnalysis';
import { useVisualization } from '../hooks/useVisualization';
import type { AudioLevels } from '../effects';

// =============================================================================
// TYPES
// =============================================================================

export interface HybridAudioContextValue {
  // Audio state
  state: HybridAudioState;

  // Controls
  controls: HybridAudioControls;

  // Web Audio (for visualizations)
  webAudio: HybridWebAudioAPI;

  // Audio levels (for reactive effects)
  audioLevels: AudioLevels;

  // Audio element ref (for custom integrations)
  audioRef: React.RefObject<HTMLAudioElement | null>;
}

// =============================================================================
// CONTEXT
// =============================================================================

const HybridAudioContext = createContext<HybridAudioContextValue | null>(null);

// =============================================================================
// PROVIDER
// =============================================================================

export interface HybridAudioProviderProps extends UseHybridAudioOptions {
  children: ReactNode;
}

export function HybridAudioProvider({ children, ...options }: HybridAudioProviderProps) {
  // Load persisted settings (shared with visualization)
  const { settings: savedSettings, setSetting } = useVisualization();

  // Use saved settings as initial values
  const effectiveOptions = {
    ...options,
    initialVolume: savedSettings.volume,
    loop: savedSettings.isLooping,
  };

  const { audioRef, state, controls, webAudio } = useHybridAudio(effectiveOptions);

  // Track if we've applied initial settings
  const hasAppliedInitialSettings = useRef(false);

  // Apply saved settings after audio is ready (for hydration timing)
  useEffect(() => {
    if (!state.isReady || hasAppliedInitialSettings.current) return;
    hasAppliedInitialSettings.current = true;

    // Apply saved volume and loop settings
    controls.setVolume(savedSettings.volume);
    controls.setLoop(savedSettings.isLooping);
  }, [state.isReady, savedSettings, controls]);

  // Persist settings when they change
  useEffect(() => {
    if (!state.isReady) return;

    // Only save if values actually changed
    if (state.volume !== savedSettings.volume) {
      setSetting('volume', state.volume);
    }
    if (state.isLooping !== savedSettings.isLooping) {
      setSetting('isLooping', state.isLooping);
    }
  }, [state.isReady, state.volume, state.isLooping, savedSettings, setSetting]);

  // Audio analysis for reactive effects
  const audioLevels = useHybridAudioAnalysis(webAudio.analyser, state.isPlaying);

  const value = useMemo<HybridAudioContextValue>(
    () => ({
      state,
      controls,
      webAudio,
      audioLevels,
      audioRef,
    }),
    [state, controls, webAudio, audioLevels, audioRef]
  );

  return <HybridAudioContext.Provider value={value}>{children}</HybridAudioContext.Provider>;
}

// =============================================================================
// HOOKS
// =============================================================================

/**
 * Access full hybrid audio context
 */
export function useHybridAudioContext(): HybridAudioContextValue {
  const context = useContext(HybridAudioContext);
  if (!context) {
    throw new Error('useHybridAudioContext must be used within HybridAudioProvider');
  }
  return context;
}

/**
 * Access audio state only (read-only)
 */
export function useHybridAudioState(): HybridAudioState {
  const { state } = useHybridAudioContext();
  return state;
}

/**
 * Access audio controls only (no state re-renders)
 */
export function useHybridAudioControls(): HybridAudioControls {
  const { controls } = useHybridAudioContext();
  return controls;
}

/**
 * Access audio levels for reactive effects
 */
export function useHybridAudioLevels(): AudioLevels {
  const { audioLevels } = useHybridAudioContext();
  return audioLevels;
}

/**
 * Access Web Audio API for custom visualizations
 */
export function useHybridWebAudio(): HybridWebAudioAPI {
  const { webAudio } = useHybridAudioContext();
  return webAudio;
}
