package com.fs.aiSoundReplication.service.impl;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.fs.aiSoundReplication.config.TtsConfig;
import com.fs.aiSoundReplication.config.VoiceCloneConfig;
import com.fs.aiSoundReplication.exception.VoiceCloneException;
import com.fs.aiSoundReplication.param.TtsRequest;
import com.fs.aiSoundReplication.param.TtsResponse;
import com.fs.aiSoundReplication.service.TtsService;
import com.fs.fastgptApi.util.AudioUtils;
import com.fs.fastgptApi.vo.AudioVO;
import com.fs.system.oss.CloudStorageService;
import com.fs.system.oss.OSSFactory;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.Base64;

import static com.fs.fastgptApi.util.AudioUtils.getDurations;
import static com.fs.fastgptApi.util.AudioUtils.transferAudioSilk;

@Service
@Slf4j
public class TtsServiceImpl implements TtsService {

    @Autowired
    private TtsConfig ttsConfig;

    @Autowired
    private VoiceCloneConfig voiceCloneConfig;

    @Autowired
    private OkHttpClient okHttpClient;

    @Autowired
    private ObjectMapper objectMapper;

    private final ExecutorService executorService = Executors.newFixedThreadPool(5);

    private static final String AUTHORIZATION_HEADER = "Authorization";
    private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");

    @Override
    public AudioVO textToSpeech(TtsRequest request) {
        try {
            // 1. 参数校验
            validateTtsRequest(request);

            // 2. 设置默认值
            setDefaultValues(request);

            // 3. 构建请求体
            String requestBody = buildRequestBody(request);

            // 4. 构建HTTP请求
            Request httpRequest = buildHttpRequest(requestBody);

            // 5. 发送请求（带重试）
            byte[] bytes = executeTtsRequest(httpRequest);

            // 6. 检查音频数据
            if (bytes == null || bytes.length == 0) {
                log.error("音频数据为空，VoiceType: {}", request.getVoiceType());
                return null;
            }

            // 7. 自动保存音频文件
            // 创建临时文件
            File tempFile = File.createTempFile("tts_", ".wav");
            try (FileOutputStream fos = new FileOutputStream(tempFile)) {
                fos.write(bytes);
            }
            // 上传到OSS
            try (FileInputStream fileInputStream = new FileInputStream(tempFile)) {
                //直接转silk然后传桶，返回url     优化-需要wav格式
                CloudStorageService storage = OSSFactory.build();
                String wavUrl = storage.uploadSuffix(fileInputStream, ".wav");
//                AudioVO audioVO = AudioUtils.transferAudioSilkFromUrl(wavUrl, false);
                Integer durations = getDurations(tempFile.getParent()+"\\"+tempFile.getName());
                String silkUrl = transferAudioSilk(tempFile.getParent()+"\\", tempFile.getName(), false);
                AudioVO audioVO = new AudioVO();
                audioVO.setDuration(durations);
                audioVO.setUrl(silkUrl);
                audioVO.setWavUrl(wavUrl);
                log.info("音频文件上传OSS成功: {}", audioVO.getUrl());
                return audioVO;
            } finally {
                // 删除临时文件
                tempFile.delete();
            }

        } catch (Exception e) {
            log.error("TTS合成失败，reqId: {}, 错误: {}",
                    request.getReqId(), e.getMessage());
            throw e instanceof VoiceCloneException ?
                    (VoiceCloneException) e :
                    new VoiceCloneException("TTS合成失败", e);
        }
    }

//    @Override
//    public String textToSpeech(String text, String voiceType) {
//        // 创建简化版请求
//        TtsRequest request = new TtsRequest(
//                voiceCloneConfig.getAppId(),
//                voiceCloneConfig.getAccessToken(),
//                voiceType,
//                text
//        );
//
//        // 设置默认参数
//        request.setFormat(ttsConfig.getDefaultFormat());
//        request.setSampleRate(ttsConfig.getDefaultSampleRate());
//        request.setCluster(ttsConfig.getDefaultCluster());
//
//        return textToSpeech(request);
//    }

//    @Override
//    public File textToSpeechAndSave(TtsRequest request, String savePath) {
//        try {
//            // 1. 执行TTS合成
//            TtsResponse response = textToSpeech(request);
//
//            if (response.getData() == null || response.getData().getAudio() == null) {
//                throw new VoiceCloneException(-1, "音频数据为空");
//            }
//
//            // 2. 解码Base64音频数据
//            byte[] audioBytes = Base64.getDecoder().decode(response.getData().getAudio());
//
//            // 3. 确定保存路径
//            String finalSavePath = savePath != null ? savePath : ttsConfig.getAudioSavePath();
//
//            // 创建目录
//            Path directory = Paths.get(finalSavePath);
//            if (!Files.exists(directory)) {
//                Files.createDirectories(directory);
//            }
//
//            // 4. 生成文件名
//            String fileName = String.format("%s_%s.%s",
//                    request.getVoiceType(),
//                    request.getReqId().substring(0, 8),
//                    request.getFormat());
//
//            File audioFile = new File(finalSavePath, fileName);
//
//            // 5. 保存文件
//            try (FileOutputStream fos = new FileOutputStream(audioFile)) {
//                fos.write(audioBytes);
//            }
//
//            log.info("音频文件保存成功: {}, 大小: {}KB",
//                    audioFile.getAbsolutePath(), audioBytes.length / 1024);
//
//            return audioFile;
//
//        } catch (IOException e) {
//            log.error("保存音频文件失败", e);
//            throw new VoiceCloneException("保存音频文件失败", e);
//        }
//    }

//    @Override
//    public byte[] textToSpeechBytes(TtsRequest request) {
//         textToSpeech(request);
//    }

//    @Override
//    public String textToSpeechStream(TtsRequest request) {
//        byte[] audioBytes = textToSpeechBytes(request);
//
//    }

//    @Override
//    public List<File> batchTextToSpeech(List<String> texts, String voiceType) {
//        List<CompletableFuture<File>> futures = new ArrayList<>();
//        List<File> results = new ArrayList<>();
//
//        for (int i = 0; i < texts.size(); i++) {
//            final String text = texts.get(i);
//            final int index = i;
//
//            CompletableFuture<File> future = CompletableFuture.supplyAsync(() -> {
//                try {
//                    TtsRequest request = new TtsRequest(
//                            voiceCloneConfig.getAppId(),
//                            voiceCloneConfig.getAccessToken(),
//                            voiceType,
//                            text
//                    );
//                    request.setReqId(String.format("batch_%s_%d",
//                            UUID.randomUUID().toString().substring(0, 8), index));
//
//                    return textToSpeechAndSave(request, null);
//                } catch (Exception e) {
//                    log.error("批量TTS处理失败，文本索引: {}, 错误: {}", index, e.getMessage());
//                    return null;
//                }
//            }, executorService);
//
//            futures.add(future);
//        }
//
//        // 等待所有任务完成
//        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
//
//        // 收集结果
//        for (CompletableFuture<File> future : futures) {
//            try {
//                File file = future.get();
//                if (file != null) {
//                    results.add(file);
//                }
//            } catch (Exception e) {
//                log.error("获取批量处理结果失败", e);
//            }
//        }
//
//        log.info("批量TTS处理完成，成功: {}/{}", results.size(), texts.size());
//        return results;
//    }

    // ============ 私有方法 ============

    private void validateTtsRequest(TtsRequest request) {
        if (request == null) {
            throw new VoiceCloneException(1001, "请求参数不能为空");
        }

        if (request.getText() == null || request.getText().trim().isEmpty()) {
            throw new VoiceCloneException(1001, "文本内容不能为空");
        }

        if (request.getText().length() > ttsConfig.getMaxTextLength()) {
            throw new VoiceCloneException(1001,
                    String.format("文本长度超过限制(%d字符)", ttsConfig.getMaxTextLength()));
        }

        if (request.getVoiceType() == null || request.getVoiceType().trim().isEmpty()) {
            throw new VoiceCloneException(1001, "音色ID不能为空");
        }

        if (request.getReqId() == null || request.getReqId().trim().isEmpty()) {
            request.setReqId(UUID.randomUUID().toString());
        }
    }

    private void setDefaultValues(TtsRequest request) {
        if (request.getAppId() == null || request.getAppId().equals("")) {
            request.setAppId(voiceCloneConfig.getAppId());
        }

        if (request.getToken() == null || request.getToken().equals("")) {
            request.setToken(voiceCloneConfig.getAccessToken());
        }

        if (request.getCluster() == null) {
            request.setCluster(ttsConfig.getDefaultCluster());
        }

        if (request.getFormat() == null) {
            request.setFormat(ttsConfig.getDefaultFormat());
        }

        if (request.getSampleRate() == null) {
            request.setSampleRate(ttsConfig.getDefaultSampleRate());
        }

        if (request.getSpeed() == null) {
            request.setSpeed(ttsConfig.getDefaultSpeed());
        }

        if (request.getVolume() == null) {
            request.setVolume(ttsConfig.getDefaultVolume());
        }

        if (request.getPitch() == null) {
            request.setPitch(ttsConfig.getDefaultPitch());
        }
    }

    private String buildRequestBody(TtsRequest request) throws IOException {
        Map<String, Object> requestBody = new HashMap<>();

        // 必填参数
        HashMap<String, Object> app = new HashMap<String, Object>() {{
            put("appid", request.getAppId());
            put("token", request.getToken());
            put("cluster", request.getCluster());
        }};
        HashMap<String, Object> user = new HashMap<String, Object>() {{
            put("uid","01");
        }};
        HashMap<String, Object> audio = new HashMap<String, Object>() {{
            put("voice_type", request.getVoiceType());
        }};
        if (request.getFormat() != null)audio.put("encoding", request.getFormat());
        if (request.getSpeed() != null)audio.put("speed_ratio", request.getSpeed());

        HashMap<String, Object> requestMap = new HashMap<String, Object>() {{
            put("reqid", request.getReqId());
            put("text", request.getText());
            put("operation","query");
            put("split_sentence", 1);//处理声音复刻语速过快
        }};

        requestBody.put("app",app);
        requestBody.put("user", user);
        requestBody.put("audio", audio);
        requestBody.put("request", requestMap);

        // 可选参数
//        if (request.getFormat() != null) {
//            requestBody.put("format", request.getFormat());
//        }

//        if (request.getSampleRate() != null) {
//            requestBody.put("sample_rate", request.getSampleRate());
//        }

//        if (request.getSpeed() != null) {
//            requestBody.put("speed", request.getSpeed());
//        }

//        if (request.getVolume() != null) {
//            requestBody.put("volume", request.getVolume());
//        }

//        if (request.getPitch() != null) {
//            requestBody.put("pitch", request.getPitch());
//        }

//        if (request.getAudioEncodeType() != null) {
//            requestBody.put("audio_encode_type", request.getAudioEncodeType());
//        }

//        if (request.getEnableSubtitle() != null) {
//            requestBody.put("enable_subtitle", request.getEnableSubtitle());
//        }

//        if (request.getVoiceId() != null) {
//            requestBody.put("voice_id", request.getVoiceId());
//        }

//        if (request.getLanguage() != null) {
//            requestBody.put("language", request.getLanguage());
//        }

//        if (request.getEmotion() != null) {
//            requestBody.put("emotion", request.getEmotion());
//        }

//        if (request.getSpeakingStyle() != null) {
//            requestBody.put("speaking_style", request.getSpeakingStyle());
//        }

        return objectMapper.writeValueAsString(requestBody);
    }

    private Request buildHttpRequest(String requestBody) {
        RequestBody body = RequestBody.create(JSON,requestBody );

        return new Request.Builder()
                .url(ttsConfig.getHttpUrl())
                .post(body)
                .addHeader(AUTHORIZATION_HEADER, "Bearer;" + voiceCloneConfig.getAccessToken())
                .addHeader("Content-Type", "application/json")
                .build();
    }

    private byte[] executeTtsRequest(Request httpRequest) {
        IOException lastException = null;

        for (int i = 0; i < ttsConfig.getMaxRetryTimes(); i++) {
            try (Response response = okHttpClient.newCall(httpRequest).execute()) {
                if (!response.isSuccessful()) {
                    throw new IOException("HTTP请求失败，状态码: " + response.code());
                }

                String responseBody = response.body().string();
                log.debug("TTS API响应: {}", responseBody);

                Map<String, Object> responseMap = objectMapper.readValue(responseBody, Map.class);
                Integer code = (Integer) responseMap.get("code");
                if (code != null && code != 3000) {
                    String message = (String) responseMap.get("message");
                    throw new VoiceCloneException(code != null ? code : -1,
                            String.format("TTS合成失败: %s (错误码: %d)", message, code != null ? code : -1));
                }
                // 获取data字段（base64编码的音频数据）
                Object data = responseMap.get("data");
                if (data == null) {
                    throw new VoiceCloneException(-1, "TTS音频数据为空");
                }

                if (!(data instanceof String)) {
                    throw new VoiceCloneException(-1, "TTS音频数据格式错误");
                }

                String base64Audio = (String) data;

                // 解码base64音频数据
                try {
                    return Base64.getDecoder().decode(base64Audio);
                } catch (IllegalArgumentException e) {
                    log.error("Base64解码失败", e);
                    throw new VoiceCloneException("音频数据解码失败", e);
                }

            } catch (IOException e) {
                lastException = e;
                log.warn("第{}次TTS请求失败: {}", i + 1, e.getMessage());

                if (i < ttsConfig.getMaxRetryTimes() - 1) {
                    try {
                        Thread.sleep(ttsConfig.getRetryInterval());
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        throw new VoiceCloneException("重试被中断", ie);
                    }
                }
            }
        }

        throw new VoiceCloneException("TTS请求失败，达到最大重试次数", lastException);
    }

    private void checkTtsResponse(TtsResponse response) {
        if (response == null || response.getBaseResp() == null) {
            throw new VoiceCloneException(-1, "TTS响应数据异常");
        }

        Integer statusCode = response.getBaseResp().getStatusCode();
        if (statusCode != 0) {
            String errorMessage = response.getBaseResp().getStatusMessage();
            throw new VoiceCloneException(statusCode,
                    String.format("TTS合成失败: %s (错误码: %d)", errorMessage, statusCode));
        }

        if (response.getData() == null) {
            throw new VoiceCloneException(-1, "TTS音频数据为空");
        }

        if (response.getData().getAudio() == null) {
            throw new VoiceCloneException(-1, "Base64音频数据为空");
        }
    }

    private void autoSaveAudio(String base64Audio, String reqId, String format) {
        try {
            // 解码音频
            byte[] audioBytes = Base64.getDecoder().decode(base64Audio);

            // 创建保存目录
            Path saveDir = Paths.get(ttsConfig.getAudioSavePath());
            if (!Files.exists(saveDir)) {
                Files.createDirectories(saveDir);
            }

            // 生成文件名
            String fileName = String.format("auto_save_%s.%s",
                    reqId.substring(0, 8), format);
            Path filePath = saveDir.resolve(fileName);

            // 保存文件
            Files.write(filePath, audioBytes);

            log.debug("音频自动保存成功: {}", filePath);

        } catch (Exception e) {
            log.warn("音频自动保存失败: {}", e.getMessage());
            // 不抛出异常，自动保存失败不影响主要功能
        }
    }
}
