import media from "@ohos:multimedia.media";
import type { BusinessError as BusinessError } from "@ohos:base";
const TAG = '[CLAVPlayer] ';
export class CLAVPlayerManager {
    static context: Context;
    public manager(context: Context) {
        CLAVPlayer.instance.createAVPlayer();
        CLAVPlayerManager.context = context;
        return CLAVPlayerManager;
    }
    public async player(source: string) {
        CLAVPlayer.instance.createAVPlayer();
        let rawFile = await CLAVPlayerManager.context.resourceManager.getRawFd('muc_0.mp3');
        CLAVPlayer.instance.play(rawFile);
    }
}
export class CLAVPlayer {
    private playState?: media.AVPlayerState;
    private avPlayer?: media.AVPlayer;
    private audioDuration?: number;
    private currTimeInAudio?: number;
    private surfaceID: string | undefined = undefined;
    public static instance: CLAVPlayer = new CLAVPlayer();
    async createAVPlayer() {
        if (this.avPlayer) {
            return;
        }
        await media.createAVPlayer().then((player: media.AVPlayer) => {
            this.avPlayer = player;
            console.log(TAG + ' avPlayer创建成功! ');
        })
            .catch((err: BusinessError) => {
            console.error(TAG + ` avPlayer创建异常: errCode:${err.code}  errMessage:${err.message}`);
        });
    }
    setPlayState() {
        this.playState = this.avPlayer?.state;
        console.log('PlayState: ' + JSON.stringify(this.playState));
    }
    // 创建状态机
    setAVPlayerCallback(avPlayer: media.AVPlayer, surfaceID?: string | undefined) {
        // seek操作结果回调函数
        avPlayer.on('seekDone', (seekDoneTime: number) => {
            console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
        });
        // error回调监听函数,当avPlayer在操作过程中出现错误时调用 reset接口触发重置流程
        avPlayer.on('error', (err: BusinessError) => {
            console.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
            if (err.code === 5400106) {
                console.log('音频地址异常');
            }
            avPlayer.reset(); // 调用reset重置资源，触发idle状态
        });
        // 状态机变化回调函数
        avPlayer.on('stateChange', async (state: string, reason: media.StateChangeReason) => {
            switch (state) {
                case 'idle': // 闲置状态， avplayer刚被创建或者调用reset方法之后进入idle状态
                    //此状态可设置 url 或者 fdSrc属性，然后自动进入initialized状态
                    this.setPlayState();
                    break;
                case 'initialized': // 资源初始化，
                    //此时可以配置 窗口、音频、等静态属性
                    console.info('AVPlayer state initialized called.');
                    this.setPlayState();
                    if (surfaceID) {
                        avPlayer.surfaceId = surfaceID;
                    }
                    avPlayer.prepare();
                    break;
                case 'prepared': // 准备完毕状态，此时播放引擎的资源已准备就绪
                    console.info('AVPlayer state prepared called.');
                    this.setPlayState();
                    avPlayer.play(); // 调用播放接口开始播放
                    break;
                case 'playing': // 正在播放状态，可在prepared/paused/completed状态调用play方法，avplayer会进入此状态
                    this.setPlayState();
                    break;
                case 'paused': // 暂停状态，在playing状态中执行pause方法，会进入paused状态
                    console.info('AVPlayer state paused called.');
                    this.setPlayState();
                    avPlayer.pause();
                    break;
                case 'completed': // 播放至结尾状态， 可调用play方法进入playing状态，调用stop方法进入stopped状态
                    console.info('AVPlayer state completed called.');
                    this.setPlayState();
                    avPlayer.stop(); //调用播放结束接口
                    break;
                case 'stopped': // 停止状态， 可调用prepared/playing/paused/completed状态调用stop方法进入此状态
                    //此状态只保留属性，但会释放内存资源
                    //可调用prepared重新准备
                    //可调用reset重置
                    //可调用release彻底销毁
                    console.info('AVPlayer state stopped called.');
                    this.setPlayState();
                    avPlayer.reset(); // 调用reset接口初始化avplayer状态
                    break;
                case 'released': //销毁状态
                    console.info('AVPlayer state released called.');
                    this.setPlayState();
                    avPlayer.reset();
                    break;
                default:
                    console.info('AVPlayer state unknown called.');
                    break;
            }
        });
        //监听进度条长度
        avPlayer.on('durationUpdate', (data: number) => {
            this.audioDuration = data;
            this.setPlayState();
            console.log('durationUpdate: ' + JSON.stringify(this.audioDuration));
        });
        //监听进度条当前位置
        avPlayer.on('timeUpdate', (data: number) => {
            this.currTimeInAudio = data;
            console.log('timeUpdate: ' + JSON.stringify(this.currTimeInAudio));
        });
    }
    //播放和暂停切换
    togglePlayOrPause() {
        if (!this.avPlayer) {
            return false;
        }
        if (this.playState === 'playing') {
            this.avPlayer!.pause();
            return true;
        }
        else if (this.playState === 'paused') {
            this.avPlayer!.play();
            return true;
        }
        return false;
    }
    //暂停播放
    pause() {
        if (this.avPlayer) {
            this.avPlayer.pause();
        }
    }
    //停止播放
    stop() {
        if (this.avPlayer) {
            this.avPlayer.stop();
        }
    }
    //释放avPlayer
    release() {
        if (this.avPlayer) {
            this.avPlayer.release();
        }
    }
    //重置 avplayer 状态
    reset() {
        if (this.avPlayer) {
            this.avPlayer.reset();
        }
    }
    //播放
    async play(audioSrc: string | media.AVFileDescriptor, surfaceID?: string | undefined) {
        if (!audioSrc) {
            return;
        }
        //如果播放状态为playing或者paused，返回true，调用指定方法，直接return;
        let res = this.togglePlayOrPause();
        if (res) {
            return;
        }
        //如果avplayer不存在，创建，此时播放状态为 idle： 空闲状态
        await this.createAVPlayer();
        //设置状态机
        this.setAVPlayerCallback(this.avPlayer!, surfaceID);
        //设置 音频url，状态自动跳至 initialized
        if (typeof audioSrc === 'string') {
            this.avPlayer!.url = audioSrc;
        }
        else {
            this.avPlayer!.fdSrc = audioSrc;
        }
    }
}
