package com.fs.sop.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fs.common.annotation.DataSource;
import com.fs.common.enums.DataSourceType;
import com.fs.common.exception.base.BaseException;
import com.fs.common.utils.PubFun;
import com.fs.common.utils.StringUtils;
import com.fs.company.service.ICompanyUserService;
import com.fs.company.vo.CompanyQwUserByIdsVo;
import com.fs.fastgptApi.util.AudioUtils;
import com.fs.fastgptApi.vo.AudioVO;
import com.fs.sop.domain.QwSop;
import com.fs.sop.domain.QwSopTempContent;
import com.fs.sop.domain.QwSopTempDay;
import com.fs.sop.domain.QwSopTempVoice;
import com.fs.sop.mapper.QwSopMapper;
import com.fs.sop.mapper.QwSopTempDayMapper;
import com.fs.sop.mapper.QwSopTempVoiceMapper;
import com.fs.sop.service.IQwSopTempContentService;
import com.fs.sop.service.IQwSopTempVoiceService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 模板对应的销售语音文件Service业务层处理
 *
 * @author fs
 * @date 2025-02-13
 */
@Slf4j
@Service
@AllArgsConstructor
public class QwSopTempVoiceServiceImpl extends ServiceImpl<QwSopTempVoiceMapper, QwSopTempVoice> implements IQwSopTempVoiceService {

    private final IQwSopTempContentService qwSopTempContentService;
    private final QwSopMapper qwSopMapper;
    private final QwSopTempDayMapper qwSopTempDayMapper;
    private final ICompanyUserService companyUserService;

    /**
     * 查询模板对应的销售语音文件
     *
     * @param id 模板对应的销售语音文件主键
     * @return 模板对应的销售语音文件
     */
    @Override
    public QwSopTempVoice selectQwSopTempVoiceById(Long id) {
        return baseMapper.selectQwSopTempVoiceById(id);
    }

    /**
     * 查询模板对应的销售语音文件列表
     *
     * @param qwSopTempVoice 模板对应的销售语音文件
     * @return 模板对应的销售语音文件
     */
    @Override
    public List<QwSopTempVoice> selectQwSopTempVoiceList(QwSopTempVoice qwSopTempVoice) {
        return baseMapper.selectQwSopTempVoiceList(qwSopTempVoice);
    }

    /**
     * 新增模板对应的销售语音文件
     *
     * @param qwSopTempVoice 模板对应的销售语音文件
     * @return 结果
     */
    @Override
    public int insertQwSopTempVoice(QwSopTempVoice qwSopTempVoice) {
        return baseMapper.insertQwSopTempVoice(qwSopTempVoice);
    }

    /**
     * 修改模板对应的销售语音文件
     *
     * @param qwSopTempVoice 模板对应的销售语音文件
     * @return 结果
     */
    @Override
    public int updateQwSopTempVoice(QwSopTempVoice qwSopTempVoice) {
        return baseMapper.updateQwSopTempVoice(qwSopTempVoice);
    }

    /**
     * 批量删除模板对应的销售语音文件
     *
     * @param ids 需要删除的模板对应的销售语音文件主键
     * @return 结果
     */
    @Override
    public int deleteQwSopTempVoiceByIds(Long[] ids) {
        return baseMapper.deleteQwSopTempVoiceByIds(ids);
    }

    /**
     * 删除模板对应的销售语音文件信息
     *
     * @param id 模板对应的销售语音文件主键
     * @return 结果
     */
    @Override
    public int deleteQwSopTempVoiceById(Long id) {
        return baseMapper.deleteQwSopTempVoiceById(id);
    }

    /**
     * 同步语音
     *
     * @param sopId          sopID
     * @param companyUserIds 销售ID和销售公司ID
     *                       数据结构实例：[[销售ID, 销售公司ID],[销售ID, 销售公司ID],[销售ID, 销售公司ID]]
     */
    @Override
    public void synchronous(String sopId, List<List<Long>> companyUserIds) {
        QwSop qwSop = qwSopMapper.selectQwSopById(sopId);
        if (qwSop == null) {
            throw new BaseException("未找到对应的SOP");
        }
        // 查询模板内容列表
        List<QwSopTempContent> contentList = qwSopTempContentService.listVoice(qwSop.getTempId());
        // 查询已存在的语音记录
        List<Long> salesIds = PubFun.listToNewList(companyUserIds, id -> id.get(0)); // 提取销售ID

        List<QwSopTempVoice> voiceList = baseMapper.selectAllByUserIds(salesIds);
        List<QwSopTempVoice> collect = genVoice(salesIds, voiceList, PubFun.listToNewList(contentList, e -> JSON.parseObject(e.getContent()).getString("value")));
        collect.forEach(e -> {
            e.setTempId(qwSop.getTempId());
        });
        if (!collect.isEmpty()) {
            baseMapper.insertBatch(collect); // 使用自定义的批量插入方法
        }
//        qwSop.setVoice(1);
        qwSopMapper.updateQwSop(qwSop);
    }

    @Override
    public List<QwSopTempVoice> getVoice(Long companyUserId, Long companyId, String tempId, Long rulesId) {
        return baseMapper.getVoice(companyUserId, companyId, tempId, rulesId);
    }

    @Override
    public List<QwSopTempVoice> getVoiceByText(Long companyUserId, List<String> textList) {
        return baseMapper.getVoiceByText(companyUserId, textList);
    }

    @Override
    public void synchronousTemp(List<QwSopTempContent> contents, QwSopTempDay day) {
        Long dayId = day.getId();
        String tempId = day.getTempId();
        if (contents == null) {
            log.info("不需要生成语音");
            qwSopTempDayMapper.updateVoice(dayId);
            return;
        }
        contents = contents.stream().filter(e -> e.getContentType() == 7).collect(Collectors.toList());
        if (contents.isEmpty()) {
            log.info("不需要生成语音");
            qwSopTempDayMapper.updateVoice(dayId);
            return;
        }
//        baseMapper.remove(tempId, dayId);
        List<QwSop> sopList = qwSopMapper.selectByTemplateId(tempId);
        if (sopList.isEmpty()) {
            log.info("sop任务为空跳过生成");
            qwSopTempDayMapper.updateVoice(dayId);
            return;
        }
        List<Long> qwUserIdList = sopList.stream().flatMap(e -> Arrays.stream(e.getQwUserIds().split(","))).distinct().filter(StringUtils::isNotEmpty).map(Long::parseLong).collect(Collectors.toList());
        List<CompanyQwUserByIdsVo> companyUserList = companyUserService.selectCompanyQwUserByIds(qwUserIdList);
        if (companyUserList.isEmpty()) {
            log.info("sop任务里面的销售为空跳过生成");
            qwSopTempDayMapper.updateVoice(dayId);
            return;
        }
        List<String> valueList = PubFun.listToNewList(contents, e -> JSON.parseObject(e.getContent()).getString("value"));
        List<Long> userIdList = PubFun.listToNewList(companyUserList, CompanyQwUserByIdsVo::getUserId);
        List<QwSopTempVoice> voiceList = baseMapper.selectAllByUserIds(userIdList);

        List<QwSopTempVoice> collect = genVoice(userIdList, voiceList, valueList);
        collect.forEach(e -> {
            e.setTempId(tempId);
        });
        if (!collect.isEmpty()) {
            baseMapper.insertBatch(collect); // 使用自定义的批量插入方法
        }
//        List<QwSopTempVoice> collect = companyUserList.parallelStream().flatMap(e -> contents.stream().map(c -> createVoice(c, e.getUserId(), e.getCompanyId()))).filter(Objects::nonNull).collect(Collectors.toList());
        qwSopTempDayMapper.updateVoice(dayId);
        log.info("模板语音生成完成：tempId{}，dayId:{}", tempId, dayId);
    }

    /**
     * 根据模板和销售生成语音
     * @param companyUserList 销售列表
     * @param voiceList       已经纯在的语音列表
     * @param valueList       要生成的语音文本列表
     * @return
     */
    private List<QwSopTempVoice> genVoice(List<Long> companyUserList, List<QwSopTempVoice> voiceList, List<String> valueList) {
        log.info("生成的文本：{}", valueList);
        log.info("生成的销售：{}", companyUserList);
        Map<Long, List<QwSopTempVoice>> voiceMap = PubFun.listToMapByGroupList(voiceList, QwSopTempVoice::getCompanyUserId);
        long startTime = System.currentTimeMillis();
        List<QwSopTempVoice> collect = companyUserList.stream().flatMap(e -> {
            List<QwSopTempVoice> userVoiceList = voiceMap.get(e);
            if(userVoiceList == null || userVoiceList.isEmpty()){
                return valueList.stream().map(value -> createVoiceByText(value, e));
            }
            List<String> values = PubFun.listToNewList(userVoiceList, QwSopTempVoice::getVoiceTxt);
            return valueList.stream().filter(value -> !values.contains(value)).map(value -> createVoiceByText(value, e));
        }).filter(Objects::nonNull).collect(Collectors.toList());
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;
        log.info("模板同步语音生成时长: {} 毫秒", duration);
        return collect;
    }

    @Override
    @DataSource(DataSourceType.SOP)
    public List<QwSopTempVoice> listByTempIdAndCompanyId(String tempId, List<Long> longs) {
        return list(new QueryWrapper<QwSopTempVoice>().eq("temp_id", tempId).in("company_user_id", longs));
    }

    private QwSopTempVoice createVoiceByText(String value, Long salesId) {
        if (StringUtils.isEmpty(value)) {
            log.error("语音内容为空，contentId: {}", value);
            return null;
        }
        AudioVO audioVO = AudioUtils.transferAudioSilkFromTextNew(value, salesId, false);
        if (audioVO == null || StringUtils.isEmpty(audioVO.getUrl())) {
            log.error("语音生成失败，salesId: {},,,text：{}", salesId, value);
            return null;
        }
        QwSopTempVoice voice = new QwSopTempVoice();
        voice.setCompanyUserId(salesId);
//        voice.setCompanyId(companyId);
        voice.setVoiceTxt(value);
        voice.setVoiceUrl(audioVO.getUrl());
        voice.setDuration(audioVO.getDuration());
        log.info("语音生成成功，salesId: {}", salesId);
        return voice;
    }
    private QwSopTempVoice createVoice(QwSopTempContent content, Long salesId, Long companyId) {
        JSONObject jsonObject = JSON.parseObject(content.getContent());
        String value = jsonObject.getString("value");
        if (StringUtils.isEmpty(value)) {
            log.error("语音内容为空，contentId: {}", content.getId());
            return null;
        }
        AudioVO audioVO = AudioUtils.transferAudioSilkFromTextNew(value, salesId, false);
        if (audioVO == null || StringUtils.isEmpty(audioVO.getUrl())) {
            log.error("语音生成失败，salesId: {},,,text：{}", salesId, value);
            return null;
        }
        QwSopTempVoice voice = new QwSopTempVoice();
        voice.setTempId(content.getTempId());
        voice.setCompanyUserId(salesId);
        voice.setCompanyId(companyId);
        voice.setContentId(content.getId());
        voice.setRuleId(content.getRulesId());
        voice.setDayId(content.getDayId());
        voice.setVoiceTxt(value);
        voice.setVoiceUrl(audioVO.getUrl());
        voice.setDuration(audioVO.getDuration());
        log.info("语音生成成功，salesId: {}", salesId);
        return voice;
    }

}
