package com.hh.lib_record.microphone;

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Environment;
import android.util.Log;


import com.hh.lib_base.log.AppLogUtils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Base64;

// 解码率16000，mp3,最长5分钟
public class MicrophoneRecorder {

    // 当前类名
    public String TAG = getClass().getSimpleName()+"--";



    //用volatile关键字确保 instance 在多线程下的可见性
    private static volatile MicrophoneRecorder instance = null;

    //将构造方法私有化，禁止外部通过构造方法创建实例
    private MicrophoneRecorder() {}

    //提供一个公共的访问方法，用于获取该类的唯一实例
    public static MicrophoneRecorder getInstance() {
        //如果instance为空，就进行实例化
        if (instance == null) {
            //保证多线程下只有一个线程进行实例化
            synchronized (MicrophoneRecorder.class) {
                //第二次判断，避免多线程下创建多个实例
                if (instance == null) {
                    instance = new MicrophoneRecorder();
                }
            }
        }
        return instance;
    }




    //是否在录制
    private boolean isRecording = false;

    //pcm文件
    private File file;


    IMicroPhoneSizeCallback iMicroPhoneSizeCallback;

    int recorderSize = 3;


    public void getResultListener(IMicroPhoneSizeCallback iMicroPhoneSizeCallback,int recorderSize) {
        this.iMicroPhoneSizeCallback = iMicroPhoneSizeCallback;
        this.recorderSize = recorderSize;
        startThreadRecord();
    }



    public void startThreadRecord(){
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                startRecord();
            }
        });
        thread.start();
    }

    public void stopRecord(){
        isRecording = false;
        if(buffer == null){
            AppLogUtils.e("buffer == null");
            return;
        }
        if(dos == null){
            AppLogUtils.e("dos == null");
            return;
        }

        String result = Arrays.toString(buffer);
        AppLogUtils.e("buffer转成string:"+result);

        String dosStr = dos.toString();
        AppLogUtils.e("dosStr转成string:"+dosStr);

//        AppLogUtils.e("file.getPath():"+file.getPath());
//
//        File fileMp3 = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/voice.mp3");
//        Log.e(TAG,"生成文件");
//        //如果存在，就先删除再创建
//        if (fileMp3.exists())
//            fileMp3.delete();
//        Log.e(TAG,"删除文件");
//        try {
//            fileMp3.createNewFile();
//            Log.e(TAG,"创建文件");
//        } catch (IOException e) {
//            Log.e(TAG,"未能创建");
//            throw new IllegalStateException("未能创建" + fileMp3.toString());
//        }
//
//
//
//        try {
//            File pcmFile = new File(file.getPath());
//            File mp3File = new File(fileMp3.getPath());
//            int sampleRate = 44100; // 采样率
//            int channels = 2; // 通道数
//            int bitRate = 128; // 比特率
//
//
//            String s = convertAudioFiles(file.getPath(), fileMp3.getPath());
////            if(s.equals("ok")){
////                String base64String = convertPcmToBase64(fileMp3.getPath());
////                AppLogUtils.e("base64String:"+base64String);
////            }
//
////            convertPcmToMp3(pcmFile, mp3File, sampleRate, channels, bitRate);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }




    }


//    public static void convertPcmToMp3(File pcmFile, File mp3File, int sampleRate, int channels, int bitRate) throws IOException {
//        FileInputStream pcmInputStream = new FileInputStream(pcmFile);
//        FileOutputStream mp3OutputStream = new FileOutputStream(mp3File);
//
//        Lame lame = new Lame(sampleRate, channels, bitRate, mp3OutputStream);
//
//        byte[] buffer = new byte[65536];
//        int bytesRead;
//        while ((bytesRead = pcmInputStream.read(buffer)) != -1) {
//            short[] shorts = new short[bytesRead / 2];
//            for (int i = 0; i < shorts.length; i++) {
//                shorts[i] = (short) ((buffer[i * 2] & 0xff) | (buffer[i * 2 + 1] << 8));
//            }
//            lame.encode(shorts, shorts.length);
//        }
//
//        lame.flush();
//        lame.close();
//        pcmInputStream.close();
//        mp3OutputStream.close();
//    }


    public static String convertAudioFiles(String src, String target) throws IOException {
        FileInputStream fis = new FileInputStream(src);
        FileOutputStream fos = new FileOutputStream(target);

        //计算长度
        byte[] buf = new byte[1024 * 4];
        int size = fis.read(buf);
        int PCMSize = 0;
        while (size != -1) {
            PCMSize += size;
            size = fis.read(buf);
        }
        fis.close();

        //填入参数，比特率等等。这里用的是16位单声道 8000 hz
        WaveHeader header = new WaveHeader();
        //长度字段 = 内容的大小（PCMSize) + 头部字段的大小(不包括前面4字节的标识符RIFF以及fileLength本身的4字节)
        header.fileLength = PCMSize + (44 - 8);
        header.FmtHdrLeth = 16;
        header.BitsPerSample = 16;
        header.Channels = 1;
        header.FormatTag = 0x0001;
        header.SamplesPerSec = 16000;//正常速度是8000，这里写成了16000，速度加快一倍
        header.BlockAlign = (short) (header.Channels * header.BitsPerSample / 8);
        header.AvgBytesPerSec = header.BlockAlign * header.SamplesPerSec;
        header.DataHdrLeth = PCMSize;

        byte[] h = header.getHeader();

        assert h.length == 44; //WAV标准，头部应该是44字节
        //write header
        fos.write(h, 0, h.length);
        //write data stream
        fis = new FileInputStream(src);
        size = fis.read(buf);
        while (size != -1) {
            fos.write(buf, 0, size);
            size = fis.read(buf);
        }
        fis.close();
        fos.close();
        AppLogUtils.e("PCM Convert to MP3 OK!");

        String base64String = convertPcmToBase64(target);
        AppLogUtils.e("base64String:"+base64String);

        return "ok";
    }


    public static String convertPcmToBase64(String pcmFilePath) {
        File pcmFile = new File(pcmFilePath);
        byte[] fileContent = new byte[(int) pcmFile.length()];

        try (FileInputStream fileInputStream = new FileInputStream(pcmFile)) {
            fileInputStream.read(fileContent);
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            return Base64.getEncoder().encodeToString(fileContent);
        }
        return "";
    }

    byte[] bytes;

    short[] buffer;
//    byte[] buffer;
    DataOutputStream dos;

    //开始录音
    public void startRecord() {
        AppLogUtils.e("startRecord--开始录音");
        //16K采集率
        int frequency = 16000;
        //格式
        int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
        //16Bit
        int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
        //生成PCM文件
        file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/voice.mp3");
//        file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/voice.pcm");
      //  Log.e(TAG,"生成文件");
        //如果存在，就先删除再创建
        if (file.exists())
            file.delete();
       // Log.e(TAG,"删除文件");
        try {
            file.createNewFile();
         //   Log.e(TAG,"创建文件");
        } catch (IOException e) {
          //  Log.e(TAG,"未能创建");
            throw new IllegalStateException("未能创建" + file.toString());
        }
        try {
            //输出流
            OutputStream os = new FileOutputStream(file);
            BufferedOutputStream bos = new BufferedOutputStream(os);
            dos = new DataOutputStream(bos);
            int bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding);
            AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency, channelConfiguration, audioEncoding, bufferSize);

            buffer = new short[bufferSize];
//            buffer = new byte[bufferSize];
            audioRecord.startRecording();
            AppLogUtils.e("开始录音");
            isRecording = true;
            while (isRecording) {
                int bufferReadResult = audioRecord.read(buffer, 0, bufferSize);
                for (int i = 0; i < bufferReadResult; i++) {
                    dos.writeShort(buffer[i]);

                    if(buffer.length >= recorderSize*1024){
                        // short数组再转换回byte数组。
                        byte[] bytes = toByteArray(buffer);

                        AppLogUtils.e("File--bytes:"+ bytes);

                        // 使用 Base64 编码器将字节数组转换为 Base64 字符串
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                            String base64String = Base64.getEncoder().encodeToString(this.bytes);
                            AppLogUtils.e("File--base64String:"+base64String);
                            iMicroPhoneSizeCallback.onSizeSuccess(base64String);
                        }



                    }


//                    dos.write(buffer[i]);
                }
            }


//            String result = dos.toString();

            audioRecord.stop();
            dos.close();
        } catch (Throwable t) {
          //  Log.e(TAG, "录音失败");
        }
    }


    /**
     * short数组转byte数组
     *
     * @param src
     * @return
     */
    private byte[] toByteArray(short[] src) {
        int count = src.length;
        byte[] dest = new byte[count << 1];
        for (int i = 0; i < count; i++) {
            dest[i * 2] = (byte) (src[i]);
            dest[i * 2 + 1] = (byte) (src[i] >> 8);
        }
        return dest;
    }


    //播放文件
    public void playRecord() {
        if(file == null){
            return;
        }
        //读取文件
        int musicLength = (int) (file.length() / 2);
        short[] music = new short[musicLength];
        try {
            InputStream is = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(is);
            DataInputStream dis = new DataInputStream(bis);
            int i = 0;
            while (dis.available() > 0) {
                music[i] = dis.readShort();
                i++;
            }
            dis.close();
            AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                    16000, AudioFormat.CHANNEL_CONFIGURATION_MONO,
                    AudioFormat.ENCODING_PCM_16BIT,
                    musicLength * 2,
                    AudioTrack.MODE_STREAM);
            audioTrack.play();
            audioTrack.write(music, 0, musicLength);
            audioTrack.stop();
        } catch (Throwable t) {
            Log.e(TAG, "播放失败");
        }
    }

    //删除文件
    private void deleFile() {
        if(file == null){
            return;
        }
        file.delete();
        AppLogUtils.e(TAG+"文件删除成功");
    }


}
