package com.fs.company.utils;

import com.fs.common.exception.ServiceException;
import com.fs.system.oss.CloudStorageService;
import com.fs.system.oss.OSSFactory;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class AudioUtils {
    /**
     * 工具地址
     **/
    static String path = "c:\\";
    static String destinationDir = "c:\\hook\\";

    /**
     * 从网络 URL 转换 MP3/WAV到SILk格式
     *
     * @param audioUrl  音频文件的 URL
     * @param isSource  是否清空原文件
     * @return SILK 文件路径
     */
    public static String transferAudioSilkFromUrl(String audioUrl, boolean isSource) {
        try {
            // 下载文件到本地临时路径
            File tempFile = downloadFileFromUrl(audioUrl);
            if (tempFile == null) {
                throw new ServiceException("下载文件失败");
            }

            String silkUrl = transferAudioSilk(tempFile.getParent()+"\\", tempFile.getName(), isSource);
            // 删除临时文件
            tempFile.delete();

            // 调用原来的转换方法
            return silkUrl;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * MP3/WAV转SILk格式
     *
     * @param path 文件路径 例：D:\\file\\
     * @param name 文件名称 例：audio.mp3/audio.wav
     * @param isSource 是否清空原文件
     * @return silk文件路径
     * @throws Exception
     */
    public static String transferAudioSilk(String path, String name, boolean isSource) {
        try {
            // 判断后缀格式
            String suffix = name.split("\\.")[1];
            if (!suffix.toLowerCase().equals("mp3") && !suffix.toLowerCase().equals("wav")) {
                throw new ServiceException("文件格式必须是mp3/wav");
            }
            String filePath = path + name;
            File file = new File(filePath);
            if (!file.exists()) {
                throw new Exception("文件不存在！");
            }
            // 文件名时拼接
            SimpleDateFormat ttime = new SimpleDateFormat("yyyyMMddhhMMSS");
            String time = ttime.format(new Date());
            // 导出的pcm格式路径
            String pcmPath = path + "PCM_" + time + ".pcm";
            // 先将mp3/wav转换成pcm格式
            transferAudioPcm(filePath, pcmPath);
            // 导出的silk格式路径
            String silkPath = path + "SILK_" + time + ".silk";
            // 转换成silk格式
            transferPcmSilk(pcmPath, silkPath);
            // 删除pcm文件
            File pcmFile = new File(pcmPath);
            if (pcmFile.exists()) {
                pcmFile.delete();
            }
            if (isSource) {
                File audioFile = new File(filePath);

                if (audioFile.exists()) {
                    audioFile.delete();
                }
            }

            File silkFile = new File(silkPath);
            //上传silk文件
            String silkPathSuffix = silkPath.split("\\.")[1];
            CloudStorageService storage = OSSFactory.build();
            byte[] fileBytes = Files.readAllBytes(silkFile.toPath());
            String silkUrl = storage.uploadSuffix(fileBytes, "."+silkPathSuffix);

            if (silkFile.exists()) {
                silkFile.delete();
            }
            return silkUrl;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * mp3/wav 通用
     * @param fpath
     * @param target
     */
    private static void transferAudioPcm(String fpath, String target) {
        List<String> commend = new ArrayList<String>();
        commend.add(path + "ffmpeg.exe");
        commend.add("-y");
        commend.add("-i");
        commend.add(fpath);
        commend.add("-f");
        commend.add("s16le");
        commend.add("-ar");
        commend.add("24000");
        commend.add("-ac");
        commend.add("1");
        commend.add(target);
        try {
            ProcessBuilder builder = new ProcessBuilder();
            builder.command(commend);
            Process p = builder.start();
            p.waitFor();
            p.destroy();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * silk_v3_encoder.exe，转成Silk格式
     * @param pcmPath pcm 文件地址
     * @param target  转换后的silk地址
     * silk_v3_encoder.exe 路径
     * pcm文件地址
     * silk输出地址
     * -Fs_API <Hz>            : API sampling rate in Hz, default: 24000
     * -Fs_maxInternal <Hz>    : Maximum internal sampling rate in Hz, default: 24000
     * -packetlength <ms>      : Packet interval in ms, default: 20
     * -rate <bps>            : Target bitrate;   default: 25000
     * -loss <perc>          : Uplink loss estimate, in percent (0-100);  default: 0
     * -complexity <comp>   : Set complexity, 0: low, 1: medium, 2: high; default: 2
     * -DTX <flag>          : Enable DTX (0/1); default: 0
     * -quiet               : Print only some basic values
     * -tencent             : Compatible with QQ/Wechat
     */
    public static void transferPcmSilk(String pcmPath, String target) {
        Process process = null;
        try {
            /**
             // 1、这一节的，语音长度太长会使音频长度丢失
             List<String> commend = new ArrayList<>();
             // 指令，可参照方法注释， 请不要在commend.add()里同时写【-参数 值】
             commend.add(path + "silk_v3_encoder.exe");
             commend.add(pcmPath);
             commend.add(target);
             commend.add("-tencent");
             ProcessBuilder builder = new ProcessBuilder();
             builder.command(commend);
             process = builder.start();
             // 如果删除下班这行写process.waitFor() ，太长的语音会阻塞，BufferedReader 打印出来太长的语音也会阻塞
             process = Runtime.getRuntime().exec("taskkill -f -t -im silk_v3_encoder.exe");
             */
            // 方法2，除了会弹出弹窗，没什么问题 cmd /c 极为重要，执行完毕后会自动关闭
            process = Runtime.getRuntime().exec("cmd /c start " + path + "silk_v3_encoder.exe " + pcmPath + " " + target + " -tencent");
            process .waitFor();
            Thread.sleep(1000);
            // 有更好的方法会后续慢慢更新..
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (process != null) {
                process.destroy();
            }
        }
    }
    /**
     * 下载文件从网络 URL 到本地临时文件夹
     *
     * @param fileUrl 文件的网络 URL
     * @return 下载到本地的临时文件
     */
    private static File downloadFileFromUrl(String fileUrl) {
        InputStream inputStream = null;
        FileOutputStream outputStream = null;
        try {
            // 创建 HTTP 连接
            URL url = new URL(fileUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();

            // 检查是否成功连接
            if (connection.getResponseCode() != 200) {
                throw new ServiceException("无法下载音频文件，HTTP 响应码：" + connection.getResponseCode());
            }

            // 获取输入流
            inputStream = connection.getInputStream();

            // 创建临时文件，并指定存放地址
            String tempFileName = "temp_" + System.currentTimeMillis() + "_" + getFileExtension(fileUrl);
            File destinationDirectory = new File(destinationDir);

            // 确保目标目录存在
            if (!destinationDirectory.exists()) {
                destinationDirectory.mkdirs();
            }

            // 将文件保存到指定路径
            File tempFile = new File(destinationDirectory, tempFileName);

            // 写入文件
            outputStream = new FileOutputStream(tempFile);
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }

            return tempFile;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (inputStream != null) inputStream.close();
                if (outputStream != null) outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

//    private static File downloadFileFromUrl(String fileUrl)
//    {
//        InputStream inputStream = null;
//        FileOutputStream outputStream = null;
//        try {
//            // 创建 HTTP 连接
//            URL url = new URL(fileUrl);
//            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//            connection.setRequestMethod("GET");
//            connection.connect();
//
//            // 检查是否成功连接
//            if (connection.getResponseCode() != 200) {
//                throw new ServiceException("无法下载音频文件，HTTP 响应码：" + connection.getResponseCode());
//            }
//
//            // 获取输入流
//            inputStream = connection.getInputStream();
//
//            // 创建临时文件
//            String tempFileName = "temp_" + System.currentTimeMillis() + "_" + getFileExtension(fileUrl);
//            File tempFile = new File(tempFileName);
//
//            // 写入文件
//            outputStream = new FileOutputStream(tempFile);
//            byte[] buffer = new byte[8192];
//            int bytesRead;
//            while ((bytesRead = inputStream.read(buffer)) != -1) {
//                outputStream.write(buffer, 0, bytesRead);
//            }
//
//            return tempFile;
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            try {
//                if (inputStream != null) inputStream.close();
//                if (outputStream != null) outputStream.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
//        return null;
//    }

    /**
     * 获取文件扩展名
     *
     * @param fileUrl 文件路径
     * @return 文件扩展名
     */
    private static String getFileExtension(String fileUrl) {
        return fileUrl.substring(fileUrl.lastIndexOf("."));
    }

    // 省略其他方法的实现
}
