import { assetManager, AudioClip, AudioSource, director, Node, sys } from 'cc';
import { LocalStorageMgr } from './game/LocalStorageMgr';

export class AudioManager {
    /** 单例模式 */
    private static _ins: AudioManager;

    constructor() {
        const audioMgr = new Node();
        audioMgr.name = '__audioMgr__';
        AudioManager._ins = this;
        director.getScene().addChild(audioMgr);
        director.addPersistRootNode(audioMgr);

        // 创建一个 AudioSource 用于背景音乐
        this._bgmAudioSource = audioMgr.addComponent(AudioSource);
        // 创建一个 AudioSource 用于effect音效
        this._effectAudioSource = audioMgr.addComponent(AudioSource);
        // 创建一个 AudioSource 用于可在随意时间停止的音效
        this._effectDiAudioSource = audioMgr.addComponent(AudioSource);

        // 从本地存储恢复静音状态
        const effectMuteState: boolean = LocalStorageMgr.getItem('audio_effectMute');
        const bgmMuteState: boolean = LocalStorageMgr.getItem('audio_bgmMute');

        this.effectMute = effectMuteState ?? false;
        this.bgmMute = bgmMuteState ?? false;
        this._updateBGMVolume();

    }

    public static get ins(): AudioManager {
        if (!AudioManager._ins) {
            AudioManager._ins = new AudioManager();
        }
        return AudioManager._ins;
    }

    private _bgmAudioSource: AudioSource;
    private _effectAudioSource: AudioSource;
    private _effectDiAudioSource: AudioSource;
    private bgmVolume = 1.0;
    private soundVolume = 1.0;
    private _isEffectMuted: boolean = false;
    private _isBGMMuted: boolean = false;

    private _activeOneShotSources: Map<string, AudioSource> = new Map();

    public get effectMute() {
        if (this._isEffectMuted === undefined) {
            this.effectMute = LocalStorageMgr.getItem('audio_effectMute') ?? false;
        }
        return this._isEffectMuted;
    }
    public set effectMute(muted: boolean) {
        this._isEffectMuted = muted;
        LocalStorageMgr.setItem('audio_effectMute', muted);
    }

    public get bgmMute() {
        if (this._isBGMMuted === undefined) {
            this.bgmMute = LocalStorageMgr.getItem('audio_bgmMute') ?? false;
        }
        return this._isBGMMuted;
    }
    public set bgmMute(muted: boolean) {
        this._isBGMMuted = muted;
        LocalStorageMgr.setItem('audio_bgmMute', muted);
        this._updateBGMVolume(muted);
    }

    private _updateBGMVolume(mute?: boolean) {
        mute = mute ?? this.bgmMute;
        this._bgmAudioSource.volume = mute ? 0 : 1;
    }

    playOneShot(sound: AudioClip | string, volume: number = 1.0, bundleName: string = 'resources') {
        if (this._isEffectMuted) return;  // 如果音效静音，直接返回
        if (sound instanceof AudioClip) {
            this._effectAudioSource.playOneShot(sound, volume);
        } else {
            let bundle = assetManager.getBundle(bundleName);
            bundle.load(sound, (err, clip: AudioClip) => {
                if (err) {
                    console.log(err);
                } else {
                    this._effectAudioSource.playOneShot(clip, volume);
                }
            });
        }
    }


    /** 播放一个短音效，可以控制停止暂停 */
    playEff(sound: AudioClip | string, bundleName: string = 'resources') {
        if (this._isEffectMuted) return;  // 如果音效静音，直接返回

        if (sound instanceof AudioClip) {
            this._effectDiAudioSource.stop();
            this._effectDiAudioSource.clip = sound;
            this._effectDiAudioSource.loop = false;  // 不循环播放
            this._effectDiAudioSource.play();
        } else {
            let bundle = assetManager.getBundle(bundleName);
            bundle.load(sound, (err, clip: AudioClip) => {
                if (err) {
                    console.log(err);
                } else {
                    this._effectDiAudioSource.stop();
                    this._effectDiAudioSource.clip = clip;
                    this._effectDiAudioSource.loop = false;  // 不循环播放
                    this._effectDiAudioSource.play();
                }
            });
        }
    }
    /**
     * 停止播放playEff指定的短音效
     */
    stopPlayEff(sound: AudioClip | string) {
        const audioSource = this._effectDiAudioSource;
        if (audioSource) {
            audioSource.stop();
        } else {
            console.log(`Sound ${sound} is not currently playing.`);
        }
    }

    play(sound: AudioClip | string, loop: boolean = true, bundleName: string = 'resources') {

        if (this.bgmMute) {
            this.bgmVolume = 0
        } else {
            this.bgmVolume = 1;
        }

        if (sound instanceof AudioClip) {
            this._bgmAudioSource.stop();
            this._bgmAudioSource.clip = sound;
            this._bgmAudioSource.loop = loop;
            this._bgmAudioSource.play();
            this._updateBGMVolume();
        } else {
            const bundle = assetManager.getBundle(bundleName);
            if (!bundle) {
                // console.error(`Bundle ${bundleName} not found.`);
                return;
            }
            bundle.load(sound, (err, clip: AudioClip) => {
                if (err) {
                    // console.error(`Failed to load sound ${sound}: ${err}`);
                } else if (clip) {
                    this._bgmAudioSource.stop();
                    this._bgmAudioSource.clip = clip;
                    this._bgmAudioSource.loop = loop;
                    this._bgmAudioSource.play();
                    this._updateBGMVolume();
                }
            });
        }
    }

    stopBgm() {
        this._bgmAudioSource.stop();
    }

    pauseBgm() {
        this._bgmAudioSource.pause();
    }

    resumeBgm() {
        this._bgmAudioSource.play();
    }
}