package com.cf.imes.module.executor.service.manage.voice;


import com.cf.imes.module.executor.config.VocieParameters;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import jakarta.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Objects;
import java.util.Random;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Service
@Slf4j
public class VoiceServiceImpl implements VoiceService{

    @Resource
    private VocieParameters vocieParameters;




//    static {
//        System.loadLibrary("jacob-1.18-x64");
//    }

    //生成音频文件
    @Override
    public String voiceAnnouncements(String data) {


        // 音频保存的路径
        String path = vocieParameters.getPath();

        // 设置音频的质量（ 越大越好，目前最大好像 22，最小为 4 ）
        Long quality = vocieParameters.getQuality();

        // 朗读声音大小
        Long soundSize = vocieParameters.getSoundSize();

        // 朗读速度
        Long readingSpeed = vocieParameters.getReadingSpeed();

        ActiveXComponent ax = null;
        Dispatch spFileStream = null;
        Dispatch spAudioFormat = null;
        Dispatch spVoice = null;
        try{
            ax = new ActiveXComponent("Sapi.SpFileStream");
            spFileStream = ax.getObject();

            ax = new ActiveXComponent("Sapi.SpAudioFormat");
            spAudioFormat = ax.getObject();

            spVoice = new ActiveXComponent("Sapi.SpVoice").getObject();
            // 设置音频流格式
            Dispatch.put(spAudioFormat, "Type", new Variant(quality));
            // 设置文件输出流格式
            Dispatch.putRef(spFileStream, "Format", spAudioFormat);
            // 随机数，控制文件的名字
            int randomInt = new Random(System.currentTimeMillis()).nextInt(900) + 100;// 生成100到999之间的随机数
            // 文件的路径
            String filePath = path + randomInt + ".mp3";

            // 调用输出文件流打开方法，创建一个.wav文件
            Dispatch.call(spFileStream, "Open", new Variant(filePath), new Variant(3), new Variant(true));
            // 设置声音对象的音频输出流为输出文件对象
            Dispatch.putRef(spVoice, "AudioOutputStream", spFileStream);
            // 设置音量  0 ~ 100
            Dispatch.put(spVoice, "Volume", new Variant(soundSize));
            // 设置朗读速度  -10 ~ +10
            Dispatch.put(spVoice, "Rate", new Variant(readingSpeed));

            Dispatch.call(spVoice, "Speak", new Variant(data));

            log.info("输出语音文件成功！");

            return filePath;

        }catch(Exception e){
            e.printStackTrace();
        }finally {
            // 关闭输出文件
            Dispatch.call(Objects.requireNonNull(spFileStream), "Close");
            Dispatch.putRef(Objects.requireNonNull(spVoice), "AudioOutputStream", null);

            Objects.requireNonNull(spAudioFormat).safeRelease();
            spFileStream.safeRelease();
            spVoice.safeRelease();
            ax.safeRelease();
        }

        return null;
    }





    @Override
    public ResponseEntity<byte[]> getVoice( String fileName) {
        try {
            File audioFile = new File(fileName);
            if (!audioFile.exists()) {
                return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
            }

            // 读取文件到字节数组
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            try (FileInputStream fileInputStream = new FileInputStream(audioFile)) {
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                    byteArrayOutputStream.write(buffer, 0, bytesRead);
                }
            }

            byte[] audioBytes = byteArrayOutputStream.toByteArray();

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType("audio/mpeg"));
            headers.setContentLength(audioBytes.length);
            headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");

            return new ResponseEntity<>(audioBytes, headers, HttpStatus.OK);

        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }








    /**
     * 把生成的音频文件进行压缩
     * @param fileNames 需要压缩的文件名称列表(包含相对路径)
     * @param zipOutName 压缩后的文件名称
     **/
    @Override
    public void zipFiles(String fileNames, String zipOutName) throws IOException {
        WritableByteChannel writableByteChannel = null;
        ByteBuffer buffer = ByteBuffer.allocate(2048);
        FileInputStream fileInputStream = null;
        FileChannel fileChannel = null;
        try (ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipOutName))) {
            writableByteChannel = Channels.newChannel(zipOutputStream);
            File source = new File(fileNames);
            zipOutputStream.putNextEntry(new ZipEntry(source.getName()));
            fileInputStream = new FileInputStream(fileNames);
            fileChannel = fileInputStream.getChannel();
            while (fileChannel.read(buffer) != -1) {
                //更新缓存区位置
                buffer.flip();
                while (buffer.hasRemaining()) {
                    writableByteChannel.write(buffer);
                }
                buffer.rewind();
            }
            fileChannel.close();

            log.info("文件压缩成功");


        } catch (Exception e) {
            log.error("batchZipFiles error  fileNames:");
        } finally {
            IOUtils.closeQuietly(writableByteChannel);
            IOUtils.closeQuietly(fileChannel);
            IOUtils.closeQuietly(fileInputStream);
            buffer.clear();
        }
    }


    // 删除生成的 mp3 文件
    @Override
    public void deleteFiles(String sourceFile) {

        // 检查文件路径是否为空
        if (sourceFile == null || sourceFile.isEmpty()) {
            log.error("文件路径为空");
        }

        File file = new File(sourceFile);

        // 检查文件是否存在
        if (!file.exists()) {
            log.error("文件不存在：" + sourceFile);
        }

        // 检查是否是文件
        if (!file.isFile()) {
            log.error("路径指向的不是文件：" + sourceFile);
        }

        // 尝试删除文件
        if (file.delete()) {
            log.error("文件删除成功：" + sourceFile);
        } else {
            log.error("文件删除失败：" + sourceFile);
        }
    }



}
