package com.ruoyi.base.service.impl;

import java.util.List;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.TtsUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.base.domain.RobotOpsBroadcastContent;
import com.ruoyi.base.mapper.RobotOpsBroadcastContentMapper;
import com.ruoyi.base.service.IRobotOpsBroadcastContentService;

/**
 * 播报内容Service业务层处理
 *
 * @author ruoyi
 * @date 2026-04-27
 */
@Service
public class RobotOpsBroadcastContentServiceImpl implements IRobotOpsBroadcastContentService
{
    private static final Logger log = LoggerFactory.getLogger(RobotOpsBroadcastContentServiceImpl.class);

    /** 音频状态：0=未合成，1=成功，2=失败，3=合成中 */
    private static final String AUDIO_STATUS_NOT_SYNTHESIZED = "0";
    private static final String AUDIO_STATUS_SUCCESS = "1";
    private static final String AUDIO_STATUS_FAILED = "2";
    private static final String AUDIO_STATUS_SYNTHESIZING = "3";

    /** TTS 默认音色 */
    private static final String DEFAULT_VOICE = "Cherry";

    /** TTS 默认语种 */
    private static final String LANGUAGE_TYPE = "Chinese";

    @Autowired
    private RobotOpsBroadcastContentMapper robotOpsBroadcastContentMapper;

    /**
     * 查询播报内容
     *
     * @param id 播报内容主键
     * @return 播报内容
     */
    @Override
    public RobotOpsBroadcastContent selectRobotOpsBroadcastContentById(Long id)
    {
        return robotOpsBroadcastContentMapper.selectRobotOpsBroadcastContentById(id);
    }

    /**
     * 查询播报内容列表
     *
     * @param robotOpsBroadcastContent 播报内容
     * @return 播报内容
     */
    @Override
    public List<RobotOpsBroadcastContent> selectRobotOpsBroadcastContentList(RobotOpsBroadcastContent robotOpsBroadcastContent)
    {
        return robotOpsBroadcastContentMapper.selectRobotOpsBroadcastContentList(robotOpsBroadcastContent);
    }

    /**
     * 新增播报内容
     *
     * @param robotOpsBroadcastContent 播报内容
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertRobotOpsBroadcastContent(RobotOpsBroadcastContent robotOpsBroadcastContent)
    {
        robotOpsBroadcastContent.setCreateTime(DateUtils.getNowDate());
        robotOpsBroadcastContent.setUpdateTime(DateUtils.getNowDate());
        // 默认音频状态为未合成
        if (StringUtils.isBlank(robotOpsBroadcastContent.getAudioStatus()))
        {
            robotOpsBroadcastContent.setAudioStatus(AUDIO_STATUS_NOT_SYNTHESIZED);
        }
        int rows = robotOpsBroadcastContentMapper.insertRobotOpsBroadcastContent(robotOpsBroadcastContent);
        // 新增成功后，自动触发音频合成
        if (rows > 0 && StringUtils.isNotBlank(robotOpsBroadcastContent.getBroadcastText()))
        {
            synthesizeAudioAsync(robotOpsBroadcastContent.getId());
        }
        return rows;
    }

    /**
     * 修改播报内容
     *
     * @param robotOpsBroadcastContent 播报内容
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateRobotOpsBroadcastContent(RobotOpsBroadcastContent robotOpsBroadcastContent)
    {
        // 获取修改前的数据，用于判断是否需要重新合成
        RobotOpsBroadcastContent oldContent = selectRobotOpsBroadcastContentById(robotOpsBroadcastContent.getId());
        boolean needResynthesize = false;

        // 判断是否需要重新合成音频
        if (oldContent != null && StringUtils.isNotBlank(robotOpsBroadcastContent.getBroadcastText()))
        {
            // 文本发生变化，或之前合成失败
            if (!robotOpsBroadcastContent.getBroadcastText().equals(oldContent.getBroadcastText()))
            {
                needResynthesize = true;
            }
            else if (AUDIO_STATUS_FAILED.equals(oldContent.getAudioStatus()))
            {
                // 之前合成失败，需要重新合成
                needResynthesize = true;
            }
        }

        robotOpsBroadcastContent.setUpdateTime(DateUtils.getNowDate());
        int rows = robotOpsBroadcastContentMapper.updateRobotOpsBroadcastContent(robotOpsBroadcastContent);

        // 如果需要重新合成，且不在合成中
        if (rows > 0 && needResynthesize && !AUDIO_STATUS_SYNTHESIZING.equals(oldContent.getAudioStatus()))
        {
            synthesizeAudioAsync(robotOpsBroadcastContent.getId());
        }

        return rows;
    }

    /**
     * 批量删除播报内容
     *
     * @param ids 需要删除的播报内容主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteRobotOpsBroadcastContentByIds(Long[] ids)
    {
        if (ids != null && ids.length > 0)
        {
            for (Long id : ids)
            {
                // 删除前先删除本地音频文件
                RobotOpsBroadcastContent content = selectRobotOpsBroadcastContentById(id);
                if (content != null && StringUtils.isNotBlank(content.getAudioPath()))
                {
                    TtsUtil.deleteAudioFile(content.getAudioPath());
                }
            }
        }
        return robotOpsBroadcastContentMapper.deleteRobotOpsBroadcastContentByIds(ids);
    }

    /**
     * 删除播报内容信息
     *
     * @param id 播报内容主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteRobotOpsBroadcastContentById(Long id)
    {
        // 删除前先删除本地音频文件
        RobotOpsBroadcastContent content = selectRobotOpsBroadcastContentById(id);
        if (content != null && StringUtils.isNotBlank(content.getAudioPath()))
        {
            TtsUtil.deleteAudioFile(content.getAudioPath());
        }
        return robotOpsBroadcastContentMapper.deleteRobotOpsBroadcastContentById(id);
    }

    /**
     * 检查是否正在合成中
     *
     * @param id 播报内容主键
     * @return true=正在合成中，false=未在合成
     */
    @Override
    public boolean isSynthesizing(Long id)
    {
        RobotOpsBroadcastContent content = selectRobotOpsBroadcastContentById(id);
        return content != null && AUDIO_STATUS_SYNTHESIZING.equals(content.getAudioStatus());
    }

    /**
     * 合成音频（异步）
     * 调用阿里云百炼 TTS 合成语音，下载返回的音频 URL，保存路径到 audio_path
     *
     * @param id 播报内容主键
     */
    @Override
    @Async("ttsTaskExecutor")
    public void synthesizeAudio(Long id)
    {
        synthesizeAudioAsync(id);
    }

    /**
     * 异步合成音频的内部实现
     *
     * @param id 播报内容主键
     */
    private void synthesizeAudioAsync(Long id)
    {
        log.info("[BroadcastContent] 开始合成音频，id: {}", id);

        try
        {
            // 1. 获取播报内容
            RobotOpsBroadcastContent content = selectRobotOpsBroadcastContentById(id);
            if (content == null)
            {
                log.error("[BroadcastContent] 播报内容不存在，id: {}", id);
                return;
            }

            // 2. 检查文本是否为空
            if (StringUtils.isBlank(content.getBroadcastText()))
            {
                log.warn("[BroadcastContent] 播报文本为空，id: {}", id);
                updateAudioStatus(id, AUDIO_STATUS_FAILED, null, "播报文本为空");
                return;
            }

            // 3. 更新状态为合成中
            updateAudioStatus(id, AUDIO_STATUS_SYNTHESIZING, null, null);

            // 4. 调用 TTS 合成
            TtsUtil.SynthesisResult result = TtsUtil.synthesize(content.getBroadcastText(), DEFAULT_VOICE, LANGUAGE_TYPE);

            // 5. 根据结果更新状态
            if (result.isSuccess())
            {
                // 合成成功
                updateAudioStatusWithDuration(id, AUDIO_STATUS_SUCCESS, result.getAudioPath(), result.getAudioDuration(), null);
                log.info("[BroadcastContent] 音频合成成功，id: {}，路径: {}，时长: {}秒", id, result.getAudioPath(), result.getAudioDuration());
            }
            else
            {
                // 合成失败
                String errorMsg = StringUtils.isNotBlank(result.getErrorMessage())
                        ? result.getErrorMessage()
                        : "TTS 合成失败，请检查阿里云百炼配置和网络连接";
                updateAudioStatus(id, AUDIO_STATUS_FAILED, null, errorMsg);
                log.error("[BroadcastContent] 音频合成失败，id: {}，错误: {}", id, result.getErrorMessage());
            }
        }
        catch (Exception e)
        {
            log.error("[BroadcastContent] 音频合成异常，id: {}，错误: {}", id, e.getMessage(), e);
            updateAudioStatus(id, AUDIO_STATUS_FAILED, null, e.getMessage());
        }
    }

    /**
     * 重新合成音频（异步）
     * 先删除旧的本地音频文件，再合成新的
     *
     * @param id 播报内容主键
     */
    @Override
    @Async("ttsTaskExecutor")
    public void regenerateAudio(Long id)
    {
        log.info("[BroadcastContent] 开始重新合成音频，id: {}", id);

        try
        {
            // 1. 获取播报内容
            RobotOpsBroadcastContent content = selectRobotOpsBroadcastContentById(id);
            if (content == null)
            {
                log.error("[BroadcastContent] 播报内容不存在，id: {}", id);
                return;
            }

            // 2. 删除旧的本地音频文件
            if (StringUtils.isNotBlank(content.getAudioPath()))
            {
                TtsUtil.deleteAudioFile(content.getAudioPath());
            }

            // 3. 调用合成（使用 synthesizeAudioAsync 的逻辑，但不需要再检查旧文件）
            synthesizeAudioAsync(id);
        }
        catch (Exception e)
        {
            log.error("[BroadcastContent] 重新合成音频异常，id: {}，错误: {}", id, e.getMessage(), e);
            updateAudioStatus(id, AUDIO_STATUS_FAILED, null, e.getMessage());
        }
    }

    /**
     * 更新音频状态
     *
     * @param id          播报内容主键
     * @param status      状态：0=未合成，1=成功，2=失败，3=合成中
     * @param audioPath   音频路径（成功时传入）
     * @param errorMsg    错误信息（失败时传入）
     */
    private void updateAudioStatus(Long id, String status, String audioPath, String errorMsg)
    {
        updateAudioStatusWithDuration(id, status, audioPath, null, errorMsg);
    }

    /**
     * 更新音频状态（包含时长）
     *
     * @param id          播报内容主键
     * @param status      状态：0=未合成，1=成功，2=失败，3=合成中
     * @param audioPath   音频路径（成功时传入）
     * @param duration    音频时长（秒）
     * @param errorMsg    错误信息（失败时传入）
     */
    private void updateAudioStatusWithDuration(Long id, String status, String audioPath, Integer duration, String errorMsg)
    {
        try
        {
            RobotOpsBroadcastContent update = new RobotOpsBroadcastContent();
            update.setId(id);
            update.setAudioStatus(status);
            update.setUpdateTime(DateUtils.getNowDate());

            if (StringUtils.isNotBlank(audioPath))
            {
                update.setAudioPath(audioPath);
            }

            if (duration != null)
            {
                update.setAudioDuration(duration);
            }

            if (StringUtils.isNotBlank(errorMsg))
            {
                update.setAudioErrorMsg(errorMsg);
            }

            // 成功时清空错误信息
            if (AUDIO_STATUS_SUCCESS.equals(status))
            {
                update.setAudioErrorMsg(null);
            }

            robotOpsBroadcastContentMapper.updateRobotOpsBroadcastContent(update);
        }
        catch (Exception e)
        {
            log.error("[BroadcastContent] 更新音频状态失败，id: {}，错误: {}", id, e.getMessage(), e);
        }
    }
}
