package chaoran.business.engine.impl;

import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.webkit.JavascriptInterface;
import android.widget.Toast;
import chaoran.business.R;
import chaoran.business.engine.OfflineVoiceEngine;
import chaoran.business.engine.entity.VoiceSetting;
import com.google.gson.Gson;
import com.iflytek.cloud.*;
import com.iflytek.cloud.util.ResourceUtil;
import com.iflytek.cloud.util.ResourceUtil.RESOURCE_TYPE;

/*
 **********************************************
 *      DATE           PERSON       REASON
 *    2021-02-05          FXY        Created
 **********************************************
 */

public class TekVoiceEngine extends OfflineVoiceEngine {
    private static String TAG = "TekVoiceEngine";

    // 语音合成对象
    private SpeechSynthesizer mTts;

    //缓冲进度
    private int mPercentForBuffering = 0;

    //播放进度
    private int mPercentForPlaying = 0;

    private Toast mToast;

    private Context context;

    private Gson gson;

    public TekVoiceEngine(Context context) {
        super(context);
        gson = new Gson();
        this.context = context;
        // 初始化合成对象
        mTts = SpeechSynthesizer.createSynthesizer(context, mTtsInitListener);
        //设置合成引擎的参数
        reload();
        //初始化对话框
        mToast = Toast.makeText(context, "", Toast.LENGTH_SHORT);
    }

    @Override
    @JavascriptInterface
    public void startSpeaking(String text) {
        if (null == mTts) {
            this.showTip("创建对象失败，请确认 libmsc.so 放置正确，\n 且有调用 createUtility 进行初始化");
        }

        if (mTts.isSpeaking())
            stopSpeaking();

        int code = mTts.startSpeaking(text, mTtsListener);
        if (code != ErrorCode.SUCCESS) {
            showTip("语音合成失败,错误码: " + code + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
        }
    }

    @Override
    @JavascriptInterface
    public void stopSpeaking() {
        mTts.stopSpeaking();
    }


    /**
     * 初始化监听
     */
    private InitListener mTtsInitListener = code -> {
        Log.d(TAG, "InitListener init() code = " + code);
        if (code != ErrorCode.SUCCESS) {
            showTip("初始化失败,错误码：" + code + ",请点击网址https://www.xfyun.cn/document/error-code查询解决方案");
        }
    };

    /**
     * 合成回调监听。
     */
    private SynthesizerListener mTtsListener = new SynthesizerListener() {

        @Override
        public void onSpeakBegin() {
            Log.d(TAG, "开始播放：" + System.currentTimeMillis());
        }

        @Override
        public void onSpeakPaused() {
            showTip("暂停播放");
        }

        @Override
        public void onSpeakResumed() {
            showTip("继续播放");
        }

        @Override
        public void onBufferProgress(int percent, int beginPos, int endPos,
                                     String info) {
            // 合成进度
            mPercentForBuffering = percent;
//            showTip(String.format(context.getString(R.string.tts_toast_format),
//                    mPercentForBuffering, mPercentForPlaying));
        }

        @Override
        public void onSpeakProgress(int percent, int beginPos, int endPos) {
            // 播放进度
            mPercentForPlaying = percent;
//            showTip(String.format(context.getString(R.string.tts_toast_format),
//                    mPercentForBuffering, mPercentForPlaying));
        }

        @Override
        public void onCompleted(SpeechError error) {
            if (error == null) {
//                showTip("播放完成");
            } else if (error != null) {
                showTip(error.getPlainDescription(true));
            }
        }

        @Override
        public void onEvent(int eventType, int arg1, int arg2, Bundle obj) {
            // 以下代码用于获取与云端的会话id，当业务出错时将会话id提供给技术支持人员，可用于查询会话日志，定位出错原因
            // 若使用本地能力，会话id为null
            if (SpeechEvent.EVENT_SESSION_ID == eventType) {
                String sid = obj.getString(SpeechEvent.KEY_EVENT_AUDIO_URL);
                Log.d(TAG, "session id =" + sid);
            }
        }
    };


    public void reload() {

        // 装载参数之前，先清空参数
        mTts.setParameter(SpeechConstant.PARAMS, null);

        VoiceSetting voiceSetting = (VoiceSetting) getSetting();

        //设置使用本地引擎
        mTts.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_LOCAL);

        //设置发音人资源路径
        mTts.setParameter(ResourceUtil.TTS_RES_PATH, getResourcePath(voiceSetting.getVoiceMember()));

        //设置发音人
        mTts.setParameter(SpeechConstant.VOICE_NAME, voiceSetting.getVoiceMember());

        //设置合成语速
        mTts.setParameter(SpeechConstant.SPEED, voiceSetting.getVoiceSpeed());

        //设置合成音调
        mTts.setParameter(SpeechConstant.PITCH, voiceSetting.getVoiceIndicate());

        //设置合成音量
        mTts.setParameter(SpeechConstant.VOLUME, voiceSetting.getVoiceSize());

        //设置播放器音频流类型
        mTts.setParameter(SpeechConstant.STREAM_TYPE, "3");

        // 设置播放合成音频打断音乐播放，默认为true
        mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "true");

        // 设置音频保存路径，保存音频格式支持pcm、wav，设置路径为sd卡请注意WRITE_EXTERNAL_STORAGE权限
        mTts.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");

        mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH, Environment.getExternalStorageDirectory() + "/msc/tts.wav");
    }


    @Override
    @JavascriptInterface
    public void setParam(String voiceMember, String voiceSize, String voiceIndicate, String voiceSpeed) {
        if (null != voiceMember) {
            //设置发音人资源路径
            mTts.setParameter(ResourceUtil.TTS_RES_PATH, getResourcePath(voiceMember));
            //设置发音人
            mTts.setParameter(SpeechConstant.VOICE_NAME, voiceMember);
        }
        if (null != voiceSize) {
            //设置合成音量
            mTts.setParameter(SpeechConstant.VOLUME, voiceSize);
        }
        if (null != voiceIndicate) {
            //设置合成音调
            mTts.setParameter(SpeechConstant.PITCH, voiceIndicate);
        }
        if (null != voiceSpeed) {
            //设置合成语速
            mTts.setParameter(SpeechConstant.SPEED, voiceSpeed);
        }
    }


    private void showTip(String str) {
        mToast.setText(str);
        mToast.show();
    }

    //获取发音人资源路径
    private String getResourcePath(String voiceMember) {
        StringBuffer tempBuffer = new StringBuffer();
        String type = "tts";
        //合成通用资源
        tempBuffer.append(ResourceUtil.generateResourcePath(context, RESOURCE_TYPE.assets, type.concat("/common.jet")));
        tempBuffer.append(";");
        tempBuffer.append(ResourceUtil.generateResourcePath(context, RESOURCE_TYPE.assets, type.concat("/").concat(voiceMember).concat(".jet")));
        return tempBuffer.toString();
    }

    public void destroy() {
        if (null != mTts) {
            mTts.stopSpeaking();
            // 退出时释放连接
            mTts.destroy();
        }
    }

    /**
     * 页面展示语音配置数据
     */
    @JavascriptInterface
    public String getStringSetting() {
        return gson.toJson(getSetting());
    }

    /**
     * 页面保存语音配置数据
     *
     * @param s
     * @return
     */
    @JavascriptInterface
    public boolean saveSetting(String s) {
        return saveSetting(gson.fromJson(s, VoiceSetting.class));
    }

}
