package com.hh.arome.common.microphone;

import android.app.Activity;
import android.content.Context;
import android.media.AudioFormat;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaMetadataRetriever;
import android.os.Build;
import android.os.CountDownTimer;
import android.os.Environment;
import android.os.Looper;
import android.text.TextUtils;

import androidx.annotation.RequiresApi;
import androidx.fragment.app.FragmentActivity;

import com.blankj.utilcode.util.FileUtils;
import com.common.lib_base.utils.StringUtils;
import com.hh.arome.MyApplication;
import com.hh.arome.common.scan.idcard.callback.IDCardScanResultCallback;
import com.hh.arome.utlis.log.AppLogUtils;
import com.hh.arome.utlis.log.LogType;
import com.zlw.main.recorderlib.RecordManager;
import com.zlw.main.recorderlib.recorder.RecordConfig;
import com.zlw.main.recorderlib.recorder.RecordHelper;
import com.zlw.main.recorderlib.recorder.RecordService;
import com.zlw.main.recorderlib.recorder.listener.RecordResultListener;
import com.zlw.main.recorderlib.recorder.listener.RecordSoundSizeListener;
import com.zlw.main.recorderlib.recorder.listener.RecordStateListener;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.Calendar;
import java.util.Locale;

import static com.hh.arome.common.Constants.Value.TIME_RECORD_INTERVAL;

public class ZlwRecordManager {

    RecordManager recordManager = RecordManager.getInstance();


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

    //将构造方法私有化，禁止外部通过构造方法创建实例

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


    Context mContext;

    public ZlwRecordManager(Context context) {
        this.mContext = context;
        init();
    }

    private void init() {

        recordManager.init(MyApplication.getContext(), true);

        recordManager.changeFormat(RecordConfig.RecordFormat.MP3);

        recordManager.changeRecordConfig(recordManager.getRecordConfig().setSampleRate(16000));
        recordManager.changeRecordConfig(recordManager.getRecordConfig().setEncodingConfig(AudioFormat.ENCODING_PCM_16BIT));

        String recordDir = String.format(Locale.getDefault(), "%s/Record/arome/",
                Environment.getExternalStorageDirectory().getAbsolutePath());

        recordManager.changeRecordDir(recordDir);


        filePath = RecordService.getFilePath();
        AppLogUtils.e("录音文件filePath：" + filePath);
        file = FileUtils.getFileByPath(filePath);

    }

    // 文件夹——包含所有录音文件
    String recordFile = "/storage/emulated/0/Record/arome/";
    // 录音文件
    File file;
    // 录音文件地址
    String filePath;


    public void start() {
        voiceContent = "";
        recordManager.start();

        isStart = true;

    }

    IMicroPhoneSizeCallback iMicroPhoneSizeCallback;

    // 毫秒
    int intervalTime = TIME_RECORD_INTERVAL;
    // 最长5分钟
    int allTime = 5 * 60 * 1000;
    // 上一次增长的文件末尾位置
    int lastFilePosition = 0;

    CountDownTimer cdt;

    /**
     * 持续发送--开始
     * @param intervalTime
     * @param iMicroPhoneSizeCallback
     */
    public void startRecordSize(Integer intervalTime, IMicroPhoneSizeCallback iMicroPhoneSizeCallback) {
        this.intervalTime = intervalTime;
        this.iMicroPhoneSizeCallback = iMicroPhoneSizeCallback;

        isStart = true;

        if (intervalTime == null) {
            intervalTime = TIME_RECORD_INTERVAL;
        }
        intervalTime = Integer.parseInt(intervalTime + "");

        filePath = RecordService.getFilePath();
//        AppLogUtils.e("录音文件filePath：" + filePath);
        file = FileUtils.getFileByPath(filePath);



        if (file.exists() && !file.isDirectory()) {

        }else{
            AppLogUtils.e("录音文件---File does not exist or is not a file",
                "开始创建");

            File file = new File(filePath);

            try {
                if (file.createNewFile()) {
                    AppLogUtils.e("文件创建成功");
                } else {
                    AppLogUtils.e("文件已存在");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


        start();
        isStart = true;

        Integer finalIntervalTime = intervalTime;
//        new Thread() {
//            // 覆盖其中的run方法
//            public void run() {
//
//                Looper.prepare();


                cdt = new CountDownTimer(allTime, finalIntervalTime) {

                    @Override
                    public void onTick(long millisUntilFinished) {
                        // 间隔时间

                        AppLogUtils.e("录音文件finalIntervalTime：" + finalIntervalTime);


                        if (file.exists() && !file.isDirectory()) {
                            if (file.canRead()) {
                                long fileSize = file.length();
                                AppLogUtils.e("录音文件fileSize：" + fileSize);
                            } else {
                                AppLogUtils.e("录音文件---Cannot read the file");
                            }
                        } else {
                            AppLogUtils.e("录音文件---File does not exist or is not a file");
                        }


                        int curLength = Integer.parseInt(file.length() + "");

                        AppLogUtils.e("录音文件filePath：" + filePath,
                                "录音文件curLength：" + curLength,
                                "录音文件lastFilePosition：" + lastFilePosition);

                        String str = "";
                        if (lastFilePosition == 0) {
                            str = fileToBase64RandomAccessFile(file, 0, curLength);
                            AppLogUtils.e("第一段数据--" + str);
                        } else {
                            str = fileToBase64RandomAccessFile(file, lastFilePosition + 1, curLength);
                            AppLogUtils.e("第二段及以后的数据--" + str);
                        }

                        lastFilePosition = curLength;

                        isStart = true;
                        iMicroPhoneSizeCallback.onSizeSuccess(str);


                    }

                    @Override
                    public void onFinish() {
                        // 倒计时结束

                        if (file == null) {
                            AppLogUtils.e("file == null");
                            return;
                        }

                        String str = fileToBase64RandomAccessFile(file, lastFilePosition, Integer.parseInt(file.length() + ""));

                        isStart = false;
                        iMicroPhoneSizeCallback.onSizeSuccess(str);

                        stopAll();

                    }

                };

                cdt.start();


                Looper.loop();

//            }
//        }.start();

    }


    /**
     * 持续发送的--停止
     * @param iMicroPhoneSizeCallback
     */
    public void stopRecordSize(IMicroPhoneSizeCallback iMicroPhoneSizeCallback) {
        this.iMicroPhoneSizeCallback = iMicroPhoneSizeCallback;

        isStart = false;
        recordManager.stop();

        if (cdt != null) {
            cdt.cancel();
        }

        recordManager.setRecordResultListener(new RecordResultListener() {
            @Override
            public void onResult(File file) {

                if (file == null) {
                    AppLogUtils.e("file == null");
                    return;
                }

//                extractMp3Info(filePath);

//                String fileTypeByContentType = getFileTypeByContentType(filePath);
//                AppLogUtils.e("录音文件fileTypeByContentType--"+fileTypeByContentType);

                String str = fileToBase64RandomAccessFile(file, lastFilePosition, Integer.parseInt(file.length() + ""));
                iMicroPhoneSizeCallback.onSizeSuccess(str);

            }
        });


    }


    String voiceContent;

    IMicroPhoneResultCallback iMicroPhoneResultCallback;


    /**
     * 主动停止后，回调mp3后一整个返回
     * @param iMicroPhoneResultCallback
     */
//    public void getResultListener(IMicroPhoneResultCallback iMicroPhoneResultCallback) {
//        this.iMicroPhoneResultCallback = iMicroPhoneResultCallback;
//        stop();
//    }

    boolean isStart;


    /**
     * 停止录音
     * 生成mp3后，一整个返回
     */
    public void stopResultListener(IMicroPhoneResultCallback iMicroPhoneResultCallback) {
        this.iMicroPhoneResultCallback = iMicroPhoneResultCallback;

        isStart = false;

        if (recordManager == null) {
            iMicroPhoneResultCallback.onError("-1", "请先初始化");
            return;
        }

        recordManager.stop();

        recordManager.setRecordResultListener(new RecordResultListener() {
            @Override
            public void onResult(File file) {


                if (file == null) {
                    AppLogUtils.e("file == null");
                    iMicroPhoneResultCallback.onError("-1", "录音失败");
                    return;
                }



                String fileToBase64Str = fileToBase64(file);


                if (StringUtils.isNotNull(fileToBase64Str)) {
                    iMicroPhoneResultCallback.onSuccess(fileToBase64Str);
                } else {
                    iMicroPhoneResultCallback.onError("-1", "录音失败");
                }

            }
        });


    }


    public void stopAll(){
        if(recordManager!=null){
            recordManager.stop();
            isStart = false;
        }
    }


    // file-->bytes-->base64
    private String fileToBase64(File file) {


        String result = "";
        AppLogUtils.e("File--getAbsolutePath:" + file.getAbsolutePath());

        try {
            byte[] bytes = fileToByteArray(file.getAbsolutePath());
            AppLogUtils.e("File--bytes:" + bytes);

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

        return "";


    }


    private String fileToBase64RandomAccessFile(File file, int startPosition, int endPosition) {

        AppLogUtils.e(
                "getAbsolutePath:" + file.getAbsolutePath(),
                "startPosition:" + startPosition,
                "endPosition:" + endPosition);


        String result = "";


        try (RandomAccessFile randomAccessFile = new RandomAccessFile(filePath, "r")) {
            randomAccessFile.seek(startPosition); // 设置起始位置

            byte[] buffer = new byte[(int) (endPosition - startPosition)];
            int bytesRead = randomAccessFile.read(buffer);

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

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                String base64String = Base64.getEncoder().encodeToString(buffer);
                AppLogUtils.e("File--base64String:" + base64String);
                result = base64String;
                return result;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }

        return "";


    }



    public String randomAccessFile(File filePath, int startPosition, int endPosition) {
        try (RandomAccessFile randomAccessFile = new RandomAccessFile(filePath, "r")) {
            randomAccessFile.seek(startPosition); // 设置起始位置
            byte[] buffer = new byte[(int) (endPosition - startPosition)];
            int bytesRead = randomAccessFile.read(buffer);

            if (bytesRead > 0) {

                String sectionContents = new String(buffer);
                return sectionContents;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }

        return "";

    }


    public void destory() {
        recordManager.stop();
        recordManager = null;
    }


    public static byte[] fileToByteArray(String filePath) {
        FileInputStream fis = null;
        byte[] fileBytes = null;
        try {
            fis = new FileInputStream(filePath);
            fileBytes = new byte[fis.available()];
            fis.read(fileBytes);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return fileBytes;
    }


    public void deleteRecordFile() {

        boolean orExistsDir = FileUtils.createOrExistsDir(recordFile);

        if (!orExistsDir) {
            AppLogUtils.e("没有该录音文件");
            return;
        } else {
            AppLogUtils.e("有该录音文件");
        }

        File file = new File(recordFile);
        File[] files = file.listFiles();
        if (files != null) {
            for (File logFile : files) {
                FileUtils.delete(logFile);
            }
        } else {
//            com.blankj.utilcode.util.ToastUtils.showShort("未查询到日志");
        }
    }


    public static String getFileTypeByContentType(String filePath) {
        Path path = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            path = Paths.get(filePath);
        }
        String contentType = null;

        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                contentType = Files.probeContentType(path);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return contentType;
    }


    IMicroPhoneStateCallback iMicroPhoneStateCallback;

    public void getState(IMicroPhoneStateCallback iMicroPhoneStateCallback){
        this.iMicroPhoneStateCallback = iMicroPhoneStateCallback;
        AppLogUtils.e("onState--state--1");

        if(isStart){
            iMicroPhoneStateCallback.onState(1);
        }else{
            iMicroPhoneStateCallback.onState(0);
        }

//        recordManager.setRecordStateListener(new RecordStateListener() {
//            @Override
//            public void onStateChange(RecordHelper.RecordState state) {
//                AppLogUtils.e("onState--state--2");
//                switch (state) {
//                    case IDLE:
//                        // 空闲
//                        iMicroPhoneStateCallback.onState(0);
//                        AppLogUtils.e("onState--state--3");
//                        break;
//                    case RECORDING:
//                        // 录音中
//                        iMicroPhoneStateCallback.onState(1);
//                        break;
//                    case FINISH:
//                        // 录音结束
//                        iMicroPhoneStateCallback.onState(2);
//                        break;
//                    case PAUSE:
//                        iMicroPhoneStateCallback.onState(3);
//                        break;
//                    case STOP:
//                        iMicroPhoneStateCallback.onState(4);
//                        break;
//                    default:
//                        break;
//                }
//            }
//
//            @Override
//            public void onError(String error) {
//                AppLogUtils.e("error:"+error);
//                iMicroPhoneStateCallback.onError(-1,error+"");
//            }
//        });
    }




}
