package com.tashow.cloud.ai.service.dialog;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tashow.cloud.ai.controller.app.dialog.vo.AiDialogMessageRespVo;
import com.tashow.cloud.ai.controller.app.dialog.vo.DialogResp;
import com.tashow.cloud.ai.controller.app.dialog.vo.TranslateReqVo;
import com.tashow.cloud.ai.controller.app.dialog.vo.TranslateRespVo;
import com.tashow.cloud.ai.dal.dataobject.dialog.AiDialogDO;
import com.tashow.cloud.ai.dal.dataobject.dialog.AiDialogMessageDO;
import com.tashow.cloud.ai.dal.mysql.dialog.AiDialogMapper;
import com.tashow.cloud.ai.dal.mysql.dialog.AiDialogMessageMapper;
import com.tashow.cloud.common.pojo.PageParam;
import com.tashow.cloud.common.pojo.PageResult;
import com.tashow.cloud.common.util.object.BeanUtils;
import com.tashow.cloud.fileapi.api.file.FileApi;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.multipart.MultipartFile;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ai-对话 Service 实现类
 *
 * @author lwq
 */
@Service
@Validated
@Slf4j
public class AiDialogServiceImpl extends ServiceImpl<AiDialogMapper, AiDialogDO> implements AiDialogService {

    @Resource
    private AiDialogMessageMapper aiDialogMessageMapper;
    @Value("${translate-server}")
    private String translateServer;
    @Value("${file-server}")
    private String fileServer;
    @Resource
    private FileApi fileApi;

    private List<String> failedStr =List.of(
            "刚刚的音符太独特了，我没听清呢~可以再对我说一次吗？",
            "哇，这是哪来的小可爱？声音太有魅力了，让我一时走了神。请靠近一点，慢慢再说一遍好？",
            "背景音有点热闹，我有点分心啦～能在一个更安静的地方，让我专心听听TA的声音吗",
            "报告主人！声波受到不明干扰（可能是零食袋的声音？），翻译任务失败，请求二次输入！",
            "我的‘物种雷达’刚才打了个盹儿~快让我再听一次这美妙的声音！",
            "这声音太迷人了，让我CPU过载了！请简化一下环境音，我们再来一次？"
    );

    private Map<String,List<String>> failedMap =new HashMap<>(){{
        put("cat",List.of(
                "听得出是猫猫在说话，但TA似乎在表达一种很深邃的情绪..也许是个小秘密呢？",
                "喵星人的这段‘加密通话’等级太高了！翻译官正在努力学习中...你能通过TA的尾巴和眼神猜猜看吗？",
                "警报！警报！接收到喵星最高机密指令，我的权限不足，无法破译！建议提供小鱼干以获取更多线索"
        ));
        put("dog",List.of(
                "听得出是狗狗在说话，但TA似乎在表达一种很深邃的情绪...也许是个小秘密呢？",
                "汪语十级考试失败！这句大概是“今天的我比昨天更爱你了'之类的复杂情感吧",
                "汪星人的这段‘加密通话’等级太高了！翻译官正在努力学习中..你能通过TA的尾巴和眼神猜猜看吗？"
        ));
        put("common",List.of(
                "TA刚才可能用了某种古老的咒语，或者...只是在打一个很有思想的哈欠？",
                "这句‘话’的哲学深度超出了我的理解范围，TA可能是一位诗人～"
        ));
    }};

    private Map<String,List<String>> successMap =new HashMap<>(){{
        put("舒服",List.of(
                "TA 现在全身心都放松下来啦，正被满满的安全感包围着呢~ ",
                "听这均匀的呼吸，TA 的心正像云朵一样软绵绵、轻飘飘的哦。",
                "这是幸福的声音！此刻的TA，觉得自己是全世界最被爱的小宝贝",
                "环境很安心～主人很贴心～TA 正在小声说：好舒服呀～…"
        ));
        put("等待喂食",List.of(
                "小肚肚发出‘咕咕’警报啦！美食雷达正在全面启动，搜寻好吃的！",
                "来自TA的紧急通讯：‘报告！能量储备严重不足，请求立刻补充！",
                "你听到了吗？那是小饭碗在思念食物的声音！TA的眼神正在发出渴望的光波~",
                "“开饭铃”已经摇响！再不开饭，小委屈就要溢出来啦！"
        ));
        put("生气",List.of(
                "TA 现在有点小紧张哦，周围可能有让TA不安的东西，快给TA一点安慰吧",
                "检测到‘心跳加速’模式！TA需要一点空间和一个温柔的声音来平静下来",
                "TA 现在有点小紧张哦，周围可能有让TA不安的东西，快给TA一点安慰吧"
        ));
    }};

    private Map<String, String> petAvatars = new HashMap<>() {{
        put("cat", "https://petshy.tashowz.com/admin-api/infra/file/29/get/默认的猫.png");
        put("dog", "https://petshy.tashowz.com/admin-api/infra/file/29/get/默认的狗.png");
    }};

    private Map<String, String> petName = new HashMap<>() {{
        put("cat", "猫猫・三胖");
        put("dog", "狗狗・旺财");
    }};


    @Override
    public DialogResp getDialog(Long userId, PageParam pageParam) {
        AiDialogDO aiDialogDO = this.getOne(new LambdaQueryWrapper<AiDialogDO>().eq(AiDialogDO::getUserId, userId));
        if (aiDialogDO == null) {
            aiDialogDO = new AiDialogDO();
            aiDialogDO.setDialogStatus(1);
            aiDialogDO.setTitle("xxx");
            aiDialogDO.setUserId(userId);
            this.save(aiDialogDO);
        }

        PageResult<AiDialogMessageDO> messageDOS = aiDialogMessageMapper.selectPage(pageParam,
                new LambdaQueryWrapper<AiDialogMessageDO>().eq(AiDialogMessageDO::getDialogId, aiDialogDO.getId())
                        .orderByAsc(AiDialogMessageDO::getCreateTime)
        );

        DialogResp resp = new DialogResp();
        resp.setDialogId(aiDialogDO.getId());
        resp.setTitle(aiDialogDO.getTitle());
        resp.setMessages(BeanUtils.toBean(messageDOS, AiDialogMessageRespVo.class));
        return resp;
    }


    @Override
    @SneakyThrows
    public TranslateRespVo translate(TranslateReqVo fileReqVo) {
        AiDialogMessageDO messageDO = new AiDialogMessageDO();
        String fileName = fileReqVo.getFile().getOriginalFilename();
        //上传文件获取文件地址
        String fileUrl = fileServer + fileApi.createFile(fileName, "", fileReqVo.getFile().getBytes());
        //翻译结果
        translate(messageDO, fileUrl, fileName);

        //创建消息
        messageDO.setFileName(fileName);
        messageDO.setFileType(fileReqVo.getFile().getContentType());
        messageDO.setDialogId(fileReqVo.getDialogId());
        //前端无法转换时 后端进行转
        messageDO.setContentDuration(fileReqVo.getContentDuration());
        messageDO.setContentText(fileUrl);
        messageDO.setContentType(2);
        messageDO.setCreateTime(LocalDateTimeUtil.now());
        return BeanUtils.toBean(messageDO, TranslateRespVo.class);
    }

    @SneakyThrows
    private Long getFileDuration(MultipartFile file) {
        AudioInputStream audioStream = AudioSystem.getAudioInputStream(file.getInputStream());
        return (long) (audioStream.getFrameLength() / audioStream.getFormat().getFrameRate());
    }


    private AiDialogMessageDO translate(AiDialogMessageDO messageDO, String file, String fileName) {
        //调用大模型接口
        String result = "";
        try {
            result = HttpRequest.post(translateServer).form("audio_data", HttpUtil.downloadBytes(file), fileName).timeout(20000) //20秒超时时间
                    .execute().body();
        } catch (Exception e) {
            log.error("调用大模型翻译出错", e);
        }
        messageDO.setSourceResult(result);
        //数据解析
        JSONObject translateResult = JSON.parseObject(result);

        //翻译失败
        if (translateResult.isEmpty()
                || !translateResult.containsKey("intent_result")
                || !translateResult.getBoolean("is_species_sound")
                || translateResult.getDouble("confidence") < 0.7
        ) {
            messageDO.setTransStatus(0);
            messageDO.setTransResult(failedStr.get(RandomUtil.randomInt(failedStr.size())));
            return messageDO;
        }

        //标签 如 cat dog
        String speciesLabels = translateResult.getString("species_labels");
        //解析翻译结果
        JSONObject intentResult = translateResult.getJSONObject("intent_result");

        //宠物档案 todo
        messageDO.setPetId(1l);
        messageDO.setPetName(petName.get(speciesLabels));
        messageDO.setPetAvatar(petAvatars.get(speciesLabels));
        messageDO.setPetType(speciesLabels);
        //识别物种，无法翻译音频
        if (intentResult.getDouble("confidence")<0.7){
            messageDO.setTransStatus(0);
            List<String> petFailResult = failedMap.get(speciesLabels);
            if (petFailResult == null) {
                petFailResult = failedMap.get("common");
            }
            messageDO.setTransResult(petFailResult.get(RandomUtil.randomInt(petFailResult.size())));
            return messageDO;
        }
        //都识别成功后 也有不同的翻译结果
        JSONObject probabilities = intentResult.getJSONObject("probabilities");
        String resultKey = probabilities.entrySet().stream()
                .max(Comparator.comparingDouble(entry -> ((Number) entry.getValue()).doubleValue()))
                .map(Map.Entry::getKey)
                .orElse(null);
        //根据key解析结果
        String emo = StrUtil.isBlank(resultKey) ? "" : resultKey.split(cn.hutool.core.util.StrUtil.UNDERLINE)[1];
        List<String> emoList = successMap.get(emo);
        messageDO.setTransStatus(1);
        messageDO.setTransResult(emoList.get(RandomUtil.randomInt(emoList.size())));

        return messageDO;
    }


    public static void main(String[] args) throws Exception {
//        byte[] bytes = HttpUtil.downloadBytes("http://192.168.1.231:48080/admin-api/infra/file/29/get/c7351abf780f18600c104ec5662d843783ed8c309c01fb427046565217f51102.wav");
//
////        File file = new File("http://192.168.1.231:48080/admin-api/infra/file/29/get/c7351abf780f18600c104ec5662d843783ed8c309c01fb427046565217f51102.wav");
//        String result = HttpRequest.post("http://43.139.42.137:8000/analyze/audio").form("audio_data", bytes, "aaa").timeout(20000) //20秒超时时间
//                .execute().body();
//        System.out.println(result);
    }


}