package com.ruoyi.ibs.audio.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.ibs.audio.domain.AudioProperties;
import com.ruoyi.ibs.audio.domain.AudioUploadDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.*;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;

/**
 * @Author 吴凯程
 * @Date 2025/11/21
 **/
@Service
@EnableAsync
@Slf4j
public class AudioService {

    public static final String AUDIO_ERROR_CODE = "---";
    public static final String AUDIO_WAIT_CODE = "000";
    private static final String TASK_ID_PREFIX = "AUDIO_RECO_";
    @Resource
    private RestTemplate restTemplate;
    @Resource
    private RedisCache redisCache;
    @Resource
    private AudioProperties audioProperties;

    public String uploadAudioAnalysis(AudioUploadDTO audioUploadDTO) {
        if (!checkFileType(audioUploadDTO.getFile(), ".mp3")){
            throw new ServiceException("文件类型错误: 只能上传mp3格式");
        }
        String uuid = IdUtils.fastSimpleUUID();
        uploadAudioAnalysis(TASK_ID_PREFIX + uuid, audioUploadDTO.getFile());
        return uuid;
    }

    public String getAudioAnalysis(String uuid) {
        if (redisCache.hasKey(TASK_ID_PREFIX + uuid)){
            return redisCache.getCacheObject(TASK_ID_PREFIX + uuid);
        }
        return AUDIO_ERROR_CODE;
    }

    @Async
    public void uploadAudioAnalysis(String taskId, MultipartFile file) {
        redisCache.setCacheObjectToEndDay(taskId, AUDIO_WAIT_CODE);
        JsonNode response = null;
        try{
            File audio = File.createTempFile(taskId, ".mp3");
            file.transferTo(audio);
            response = postRequestWithFile(audioProperties.getUrl(), "audio", audio);
            audio.delete();
        } catch (Exception e){
            log.error("语音转文字失败", e);
            redisCache.setCacheObjectToEndDay(taskId, AUDIO_ERROR_CODE);
        }
        if(response.get("code").asInt() != 0){
            log.error("语音转文字失败", response);
            redisCache.setCacheObjectToEndDay(taskId, AUDIO_ERROR_CODE);
        }
        redisCache.setCacheObject(taskId, response.get("text").toString().replace("\"", "").replace("'", ""));
    }

    private Boolean checkFileType(MultipartFile file, String type){
        String fileName = file.getOriginalFilename();
        if (fileName != null && fileName.contains(".")) {
            int lastDotIndex = fileName.lastIndexOf(".");
            String fileSuffix = fileName.substring(lastDotIndex);
            if (type.equals(fileSuffix)){
                return Boolean.TRUE;
            }
        }
        return Boolean.FALSE;
    }


    private JsonNode postRequestWithFile(String url, String fileName, File file){
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);

        MultiValueMap<String, Object> multipartBody = new LinkedMultiValueMap<>();
        multipartBody.add(fileName, new FileSystemResource(file));

        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(multipartBody, headers);

        ResponseEntity<JsonNode> response = restTemplate.exchange(
                url,
                HttpMethod.POST,
                requestEntity,
                JsonNode.class
        );
        log.info(String.valueOf(response.getBody()));
        return response.getBody();
    }


}
