/**
 * Audio Manager System
 * Manages game sounds and music with Howler.js
 */

export interface AudioAsset {
  id: string;
  name: string;
  type: 'sound' | 'music';
  url: string;
  volume: number;
  loop: boolean;
}

export interface AudioConfig {
  masterVolume: number;
  soundVolume: number;
  musicVolume: number;
  soundEnabled: boolean;
  musicEnabled: boolean;
}

export class AudioManager {
  private config: AudioConfig = {
    masterVolume: 0.8,
    soundVolume: 0.7,
    musicVolume: 0.5,
    soundEnabled: true,
    musicEnabled: true,
  };

  private assets: Map<string, AudioAsset> = new Map();
  private currentMusic: string | null = null;

  constructor() {
    this.initializeDefaultAssets();
  }

  /**
   * Initialize default audio assets
   */
  private initializeDefaultAssets(): void {
    const defaultAssets: AudioAsset[] = [
      // Spin sounds
      {
        id: 'spin-start',
        name: 'Spin Start',
        type: 'sound',
        url: '/audio/spin-start.mp3',
        volume: 0.7,
        loop: false,
      },
      {
        id: 'spin-end',
        name: 'Spin End',
        type: 'sound',
        url: '/audio/spin-end.mp3',
        volume: 0.7,
        loop: false,
      },
      {
        id: 'reel-stop',
        name: 'Reel Stop',
        type: 'sound',
        url: '/audio/reel-stop.mp3',
        volume: 0.6,
        loop: false,
      },

      // Win sounds
      {
        id: 'small-win',
        name: 'Small Win',
        type: 'sound',
        url: '/audio/small-win.mp3',
        volume: 0.6,
        loop: false,
      },
      {
        id: 'medium-win',
        name: 'Medium Win',
        type: 'sound',
        url: '/audio/medium-win.mp3',
        volume: 0.7,
        loop: false,
      },
      {
        id: 'big-win',
        name: 'Big Win',
        type: 'sound',
        url: '/audio/big-win.mp3',
        volume: 0.8,
        loop: false,
      },
      {
        id: 'jackpot',
        name: 'Jackpot',
        type: 'sound',
        url: '/audio/jackpot.mp3',
        volume: 1.0,
        loop: false,
      },

      // Bonus sounds
      {
        id: 'bonus-trigger',
        name: 'Bonus Trigger',
        type: 'sound',
        url: '/audio/bonus-trigger.mp3',
        volume: 0.8,
        loop: false,
      },
      {
        id: 'free-spin',
        name: 'Free Spin',
        type: 'sound',
        url: '/audio/free-spin.mp3',
        volume: 0.7,
        loop: false,
      },
      {
        id: 'cascade',
        name: 'Cascade',
        type: 'sound',
        url: '/audio/cascade.mp3',
        volume: 0.6,
        loop: false,
      },

      // UI sounds
      {
        id: 'button-click',
        name: 'Button Click',
        type: 'sound',
        url: '/audio/button-click.mp3',
        volume: 0.5,
        loop: false,
      },
      {
        id: 'error',
        name: 'Error',
        type: 'sound',
        url: '/audio/error.mp3',
        volume: 0.6,
        loop: false,
      },

      // Background music
      {
        id: 'neon-nights-music',
        name: 'Neon Nights Music',
        type: 'music',
        url: '/audio/neon-nights.mp3',
        volume: 0.5,
        loop: true,
      },
      {
        id: 'dragons-fury-music',
        name: "Dragon's Fury Music",
        type: 'music',
        url: '/audio/dragons-fury.mp3',
        volume: 0.5,
        loop: true,
      },
      {
        id: 'cosmic-quest-music',
        name: 'Cosmic Quest Music',
        type: 'music',
        url: '/audio/cosmic-quest.mp3',
        volume: 0.5,
        loop: true,
      },
      {
        id: 'retro-arcade-music',
        name: 'Retro Arcade Music',
        type: 'music',
        url: '/audio/retro-arcade.mp3',
        volume: 0.5,
        loop: true,
      },
      {
        id: 'lobby-music',
        name: 'Lobby Music',
        type: 'music',
        url: '/audio/lobby.mp3',
        volume: 0.4,
        loop: true,
      },
    ];

    for (const asset of defaultAssets) {
      this.assets.set(asset.id, asset);
    }
  }

  /**
   * Get audio asset
   */
  getAsset(assetId: string): AudioAsset | null {
    return this.assets.get(assetId) || null;
  }

  /**
   * Get all audio assets
   */
  getAllAssets(): AudioAsset[] {
    return Array.from(this.assets.values());
  }

  /**
   * Get all sounds
   */
  getAllSounds(): AudioAsset[] {
    return Array.from(this.assets.values()).filter((a) => a.type === 'sound');
  }

  /**
   * Get all music
   */
  getAllMusic(): AudioAsset[] {
    return Array.from(this.assets.values()).filter((a) => a.type === 'music');
  }

  /**
   * Play sound
   */
  playSound(assetId: string): void {
    if (!this.config.soundEnabled) return;

    const asset = this.assets.get(assetId);
    if (!asset || asset.type !== 'sound') return;

    // In real implementation, would use Howler.js
    console.log(`[Audio] Playing sound: ${asset.name}`);
  }

  /**
   * Play music
   */
  playMusic(assetId: string): void {
    if (!this.config.musicEnabled) return;

    const asset = this.assets.get(assetId);
    if (!asset || asset.type !== 'music') return;

    // Stop current music if playing
    if (this.currentMusic) {
      console.log(`[Audio] Stopping music: ${this.currentMusic}`);
    }

    this.currentMusic = assetId;
    console.log(`[Audio] Playing music: ${asset.name}`);
  }

  /**
   * Stop music
   */
  stopMusic(): void {
    if (this.currentMusic) {
      console.log(`[Audio] Stopping music: ${this.currentMusic}`);
      this.currentMusic = null;
    }
  }

  /**
   * Set master volume
   */
  setMasterVolume(volume: number): void {
    this.config.masterVolume = Math.max(0, Math.min(1, volume));
  }

  /**
   * Set sound volume
   */
  setSoundVolume(volume: number): void {
    this.config.soundVolume = Math.max(0, Math.min(1, volume));
  }

  /**
   * Set music volume
   */
  setMusicVolume(volume: number): void {
    this.config.musicVolume = Math.max(0, Math.min(1, volume));
  }

  /**
   * Toggle sound
   */
  toggleSound(): void {
    this.config.soundEnabled = !this.config.soundEnabled;
  }

  /**
   * Toggle music
   */
  toggleMusic(): void {
    this.config.musicEnabled = !this.config.musicEnabled;
    if (!this.config.musicEnabled) {
      this.stopMusic();
    }
  }

  /**
   * Get audio configuration
   */
  getConfig(): AudioConfig {
    return { ...this.config };
  }

  /**
   * Update audio configuration
   */
  updateConfig(config: Partial<AudioConfig>): void {
    this.config = { ...this.config, ...config };
  }

  /**
   * Play spin sequence
   */
  playSpinSequence(): void {
    this.playSound('spin-start');
    // Reel stops would be played during animation
    setTimeout(() => this.playSound('reel-stop'), 500);
    setTimeout(() => this.playSound('reel-stop'), 700);
    setTimeout(() => this.playSound('reel-stop'), 900);
  }

  /**
   * Play win sequence based on win amount
   */
  playWinSequence(winAmount: number, baseWin: number): void {
    const winRatio = winAmount / baseWin;

    if (winRatio >= 50) {
      this.playSound('jackpot');
    } else if (winRatio >= 10) {
      this.playSound('big-win');
    } else if (winRatio >= 3) {
      this.playSound('medium-win');
    } else if (winRatio >= 1) {
      this.playSound('small-win');
    }
  }

  /**
   * Play bonus sequence
   */
  playBonusSequence(bonusType: string): void {
    this.playSound('bonus-trigger');

    if (bonusType === 'free_spins') {
      setTimeout(() => this.playSound('free-spin'), 500);
    } else if (bonusType === 'cascade') {
      this.playSound('cascade');
    }
  }

  /**
   * Export audio configuration
   */
  export(): {
    config: AudioConfig;
    assets: AudioAsset[];
  } {
    return {
      config: this.config,
      assets: Array.from(this.assets.values()),
    };
  }
}

// Global audio manager instance
export const audioManager = new AudioManager();
