import { Howl, Howler } from 'howler';
import Tuna from 'tunajs';

// 类型定义扩展
interface HowlSound {
  _sounds: Array<{
    _node: HTMLMediaElement & {
      destination?: MediaElementAudioSourceNode;
    };
  }>;
}

export interface EQSettings {
  [key: string]: number;
}

export class EQService {
  private context: AudioContext | null = null;

  private tuna: any = null;

  private equalizer: any = null;

  private source: MediaElementAudioSourceNode | null = null;

  private gainNode: GainNode | null = null;

  private bypass = false;

  // 预设频率
  private readonly frequencies = [31, 62, 125, 250, 500, 1000, 2000, 4000, 8000, 16000];

  // 默认EQ设置
  private defaultEQSettings: EQSettings = Object.fromEntries(
    this.frequencies.map((f) => [f.toString(), 0])
  );

  constructor() {
    this.loadSavedSettings();
    this.bypass = localStorage.getItem('eqBypass') === 'true';
    this.initializeUserGestureHandler();
  }

  // 初始化用户手势处理
  private initializeUserGestureHandler() {
    const handler = async () => {
      if (this.context?.state === 'suspended') {
        await this.context.resume();
      }
      document.removeEventListener('click', handler);
    };
    document.addEventListener('click', handler);
  }

  // 初始化音频上下文
  public async setupAudioContext(howl: Howl) {
    try {
      // 使用Howler的现有上下文
      this.context = (Howler.ctx as AudioContext) || new AudioContext();

      // 初始化Howler的音频系统（如果需要）
      if (!Howler.ctx) {
        Howler.ctx = this.context;
        Howler.masterGain = this.context.createGain();
        Howler.masterGain.connect(this.context.destination);
      }

      // 确保上下文处于运行状态
      if (this.context.state === 'suspended') {
        await this.context.resume();
      }

      const sound = (howl as unknown as HowlSound)._sounds[0];
      if (!sound?._node) throw new Error('无法获取音频节点');

      // 清理现有资源
      await this.dispose();

      // 创建新的处理链
      this.tuna = new Tuna(this.context);

      // 创建/复用源节点
      if (!sound._node.destination) {
        this.source = this.context.createMediaElementSource(sound._node);
        sound._node.destination = this.source;
      } else {
        this.source = sound._node.destination;
      }

      // 创建效果节点
      this.gainNode = this.context.createGain();
      this.equalizer = new this.tuna.Equalizer({
        frequencies: this.frequencies,
        gains: this.frequencies.map((f) => this.getSavedGain(f.toString())),
        bypass: this.bypass
      });

      // 连接节点链
      this.source!.connect(this.equalizer.input).connect(this.gainNode).connect(Howler.masterGain);

      // 恢复音量设置
      const volume = localStorage.getItem('volume');
      this.gainNode.gain.value = volume ? parseFloat(volume) : 1;
    } catch (error) {
      console.error('音频上下文初始化失败:', error);
      await this.dispose();
      throw error;
    }
  }

  // EQ功能开关
  public setEnabled(enabled: boolean) {
    this.bypass = !enabled;
    localStorage.setItem('eqBypass', JSON.stringify(this.bypass));
    if (this.equalizer) this.equalizer.bypass = this.bypass;
  }

  public isEnabled(): boolean {
    return !this.bypass;
  }

  // 调整频率增益
  public setFrequencyGain(frequency: string, gain: number) {
    const index = this.frequencies.findIndex((f) => f.toString() === frequency);
    if (index !== -1 && this.equalizer) {
      this.equalizer.setGain(index, gain);
      this.saveSettings(frequency, gain);
    }
  }

  // 重置EQ设置
  public resetEQ() {
    this.frequencies.forEach((f) => {
      this.setFrequencyGain(f.toString(), 0);
    });
    localStorage.removeItem('eqSettings');
  }

  // 获取当前设置
  public getAllSettings(): EQSettings {
    return this.loadSavedSettings();
  }

  // 保存/加载设置
  private saveSettings(frequency: string, gain: number) {
    const settings = this.loadSavedSettings();
    settings[frequency] = gain;
    localStorage.setItem('eqSettings', JSON.stringify(settings));
  }

  private loadSavedSettings(): EQSettings {
    const saved = localStorage.getItem('eqSettings');
    return saved ? JSON.parse(saved) : { ...this.defaultEQSettings };
  }

  private getSavedGain(frequency: string): number {
    return this.loadSavedSettings()[frequency] || 0;
  }

  // 清理资源
  public async dispose() {
    try {
      [this.source, this.equalizer, this.gainNode].forEach((node) => {
        if (node) {
          node.disconnect();
          // 特殊清理Tuna节点
          if (node === this.equalizer && typeof (node as any).destroy === 'function') {
            (node as any).destroy();
          }
        }
      });

      if (this.context && this.context !== Howler.ctx) {
        await this.context.close();
      }

      this.context = null;
      this.tuna = null;
      this.source = null;
      this.equalizer = null;
      this.gainNode = null;
    } catch (error) {
      console.error('资源清理失败:', error);
    }
  }
}

export const eqService = new EQService();
