package com.cmvr.tts.service.impl;

import cn.hutool.core.util.IdUtil;
import com.cmvr.common.core.minio.MinioService;
import com.cmvr.common.core.page.TableDataInfo;
import com.cmvr.common.utils.DateUtils;
import com.cmvr.common.utils.SecurityUtils;
import com.cmvr.common.utils.StringUtils;
import com.cmvr.common.utils.http.HttpUtils;
import com.cmvr.tts.domain.CorpusInfo;
import com.cmvr.tts.domain.TtsSynthesizeTask;
import com.cmvr.tts.domain.vo.TtsSynthesizeTaskVo;
import com.cmvr.tts.mapper.CorpusInfoMapper;
import com.cmvr.tts.mapper.TtsSynthesizeTaskMapper;
import com.cmvr.tts.service.ITtsSynthesizeTaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;

/**
 * TTS合成任务Service业务层处理
 *
 * @author cmvr
 */
@Slf4j
@Service
public class TtsSynthesizeTaskServiceImpl implements ITtsSynthesizeTaskService {

    @Autowired
    private TtsSynthesizeTaskMapper ttsTaskMapper;

    @Autowired
    private CorpusInfoMapper corpusInfoMapper;

    @Autowired
    private MinioService minioService;

    @org.springframework.beans.factory.annotation.Value("${tts.external-api.url:http://192.168.1.101:8080/tts/synthesize}")
    private String externalTtsUrl;

    @org.springframework.beans.factory.annotation.Value("${minio.bucketName:cmvr-iot}")
    private String bucketName;

    /**
     * 查询TTS合成任务列表
     */
    @Override
    public TableDataInfo selectTtsTaskList(TtsSynthesizeTask task) {
        List<TtsSynthesizeTaskVo> list = ttsTaskMapper.selectTtsTaskVoList(task);
        return new TableDataInfo(list, list.size());
    }

    /**
     * 查询TTS合成任务详情
     */
    @Override
    public TtsSynthesizeTaskVo selectTtsTaskById(String id) {
        TtsSynthesizeTask task = ttsTaskMapper.selectTtsTaskById(id);
        if (task == null) {
            return null;
        }
        // 转换为VO，包含关联信息
        List<TtsSynthesizeTaskVo> voList = ttsTaskMapper.selectTtsTaskVoList(task);
        return voList != null && !voList.isEmpty() ? voList.get(0) : null;
    }

    /**
     * 新增TTS合成任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public TtsSynthesizeTask insertTtsTask(TtsSynthesizeTask task) {
        // 生成UUID作为主键
        if (task.getId() == null || task.getId().isEmpty()) {
            task.setId(IdUtil.fastSimpleUUID());
        }
        task.setTaskCode(IdUtil.fastSimpleUUID());
        task.setStatus("0");
        task.setCreateTime(DateUtils.getNowDate());
        task.setCreateBy(SecurityUtils.getUsername());
        
        int rows = ttsTaskMapper.insertTtsTask(task);
        
        // 异步调用外部TTS接口
        if (rows > 0) {
            callExternalTtsApi(task);
        }
        
        return task;
    }

    /**
     * 批量新增TTS合成任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchInsertTtsTask(List<TtsSynthesizeTask> tasks) {
        int count = 0;
        for (TtsSynthesizeTask task : tasks) {
            // 生成UUID作为主键
            if (task.getId() == null || task.getId().isEmpty()) {
                task.setId(IdUtil.fastSimpleUUID());
            }
            task.setTaskCode(IdUtil.fastSimpleUUID());
            task.setStatus("0");
            task.setCreateTime(DateUtils.getNowDate());
            task.setCreateBy(SecurityUtils.getUsername());
            ttsTaskMapper.insertTtsTask(task);
            
            // 异步调用外部TTS接口
            callExternalTtsApi(task);
            count++;
        }
        return count;
    }

    /**
     * 修改TTS合成任务
     */
    @Override
    public int updateTtsTask(TtsSynthesizeTask task) {
        task.setUpdateTime(DateUtils.getNowDate());
        task.setUpdateBy(SecurityUtils.getUsername());
        return ttsTaskMapper.updateTtsTask(task);
    }

    /**
     * 删除TTS合成任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteTtsTaskByIds(String[] ids) {
        for (String id : ids) {
            TtsSynthesizeTask task = ttsTaskMapper.selectTtsTaskById(id);
            if (task != null && StringUtils.isNotEmpty(task.getAudioFilePath())) {
                // 删除音频文件
                try {
                    minioService.deleteFile(bucketName, task.getAudioFilePath());
                } catch (Exception e) {
                    log.error("删除音频文件失败: {}", task.getAudioFilePath(), e);
                }
            }
            ttsTaskMapper.deleteTtsTaskById(id);
        }
        return ids.length;
    }

    /**
     * 重生成TTS任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int regenerateTask(String taskId) {
        TtsSynthesizeTask task = ttsTaskMapper.selectTtsTaskById(taskId);
        if (task == null) {
            throw new RuntimeException("任务不存在");
        }
        
        // 更新状态为待处理
        task.setStatus("0");
        task.setErrorMsg(null);
        task.setUpdateTime(DateUtils.getNowDate());
        task.setUpdateBy(SecurityUtils.getUsername());
        ttsTaskMapper.updateTtsTask(task);
        
        // 重新调用外部TTS接口
        callExternalTtsApi(task);
        
        return 1;
    }

    /**
     * 获取音频文件流
     */
    @Override
    public void getAudioStream(String taskId, HttpServletResponse response) {
        TtsSynthesizeTask task = ttsTaskMapper.selectTtsTaskById(taskId);
        if (task == null || StringUtils.isEmpty(task.getAudioFilePath())) {
            throw new RuntimeException("音频文件不存在");
        }
        
        try {
            InputStream inputStream = minioService.getObject(bucketName, task.getAudioFilePath());
            response.setContentType("audio/wav");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("audio_" + taskId + ".wav", "UTF-8"));
            
            OutputStream outputStream = response.getOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, len);
            }
            outputStream.flush();
            inputStream.close();
        } catch (Exception e) {
            log.error("获取音频流失败", e);
            throw new RuntimeException("获取音频流失败");
        }
    }

    /**
     * 导出TTS合成任务列表
     */
    @Override
    public byte[] exportTtsTaskList(TtsSynthesizeTask task) {
        List<TtsSynthesizeTaskVo> list = ttsTaskMapper.selectTtsTaskVoList(task);
        // TODO: 使用Excel工具类导出
        return new byte[0];
    }

    /**
     * 查询看板统计数据
     */
    @Override
    public Map<String, Object> getDashboardStats() {
        Map<String, Object> todayStats = ttsTaskMapper.selectDashboardStats();
        Map<String, Object> yesterdayStats = ttsTaskMapper.selectYesterdayStats();
        
        // 计算环比
        calculateGrowthRate(todayStats, yesterdayStats);
        
        return todayStats;
    }

    /**
     * 按语种统计
     */
    @Override
    public List<Map<String, Object>> getStatsByLanguage() {
        return ttsTaskMapper.selectStatsByLanguage();
    }

    /**
     * 按音色统计
     */
    @Override
    public List<Map<String, Object>> getStatsByVoice() {
        return ttsTaskMapper.selectStatsByVoice();
    }

    /**
     * 按情绪统计
     */
    @Override
    public List<Map<String, Object>> getStatsByEmotion() {
        return ttsTaskMapper.selectStatsByEmotion();
    }

    /**
     * 近7日趋势
     */
    @Override
    public List<Map<String, Object>> getLast7DaysTrend() {
        return ttsTaskMapper.selectLast7DaysTrend();
    }

    /**
     * 调用外部TTS接口
     */
    private void callExternalTtsApi(TtsSynthesizeTask task) {
        try {
            // 更新状态为合成中
            task.setStatus("1");
            ttsTaskMapper.updateTtsTask(task);
            
            // 构建请求参数 - 只支持text, voice, speed, volume, pitch, sampleRate, format
            Map<String, Object> params = new HashMap<>();
            params.put("text", task.getText());
            params.put("voice", task.getVoice());
            params.put("speed", task.getSpeed());
            params.put("volume", task.getVolume());
            params.put("pitch", task.getPitch());
            params.put("sampleRate", task.getSampleRate());
            params.put("format", task.getOutputFormat());
            
            // 调用外部TTS接口，返回音频文件(字节数组)
            byte[] audioBytes = HttpUtils.sendPostReturnBytes(externalTtsUrl, params);
            
            if (audioBytes != null && audioBytes.length > 0) {
                // 上传音频到Minio
                String objectName = "tts/" + DateUtils.datePath() + "/" + task.getTaskCode() + ".wav";
                ByteArrayInputStream inputStream = new ByteArrayInputStream(audioBytes);
                
                // 使用MinioService上传
                minioService.uploadStream(bucketName, objectName, inputStream, audioBytes.length, "audio/wav");
                
                // 更新任务状态
                task.setStatus("2");
                task.setAudioFilePath(objectName);
                task.setFileSize((long) audioBytes.length);

                // 估算音频时长（假设WAV格式，16bit采样）
                Integer sampleRateInt = Integer.parseInt(task.getSampleRate());
                double duration = audioBytes.length / (sampleRateInt * 2.0);
                task.setAudioDuration(BigDecimal.valueOf(duration).setScale(2, BigDecimal.ROUND_HALF_UP));
                ttsTaskMapper.updateTtsTask(task);
            } else {
                throw new RuntimeException("外部TTS接口返回空数据");
            }
        } catch (Exception e) {
            log.error("调用外部TTS接口失败", e);
            task.setStatus("3");
            task.setErrorMsg(e.getMessage());
            ttsTaskMapper.updateTtsTask(task);
        }
    }

    /**
     * 保存任务到语料库
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int saveToCorpus(String taskId, String categoryId) {
        // 查询任务
        TtsSynthesizeTask task = ttsTaskMapper.selectTtsTaskById(taskId);
        if (task == null) {
            throw new RuntimeException("任务不存在");
        }
        
        // 检查是否有音频文件
        if (StringUtils.isEmpty(task.getAudioFilePath())) {
            throw new RuntimeException("任务尚未合成音频，无法保存到语料库");
        }
        
        // 创建语料记录
        CorpusInfo corpus = new CorpusInfo();
        corpus.setId(IdUtil.fastSimpleUUID());
        corpus.setCategoryId(categoryId);
        corpus.setText(task.getText());
        corpus.setLanguage(task.getLanguage());
        corpus.setDialect(task.getDialect());
        corpus.setEmotion(task.getEmotion());
        corpus.setVoice(task.getVoice());
        corpus.setAudioFilePath(task.getAudioFilePath());
        corpus.setAudioDuration(task.getAudioDuration());
        corpus.setFileSize(task.getFileSize());
        corpus.setCreateBy(SecurityUtils.getUsername());
        corpus.setCreateTime(DateUtils.getNowDate());
        
        return corpusInfoMapper.insertCorpus(corpus);
    }

    /**
     * 计算环比增长率
     */
    private void calculateGrowthRate(Map<String, Object> today, Map<String, Object> yesterday) {
        if (yesterday == null || yesterday.isEmpty()) {
            today.put("totalTasksGrowth", "0%");
            today.put("todayTasksGrowth", "0%");
            today.put("avgDurationGrowth", "0%");
            return;
        }
        
        // 总任务数环比
        Long todayTotal = ((Number) today.get("totalTasks")).longValue();
        Long yesterdayTotal = ((Number) yesterday.get("totalTasks")).longValue();
        today.put("totalTasksGrowth", calculatePercent(todayTotal, yesterdayTotal));
        
        // 今日任务数环比
        Long todayNew = ((Number) today.get("todayTasks")).longValue();
        Long yesterdayNew = ((Number) yesterday.get("todayTasks")).longValue();
        today.put("todayTasksGrowth", calculatePercent(todayNew, yesterdayNew));
        
        // 平均时长环比
        Double todayAvg = ((Number) today.get("avgDuration")).doubleValue();
        Double yesterdayAvg = ((Number) yesterday.get("avgDuration")).doubleValue();
        today.put("avgDurationGrowth", calculatePercentDouble(todayAvg, yesterdayAvg));
    }

    private String calculatePercent(Long current, Long previous) {
        if (previous == 0) {
            return current > 0 ? "+100%" : "0%";
        }
        double growth = (current - previous) * 100.0 / previous;
        return String.format("%+.2f%%", growth);
    }

    private String calculatePercentDouble(Double current, Double previous) {
        if (previous == 0 || previous.isNaN()) {
            return "0%";
        }
        double growth = (current - previous) * 100.0 / previous;
        return String.format("%+.2f%%", growth);
    }
}
