package com.efounder.chat.view.voicedictate;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.os.Looper;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;

import com.efounder.chat.R;
import com.efounder.chat.utils.AudioCodecUtils;
import com.efounder.pansoft.chat.listener.VoiceDictateSendListener;
import com.efounder.util.LoadingDataUtilBlack;
import com.utilcode.util.LogUtils;
import com.utilcode.util.NetworkUtils;
import com.utilcode.util.ReflectUtils;
import com.utilcode.util.ScreenUtils;
import com.utilcode.util.SizeUtils;
import com.utilcode.util.ToastUtils;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ShortBuffer;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

/**
 * author : zzj
 * e-mail : zhangzhijun@pansoft.com
 * date   : 2018/9/6 16:06
 * desc   : 语音转换管理器
 * version: 1.0
 */
public class VoiceDictatePopManager implements View.OnClickListener {
    private Context context;
    private BubblePopupWindow bubblePopupWindow;
    //听写内容
    private TextView dictateContent;

    //取消
    private TextView tv_cancel;
    //发送
    private TextView tv_voice_dictate_send;
    //说完了控件
    private TextView tv_voice_dictate_speak_end;
    //反射主工程的语音听写管理器
    private ReflectUtils reflectUtils;
    private ReflectUtils reflectUtils1;
    //声音的波形控件
    private VoiceDictateWaveView view_voice_dictate_wave;
    //语音听写的路径
    private String voicePath;
    //popwindow指定弹窗的位置
    private View locationView;
    //popwindow的原始高度
    private int primevalPopHeght;
    private int primevalPopWidth;
    private int rateX = 30; //30帧取一帧
    float divider = 0.2f;
    int[] location = new int[2];
    private int gravity = Gravity.TOP;
    //是否聊天列表底部显示，此时角位置在右下角
    private boolean setLegRightBottom;
    ArrayList<Short> buf = new ArrayList<>();
    //是否弹窗pop
    private boolean isShowPop;
    private VoiceDictateSendListener voiceDictateSendListener;
    //语音听写音频文件的转码工具类
    private AudioCodecUtils audioCodecUtils;

    private ViewTreeObserver viewTreeObserver;
    //设置窗口的宽度
    private int updateWidth;
    //定时器计算语音听写的事件
    private Timer timer;
    private long time;//语音时间

    //是否识别成功
    private boolean isRecognitionSuccess;

    //是否点发送按钮
    private boolean isClickSend;

    public VoiceDictatePopManager(Context context) {
        this.context = context;
        initPop();

    }

    View bubbleView;

    @SuppressLint("WrongConstant")
    private void initPop() {

        bubblePopupWindow = new BubblePopupWindow(context);
        bubbleView = LayoutInflater.from(context).inflate(R.layout.pop_voice_dictate_view, null);
        bubblePopupWindow.setBubbleView(bubbleView);
        bubblePopupWindow.setSoftInputMode(PopupWindow.INPUT_METHOD_NEEDED);
        bubblePopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        dictateContent = bubbleView.findViewById(R.id.tv_dictate_content);
        tv_voice_dictate_send = bubbleView.findViewById(R.id.tv_voice_dictate_send);
        dictateContent.setWidth((int) (BubblePopupWindow.getScreenWidth(context) * 7.6 / 10));

        tv_cancel = bubbleView.findViewById(R.id.tv_cancel);
        view_voice_dictate_wave = bubbleView.findViewById(R.id.view_voice_dictate_wave);
        tv_cancel.setOnClickListener(this);
        tv_voice_dictate_send.setOnClickListener(this);
        tv_voice_dictate_speak_end = bubbleView.findViewById(R.id.tv_voice_dictate_speak_end);
        tv_voice_dictate_speak_end.setOnClickListener(this);

        updateWidth = BubblePopupWindow.getScreenWidth(context) * 4 / 5;

        bubblePopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                LogUtils.e("onDismiss");
                LoadingDataUtilBlack.dismiss();
                isShowPop = false;
                cancelTimer();
                //释放语音资源
                stopVoiceDictate();
                //防止语音资源已经释放，接口还在回调中
                if (speechRecognitionCallBack != null) {
                    speechRecognitionCallBack = null;
                }
                //清除数据
                buf.clear();
            }
        });
    }

    /**
     * 隐藏pop
     */
    public void disMissPop() {
//        if (bubblePopupWindow.isShowing()) {
//            isShowPop = false;
//            //释放语音资源
//            stopVoiceDictate();
//            //防止语音资源已经释放，接口还在回调中
//            if(speechRecognitionCallBack!=null){
//                speechRecognitionCallBack = null;
//            }
//            //清除数据
//            buf.clear();
//            //关闭转码流
////            audioCodecUtils.close();
//            bubblePopupWindow.dismiss();
//        }
        try {
            if (!((Activity) context).isDestroyed() && bubblePopupWindow.isShowing()) {
                bubblePopupWindow.dismiss();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public PopupWindow getPop() {
        return bubblePopupWindow;
    }

    /**
     * 弹出
     *
     * @param view
     * @param offheight
     */
    public void showTopPopWindow(View view, int offheight, String content, boolean isStart) {
        //设置弹窗为true状态
        isShowPop = true;
        //        //模拟音频数据 从右边开始绘制
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 3000; i++) {
                    buf.add(new Short("0"));
                }
            }
        }).start();
//        audioCodecUtils = new AudioCodecUtils();
        //初始化发送和说完了控件的显示状态
        setSendOrSpeakEndState(false);
        //清空文本内容
        dictateContent.setText(content);
        offheight = offheight + dictateContent.getMeasuredHeight();
        view.getLocationInWindow(location);
        int viewX = location[0];
//        Log.e("showtop----->", "viewX___---->" + viewX);
        locationView = view;

//        bubblePopupWindow.show(view, gravity, 0, offheight);
        primevalPopHeght = bubblePopupWindow.getMeasureHeight();
        primevalPopWidth = bubblePopupWindow.getMeasuredWidth();
        //聊天列表底部显示
        if (setLegRightBottom) {
            bubblePopupWindow.show(view, gravity, 0, offheight);
            bubblePopupWindow.update(location[0] + (view.getMeasuredWidth() - primevalPopWidth
                            - SizeUtils.dp2px(20)), location[1] - primevalPopHeght + SizeUtils.dp2px(50)
                    , LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
        } else

            //聊天列表正常显示
            if (gravity == Gravity.LEFT) {
                bubblePopupWindow.show(view, gravity, 0, offheight);
                bubblePopupWindow.update(location[0] + (view.getMeasuredWidth() - primevalPopWidth
                                - SizeUtils.dp2px(20)), location[1] + SizeUtils.dp2px(15)
                        , LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            } else {

                //聊天界面显示
                bubblePopupWindow.show(view, Gravity.CENTER, viewX - view.getWidth() + 20, offheight);
//            bubblePopupWindow.update(location[0], location[1] - primevalPopHeght - dictateContent.getMeasuredHeight()
//                    , LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
                bubblePopupWindow.update(0, location[1] - primevalPopHeght
                        , updateWidth, LinearLayout.LayoutParams.WRAP_CONTENT);

            }
        if (isStart) {
            startVoiceDictate();
        }
    }

    public void setGravity(int gravity) {
        this.gravity = gravity;
    }

    /**
     * 气泡的角位置设为右下
     */
    public void setBubbleLegRightBottom(boolean isLegRightBottom) {
        bubblePopupWindow.setLegRightBottom(isLegRightBottom);
        //同时气泡显示高度要上调
        setLegRightBottom = isLegRightBottom;
    }

    /**
     * 语音转换
     */
    private void startVoiceDictate() {
        initVoiceDictateManager();
        reflectUtils1.method("startRecognition");
    }


    /**
     * byte[]转short[]
     *
     * @param data
     * @return
     */
    private short[] byteArray2ShortArrayLittle(byte[] data) {
        int items = data.length >> 1;
        short[] retVal = new short[items];
        for (int i = 0; i < retVal.length; i++)
            retVal[i] = (short) ((data[i * 2] & 0xff) | (data[i * 2 + 1] & 0xff) << 8);

        return retVal;
    }

    public void setVoiceDictateSendListener(VoiceDictateSendListener voiceDictateSendListener) {
        this.voiceDictateSendListener = voiceDictateSendListener;
    }

    @Override
    public void onClick(View v) {
        int i = v.getId();
        if (i == R.id.tv_cancel) {//取消
            stopVoiceDictate();
            disMissPop();
        } else if (i == R.id.tv_voice_dictate_send) {//发送
            isClickSend = true;
            if (isRecognitionSuccess) {
                sendVoiceDictate();
            } else {
                LoadingDataUtilBlack.show(context, context.getString(R.string.voice_dictate_pop_manager_recognition));
                reflectUtils1.method("stopListening");
                cancelTimer();
            }
        } else if (i == R.id.tv_voice_dictate_speak_end) {//说完了
            setSendOrSpeakEndState(true);
            stopVoiceDictate();
        }
    }

    /**
     * 发送语音消息
     */
    private void sendVoiceDictate() {
        if (voiceDictateSendListener != null) {
//                File f = new File(ImageUtil.amrpath,
//                        System.currentTimeMillis()+".amr");
//                AudioCodecUtils.createFile(f);
//                AudioCodecUtils.pcm2Amr(voicePath,f.getAbsolutePath());
            disMissPop();
            isRecognitionSuccess = false;
            isClickSend = false;
//                LogUtils.e("获取音频文件编码后的路径---->"+f.getAbsolutePath());
            voiceDictateSendListener.onViceDictateSendListener(dictateContent.getText().toString(), voicePath);
        }
    }

    /**
     * 释放资源
     */
    private void stopVoiceDictate() {
        //释放语音资源
        reflectUtils1.method("release");
    }

    /**
     * 初始化语音听写管理器
     */
    private SpeechRecognitionCallBack speechRecognitionCallBack;

    private void initVoiceDictateManager() {
        reflectUtils = ReflectUtils.reflect("com.efounder.VoiceRecognitionManager");
        reflectUtils1 = reflectUtils.newInstance(context);
        reflectUtils1.method("setVoiceRecognitionCallBack", speechRecognitionCallBack = new SpeechRecognitionCallBack() {
            @Override
            public void onStartOfSpeech() {
                if (bubblePopupWindow != null && bubblePopupWindow.isShowing()) {
                    timer = new Timer();
                    time = 0;
                    //获取录音转码的音频文件地址
//                if(audioCodecUtils!=null){
//                    voicePath = audioCodecUtils.getAudioPath();
//                }
                    //开始计时
                    timer.schedule(new TimerTask() {
                        @Override
                        public void run() {
                            time = time + 1000;
                            if (time == 50000) {
                                ToastUtils.showShort(R.string.wechatview_voice_speak_left_ten);
                                cancelTimer();
                            }
                        }
                    }, 0, 1000);
                }

            }

            @Override
            public void onEndOfSpeech() {
                //听写结束 显示 发送
                setSendOrSpeakEndState(true);
                cancelTimer();
//                ToastUtils.showShort("语音听写结束");
            }

            @Override
            public void onSuccess(String text, boolean isLast) {
                isRecognitionSuccess = isLast;
                dictateContent.setText(text);


                //聊天列表底部显示
                if (setLegRightBottom) {
                    bubblePopupWindow.update(location[0] + (ScreenUtils.getScreenWidth() - primevalPopWidth
                                    - SizeUtils.dp2px(20)), location[1] - primevalPopHeght + SizeUtils.dp2px(50)
                            , LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
                } else
                    //聊天列表正常显示
                    if (gravity == Gravity.LEFT) {
                        bubblePopupWindow.update(location[0] + (ScreenUtils.getScreenWidth() - primevalPopWidth
                                        - SizeUtils.dp2px(20)), location[1] + SizeUtils.dp2px(15)
                                , LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
                    } else {

                        viewTreeObserver = dictateContent.getViewTreeObserver();
                        viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                            @Override
                            public void onGlobalLayout() {
                                //聊天界面显示
                                bubblePopupWindow.update(0, location[1] - bubblePopupWindow.getMeasureHeight()
                                        , updateWidth, LinearLayout.LayoutParams.WRAP_CONTENT);
                            }
                        });

                    }
                if (isRecognitionSuccess && isClickSend) {
                    LoadingDataUtilBlack.dismiss();
                    sendVoiceDictate();
                }
            }

            @Override
            public void onFail(String failMsg) {
                LogUtils.e("当前线程是否为主线程--->" + isOnMainThread());
                disMissPop();
                cancelTimer();
                if (!NetworkUtils.isConnected()) {
                    ToastUtils.showShort(R.string.common_text_network_error);
                } else {
                    ToastUtils.showShort(R.string.wechatview_voice_pop_no_speak);

                }
                LoadingDataUtilBlack.dismiss();
            }

            @Override
            public void onVolumeChanged(int volume, byte[] data) {
                if (bubblePopupWindow.isShowing()) {
//                    audioCodecUtils.offerEncoder(data);
                }
                short[] shorts = byte2short(data);
                for (int i = 0; i < shorts.length; i += rateX) {
                    buf.add(shorts[i]);
//                    LogUtils.e("获取的音频集合-  short--》" + shorts[i] + "---byte--" + data[i]);
                }
                synchronized (buf) {
                    if (buf.size() == 0)
                        return;
                    //调整声波图出来的位置
                    while (buf.size() > (view_voice_dictate_wave.getWidth() - 160) / divider) {
                        if (buf.size() > 0) {
                            buf.remove(0);
                        }

                    }
                    //绘制波形图数据
                    view_voice_dictate_wave.setVoiceList(buf);
                }

            }

            @Override
            public void getAudioFilePath(String audioPath) {
                voicePath = audioPath;
            }
        });
    }

    public short[] byte2short(byte[] data) {
        // 假设data作为源音频数据，是一个byte[]
        int dataLength = data.length;
//byte[]转成short[]，数组长度缩减一半

        int shortLength = dataLength / 2;

        //把byte[]数组装进byteBuffer缓冲
        ByteBuffer byteBuffer = ByteBuffer.wrap(data, 0, dataLength);
        //将byteBuffer转成小端序并获取shortBuffer

        ShortBuffer shortBuffer = byteBuffer.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();

        short[] shortSamples = new short[shortLength];

        //取出shortBuffer中的short数组
        shortBuffer.get(shortSamples, 0, shortLength);
        return shortSamples;
    }

    /**
     * 控制发送和说完了控件的显示隐藏
     *
     * @param isShow
     */
    private void setSendOrSpeakEndState(boolean isShow) {
//        tv_voice_dictate_send.setVisibility(isShow ? View.VISIBLE : View.GONE);
//        tv_voice_dictate_speak_end.setVisibility(isShow ? View.GONE : View.VISIBLE);
    }

    /**
     * 判断是否在当前主线程
     *
     * @return
     */
    public static boolean isOnMainThread() {
        return Looper.myLooper() == Looper.getMainLooper();
    }

    /**
     * 是否弹出pop
     *
     * @return
     */
    public boolean isShowPop() {
        if (bubblePopupWindow != null) {
            return bubblePopupWindow.isShowing();
        }
        return false;
    }

    /**
     * 返回pop
     *
     * @return
     */
    public BubblePopupWindow getBubblePopupWindow() {
        if (bubblePopupWindow != null) {
            return bubblePopupWindow;
        }
        return null;
    }

    /**
     * 停止计时器
     */
    private void cancelTimer() {

        if (timer != null) {
            LogUtils.e("cancelTimer---->" + time != null);
            timer.cancel();
            timer = null;
        }
    }
//
//    public static String toSBC(String input) {
//        char c[] = input.toCharArray();
//        for (int i = 0; i < c.length; i++) {
//            if (c[i] == ' ') {
//                c[i] = '\u3000';
//            } else if (c[i] < '\177') {
//                c[i] = (char) (c[i] + 65248);
//            }
//        }
//        return new String(c);
//    }
}
