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.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.company.domain.Company;
import com.fs.company.service.ICompanyService;
import com.fs.config.cloud.CloudHostProper;
import com.fs.course.config.CourseConfig;
import com.fs.course.domain.FsUserCourse;
import com.fs.course.domain.FsUserCourseVideo;
import com.fs.course.domain.FsUserCourseVideoRedPackage;
import com.fs.course.mapper.FsUserCourseMapper;
import com.fs.course.mapper.FsUserCourseVideoMapper;
import com.fs.course.service.IFsUserCourseVideoRedPackageService;
import com.fs.course.utils.TimeCalculator;
import com.fs.fastGpt.domain.FastGptChatReplaceWords;
import com.fs.fastGpt.mapper.FastGptChatReplaceWordsMapper;
import com.fs.qw.service.IQwUserService;
import com.fs.qw.vo.QwSopTempSetting2;
import com.fs.qw.vo.QwUserVO;
import com.fs.qw.vo.SortDayVo;
import com.fs.sop.domain.*;
import com.fs.sop.mapper.QwSopTempMapper;
import com.fs.sop.params.QwSopShareTempParam;
import com.fs.sop.service.*;
import com.fs.sop.vo.QwSopTempRedPackageVo;
import com.fs.system.domain.SysConfig;
import com.fs.system.service.ISysConfigService;
import io.netty.util.internal.StringUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * sop模板Service业务层处理
 *
 * @author fs
 * @date 2024-09-26
 */
@Service
@AllArgsConstructor
@Slf4j
public class QwSopTempServiceImpl implements IQwSopTempService {

    @Autowired
    private CloudHostProper cloudHostProper;

    private final QwSopTempMapper qwSopTempMapper;
    private final FastGptChatReplaceWordsMapper fastGptChatReplaceWordsMapper;
    private final IQwSopTempRulesService qwSopTempRulesService;
    private final IQwSopTempDayService qwSopTempDayService;
    private final IQwSopTempContentService qwSopTempContentService;
    private final IQwSopTempVoiceService qwSopTempVoiceService;
    private final RocketMQTemplate rocketMQTemplate;
    private final ISysConfigService sysConfigService;
    private final IFsUserCourseVideoRedPackageService fsUserCourseVideoRedPackageService;
    private final FsUserCourseVideoMapper fsUserCourseVideoMapper;
    private final FsUserCourseMapper fsUserCourseMapper;
    private final IQwSopService qwSopService;
    private final IQwUserService qwUserService;
    private final ICompanyService companyService;
    private final ThreadPoolTaskExecutor threadPoolTaskExecutor;

    /**
     * 查询sop模板
     *
     * @param id sop模板主键
     * @return sop模板
     */
    @Override
    public QwSopTemp selectQwSopTempById(String id) {
//        QwSopTemp qwSopTemp = qwSopTempMapper.selectQwSopTempById(id);
        QwSopTemp qwSopTemp = qwSopTempMapper.selectQwSopTempById(id);
        List<QwSopTempDay> qwSopTempDays = qwSopTempDayService.listByTempId(id);
        qwSopTemp.setList(qwSopTempDays);
//        List<QwSopTempRules> rulesList = qwSopTempRulesService.listByTempId(id);
//        if(!rulesList.isEmpty()){
//            Map<Integer, List<QwSopTempRules>> ruleDayMap = PubFun.listToMapByGroupList(rulesList, QwSopTempRules::getDayNum);
//            qwSopTemp.setRules(ruleDayMap.values().stream().map(qwSopTempRules -> {
//                Map<String, Object> map = new HashMap<>();
//                QwSopTempRules rules = qwSopTempRules.get(0);
//                map.put("name", rules.getName());
//                map.put("id", rules.getTempId());
//                map.put("dayNum", rules.getDayNum());
////                map.put("content", qwSopTempRules);
//                return map;
//            }).collect(Collectors.toList()));
//        }else{
//            qwSopTemp.setRules(new ArrayList<>());
//        }
        return qwSopTemp;
    }

    /**
     * 查询sop模板列表
     *
     * @param qwSopTemp sop模板
     * @return sop模板
     */
    @Override
    public List<QwSopTemp> selectQwSopTempList(QwSopTemp qwSopTemp) {
        return qwSopTempMapper.selectQwSopTempList(qwSopTemp);
    }

    /**
     * 新增sop模板
     *
     * @param qwSopTemp sop模板
     * @return 结果
     */
    @Override
    public int insertQwSopTemp(QwSopTemp qwSopTemp) {
        qwSopTemp.setId(UUID.randomUUID().toString());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        qwSopTemp.setCreateTime(sdf.format(new Date()));
        return qwSopTempMapper.insert(qwSopTemp);
    }

    // 提取通用替换逻辑的方法
    private void replaceContent(String contentType, String content, Consumer<String> setter, List<FastGptChatReplaceWords> words) {
        if (contentType != null && content != null && !content.isEmpty()) {
            for (FastGptChatReplaceWords word : words) {
                if (content.contains(word.getContent())) {
                    // 如果包含目标字段，则替换
                    setter.accept(content.replace(word.getContent(), word.getChangeCount()));
                }
            }
        }
    }

    /**
     * 修改sop模板
     *
     * @param qwSopTemp sop模板
     * @return 结果
     */
    @Override
    public int updateQwSopTemp(QwSopTemp qwSopTemp) {
        return qwSopTempMapper.updateQwSopTemp(qwSopTemp);
    }

    /**
     * 批量删除sop模板
     *
     * @param ids 需要删除的sop模板主键
     * @return 结果
     */
    @Override
    public int deleteQwSopTempByIds(String[] ids) {
        return qwSopTempMapper.deleteQwSopTempByIds(ids);
    }

    @Override
    public int shareQwSopTemp(QwSopShareTempParam param) {
        QwSopTemp qwSopTemp = qwSopTempMapper.selectQwSopTempById(param.getTempleId());
        Arrays.stream(param.getCompanyIds()).forEach(companyId -> {

            Company company = companyService.selectCompanyById(companyId);
            qwSopTemp.setCreateBy(company.getUserId().toString());
            qwSopTemp.setCompanyId(companyId);
            copyTemplate(qwSopTemp);
        });
        return 1;
    }

    @Override
    public int updateQwSopTempByIds(String[] ids) {
        return qwSopTempMapper.updateQwSopTempByIds(ids);
    }

    /**
     * 删除sop模板信息
     *
     * @param id sop模板主键
     * @return 结果
     */
    @Override
    public int deleteQwSopTempById(String id) {
        return qwSopTempMapper.deleteQwSopTempById(id);
    }

    @Override
    public int addNew(QwSopTemp qwSopTemp) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        qwSopTemp.setCreateTime(sdf.format(new Date()));
        qwSopTemp.setId(UUID.randomUUID().toString());
        return qwSopTempMapper.insertQwSopTemp(qwSopTemp);
    }

    @Override
    @DataSource(DataSourceType.SOP)
    public int update(QwSopTemp qwSopTemp) {
        QwSopTemp temp = qwSopTempMapper.selectById(qwSopTemp.getId());
        int i = qwSopTempMapper.updateById(qwSopTemp);
        if (!Objects.equals(temp.getGap(), qwSopTemp.getGap())) {
            // 重新排序
            reorder(qwSopTemp.getId());
        }
        return i;
    }

    @Override
    public Map<String, Object> addOrUpdateSetting(QwSopTempDay day) {
        List<QwSopTempRules> list = day.getList();
        List<QwSopTempContent> collect = list.stream().flatMap(e -> e.getSettingList().stream()).collect(Collectors.toList());
        List<QwSopTempContent> voiceList = collect.stream().filter(e -> e.getContentType() == 7).collect(Collectors.toList());
//        if(!voiceList.isEmpty()){
////            day.setVoice(1);
//        }
        qwSopTempDayService.saveOrUpdate(day);
        qwSopTempRulesService.removeByDayId(day.getId());
        qwSopTempContentService.removeByDayId(day.getId());

        list.forEach(item -> item.setDayId(day.getId()));
        processAndReplaceContent(list);
        QwSopTempRules rules = list.get(0);
        String tempId = rules.getTempId();
        // 批量插入
        qwSopTempRulesService.insertBatch(list);
        // 处理添加列表设置ID
        list.forEach(e -> e.getSettingList().forEach(item -> {
            item.setRulesId(e.getId());
            item.setDayId(e.getDayId());
            item.setTempId(tempId);
        }));
        // 批量插入内容

        qwSopTempContentService.insertBatch(collect);
        reorder(day.getTempId());
        Map<String, Object> map = new HashMap<>();
        map.put("id", day.getId());
        if (!voiceList.isEmpty()) {
            for (QwSopTempContent qwSopTempContent : voiceList) {
                String content = qwSopTempContent.getContent();
                JSONObject jsonObject = JSONObject.parseObject(content);
                String text = jsonObject.getString("value");
                List<QwSop> qwSopList = qwSopService.selectQwSopByTempId(tempId);//通过tempId查询出所有sop
                if (qwSopList != null && !qwSopList.isEmpty()) {
                    for (QwSop qwSop : qwSopList) {
                        if (qwSop != null && qwSop.getQwUserIds() != null) {
                            //查询出所有的tempContent来筛选文字
                            List<QwSopTempContent> qwSopTempContentList = qwSopTempContentService.selectQwSopTempContentByTempId(tempId);
                            if (qwSopTempContentList != null && !qwSopTempContentList.isEmpty()) {
                                for (QwSopTempContent qwSopTemp : qwSopTempContentList) {
                                    if (qwSopTemp != null && qwSopTemp.getContentType() == 7) {
                                        String[] split = qwSop.getQwUserIds().split(",");
                                        Long[] qwUserIds = (Long[]) ConvertUtils.convert(split, Long.class);
                                        List<QwUserVO> qwUserVOS = qwUserService.selectQwUserVOByIds(qwUserIds);
                                        if (qwUserVOS != null) {
                                            for (QwUserVO qwUserVO : qwUserVOS) {
                                                Long companyUserId = qwUserVO.getCompanyUserId();
                                                QwSopTempVoice qwSopTempVoice = qwSopTempVoiceService.selectQwSopTempVoiceByCompanyUserIdAndVoiceTxt(companyUserId, text);
                                                if (qwSopTempVoice == null) {
                                                    if (companyUserId != null && text != null) {
                                                        QwSopTempVoice sopTempVoice = new QwSopTempVoice();
                                                        sopTempVoice.setCompanyUserId(companyUserId);
                                                        sopTempVoice.setVoiceTxt(text);
                                                        sopTempVoice.setTempId(tempId);
                                                        sopTempVoice.setRecordType(0);
                                                        qwSopTempVoiceService.insertQwSopTempVoice(sopTempVoice);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
//        if(!voiceList.isEmpty()){
//            rocketMQTemplate.syncSend("voice-generation", JSON.toJSONString(VoiceVo.builder().type(0).id(day.getId().toString()).build()));
//        }
        return map;
    }

    private void processAndReplaceContent(List<QwSopTempRules> tempSettings) {
        List<FastGptChatReplaceWords> words = fastGptChatReplaceWordsMapper.selectAllFastGptChatReplaceWords();
        //循环天
        tempSettings.forEach(settingList -> {
            //循环单日
            settingList.getSettingList().forEach(item -> {
                JSONObject obj = JSON.parseObject(item.getContent());
                List<String> list = Arrays.asList("linkTitle", "linkDescribe", "desc", "nickname", "value");
                list.stream().filter(obj::containsKey).forEach(key -> {
                    replaceContent(item.getContentType().toString(), obj.getString(key), val -> obj.put(key, val), words);
                });
                item.setContent(obj.toJSONString());
            });
        });
    }

    @Override
    public void delRules(Long id) {
        if (id == null) return;
        QwSopTempDay day = qwSopTempDayService.info(id);
        if (day == null) return;
        qwSopTempDayService.removeById(day.getId());
        qwSopTempContentService.removeByDayId(day.getId());
        reorder(day.getTempId());
    }

    @Override
    public QwSopTempDay selectRulesInfo(Long id) {
        QwSopTempDay day = qwSopTempDayService.info(id);
        List<QwSopTempRules> rulesList = qwSopTempRulesService.listByDayId(id);
        if (!rulesList.isEmpty()) {
            List<QwSopTempContent> contentList = qwSopTempContentService.listByRulesIds(PubFun.listToNewList(rulesList, QwSopTempRules::getId));
            Map<Long, List<QwSopTempContent>> contentMap = PubFun.listToMapByGroupList(contentList, QwSopTempContent::getRulesId);
            rulesList.forEach(e -> {
                List<QwSopTempContent> contents = contentMap.get(e.getId());
                if (CollectionUtils.isNotEmpty(contents)) {
                    e.setSetting(contents.stream().map(c -> JSON.parseObject(c.getContent())).collect(Collectors.toList()));
                }
            });
        }
        day.setList(rulesList);
        return day;
    }

    @Override
    public List<QwSopTemp> selectQwSopTempListNew(QwSopTemp qwSopTemp) {
        return qwSopTempMapper.selectQwSopTempListNew(qwSopTemp);
    }

    @Override
    public void copyTemplate(QwSopTemp qwSopTemp) {
        String oldId = qwSopTemp.getId();
        String newId = UUID.randomUUID().toString();
        qwSopTemp.setId(newId);
        qwSopTempMapper.insertQwSopTemp(qwSopTemp);
        List<QwSopTempDay> dayList = qwSopTempRulesService.listByTempIdAll(oldId);
        if (dayList.isEmpty()) return;
//        List<QwSopTempRules> rulesList = qwSopTempRulesService.listByTempId(oldId);
        dayList.forEach(day -> {
            day.setTempId(newId);
            if (day.getList() != null && !day.getList().isEmpty()) {
                day.getList().forEach(e -> {
                    e.setTempId(newId);
                    if (e.getSettingList() != null && !e.getSettingList().isEmpty()) {
                        e.getSettingList().forEach(item -> {
                            item.setTempId(newId);
                        });
                    }
                });
            }
        });
        qwSopTempDayService.insertBatch(dayList);
        dayList.forEach(e -> e.getList().forEach(item -> item.setDayId(e.getId())));
        List<QwSopTempRules> collect = dayList.stream().flatMap(e -> e.getList().stream()).collect(Collectors.toList());
        qwSopTempRulesService.insertBatch(collect);
        collect.forEach(e -> e.getSettingList().forEach(item -> {
            item.setRulesId(e.getId());
            item.setDayId(e.getDayId());
        }));
        qwSopTempContentService.insertBatch(collect.stream().flatMap(e -> e.getSettingList().stream()).collect(Collectors.toList()));
    }

    @Override
    @DataSource(DataSourceType.SOP)
    public List<QwSopTemp> listTemp() {
        return qwSopTempMapper.selectList(new QueryWrapper<>());
    }

    @Override
    @DataSource(DataSourceType.SOP)
    public void sortDay(List<SortDayVo> list) {
        Collection<QwSopTempDay> days = qwSopTempDayService.listByIds(PubFun.listToNewList(list, SortDayVo::getId));
        Map<Long, Integer> dayMap = list.stream().collect(Collectors.toMap(SortDayVo::getId, SortDayVo::getDayNum));
        if (days.stream().anyMatch(e -> !dayMap.containsKey(e.getId()))) {
            throw new BaseException("数据错误！");
        }
        days.forEach(day -> day.setDayNum(dayMap.get(day.getId())));
        qwSopTempDayService.updateBatchById(days);
    }

    @Override
    public List<QwSopTempDay> dayList(String id) {
        return qwSopTempDayService.listByTempId(id);
    }


    @DataSource(DataSourceType.SOP)
    private void reorder(String tempId) {
        QwSopTemp qwSopTemp = qwSopTempMapper.selectQwSopTempById(tempId);
        List<QwSopTempDay> days = qwSopTempDayService.listByTempId(tempId);
        if (days.isEmpty()) return;
        for (int i = 0; i < days.size(); i++) {
            QwSopTempDay entity = days.get(i);
            entity.setSorts(i);
            entity.setDayNum((entity.getSorts() * qwSopTemp.getGap()) + 1);
        }
        qwSopTempDayService.addOrUpdateBatch(days);
    }

    @Override
    public void createSopTempRules(QwSopTemp temp) {
        if (temp.getTime() == null) {
            return;
        }

        FsUserCourse fsUserCourse = fsUserCourseMapper.selectFsUserCourseByCourseId(temp.getCourseId());
        temp.setProject(fsUserCourse.getProject());
        qwSopTempMapper.updateQwSopTemp(temp);
        List<FsUserCourseVideo> videoList = fsUserCourseVideoMapper.selectVideoByCourseId(fsUserCourse.getCourseId());
        AtomicInteger i = new AtomicInteger(1);
        Integer gap = temp.getGap();
        List<QwSopTempDay> collect = videoList.stream().map(e -> {
            QwSopTempDay day = new QwSopTempDay();
            day.setTempId(temp.getId());
            day.setDayNum(i.getAndIncrement() * gap);
            day.setName("第" + day.getDayNum() + "天");
            day.setSorts(day.getDayNum());
            day.setList(new ArrayList<>());
            List<String> timeList = new ArrayList<>();
            if (temp.getTimeList() != null) {
                timeList = JSON.parseArray(JSON.toJSONString(temp.getTimeList()), String.class);
            }
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
            if (temp.getTime() != null) {
                timeList.add(0, temp.getTime().format(formatter));
            }
            AtomicInteger sorts = new AtomicInteger(0);
            List<QwSopTempRules> rulesList = timeList.stream().map(time -> {
                QwSopTempRules rules = new QwSopTempRules();
                rules.setTempId(temp.getId());
                rules.setName(day.getName());
                if (temp.getOpenOfficial().equals("1")) {
                    rules.setIsOfficial(sorts.get() == 0 ? "1" : "0");
                } else {
                    rules.setIsOfficial("0");
                }

                if (day.getDayNum() == 1 && sorts.get() == 0 && temp.getOpenOfficial().equals("1")) {
                    rules.setTime("01:05");
                } else {
                    rules.setTime(time);
                }

                rules.setContentType(2);
                rules.setType(2);
                rules.setCourseType(0);
                rules.setCourseId(e.getCourseId());
                rules.setVideoId(e.getVideoId());
                // 设置消息类型

                QwSopTempContent content = new QwSopTempContent();
                content.setTempId(temp.getId());
                content.setContentType(3);
                QwSopTempSetting2.Content.Setting setting = new QwSopTempSetting2.Content.Setting();
                setting.setLinkTitle(e.getTitle());
                setting.setMiniprogramTitle(e.getTitle());

                //用课节图片做封面
                if ("今正科技".equals(cloudHostProper.getCompanyName())) {
                    setting.setMiniprogramPicUrl(!StringUtil.isNullOrEmpty(e.getThumbnail()) ? e.getThumbnail() : fsUserCourse.getImgUrl());
                    setting.setLinkImageUrl(!StringUtil.isNullOrEmpty(e.getThumbnail()) ? e.getThumbnail() : fsUserCourse.getImgUrl());
                } else {
                    setting.setMiniprogramPicUrl(fsUserCourse.getImgUrl());
                    setting.setLinkImageUrl(fsUserCourse.getImgUrl());

                }

                setting.setIsBindUrl(1);
                setting.setLinkDescribe(e.getTitle());
                setting.setContentType("4");
                content.setContent(JSON.toJSONString(setting));
                content.setIsBindUrl(1);
                List<QwSopTempContent> qwSopTempContents = new ArrayList<>();
                qwSopTempContents.add(content);
                if (sorts.get() == 0 && !StringUtil.isNullOrEmpty(temp.getModeContent())) {
                    QwSopTempContent content2 = new QwSopTempContent();
                    content2.setTempId(temp.getId());
                    content2.setContentType(3);
                    QwSopTempSetting2.Content.Setting setting2 = new QwSopTempSetting2.Content.Setting();
                    setting2.setValue(temp.getModeContent());
                    setting2.setContentType("1");
                    content2.setContent(JSON.toJSONString(setting2));
                    qwSopTempContents.add(content2);
                }
                if (sorts.get() > 0) {

                    QwSopTempContent content3 = new QwSopTempContent();
                    content3.setTempId(temp.getId());
                    content3.setContentType(3);
                    QwSopTempSetting2.Content.Setting setting3 = new QwSopTempSetting2.Content.Setting();
                    setting3.setValue(temp.getTimeDesc().get(sorts.get() - 1));
                    setting3.setContentType("1");
                    content3.setContent(JSON.toJSONString(setting3));
                    qwSopTempContents.add(content3);

                }

                rules.setSorts(sorts.getAndIncrement());
                if (rules.getSorts() == 0) {
                    rules.setCourseType(0);
                } else if (rules.getSorts() == 1) {
                    rules.setCourseType(1);
                } else {
                    rules.setCourseType(4);
                }
                rules.setList(qwSopTempContents);
                return rules;
            }).collect(Collectors.toList());
            day.getList().addAll(rulesList);
            return day;
        }).collect(Collectors.toList());
        qwSopTempDayService.addOrUpdateBatch(collect);
        List<QwSopTempRules> ruleList = collect.stream().flatMap(e -> e.getList().stream().peek(r -> r.setDayId(e.getId()))).collect(Collectors.toList());
        qwSopTempRulesService.saveList(ruleList);
        List<QwSopTempContent> contentList = ruleList.stream().flatMap(e -> e.getList().stream().peek(r -> {
            r.setDayId(e.getDayId());
            r.setRulesId(e.getId());
        })).collect(Collectors.toList());
        qwSopTempContentService.saveList(contentList);
        SysConfig sysConfig = sysConfigService.selectConfigByConfigKey("course.config");
        CourseConfig courseConfig = JSON.parseObject(sysConfig.getConfigValue(), CourseConfig.class);
        List<Long> videoIdList = PubFun.listToNewList(ruleList, QwSopTempRules::getVideoId);
        Map<Long, Optional<BigDecimal>> redMap;
        if (!videoIdList.isEmpty()) {
            List<FsUserCourseVideoRedPackage> redPackageList = fsUserCourseVideoRedPackageService.listByCompanyIdAndVideoIds(temp.getCompanyId(), videoIdList);
            redMap = redPackageList.stream().collect(Collectors.groupingBy(FsUserCourseVideoRedPackage::getVideoId, Collectors.mapping(FsUserCourseVideoRedPackage::getRedPacketMoney, Collectors.reducing((e1, e2) -> e1))));
        } else {
            redMap = new HashMap<>();
        }

        List<FsUserCourseVideoRedPackage> redPackage = ruleList.stream().filter(e -> e.getVideoId() != null && e.getSorts() == 0).map(e -> {
            FsUserCourseVideoRedPackage red = new FsUserCourseVideoRedPackage();
            red.setCompanyId(temp.getCompanyId());
            red.setVideoId(e.getVideoId());
            red.setRedPacketMoney(redMap.getOrDefault(e.getVideoId(), Optional.ofNullable(courseConfig.getRedPackageMoney())).orElse(BigDecimal.ZERO));
            red.setRuleId(e.getId());
            red.setDataType(3);
            return red;
        }).collect(Collectors.toList());
        fsUserCourseVideoRedPackageService.batchSaveFsUserCourseVideoRedPackage(redPackage);
    }

    @Override
    public List<QwSopTempRedPackageVo> redList(String id) {
        List<QwSopTempDay> dayList = qwSopTempRulesService.listByTempIdAll(id);
        if (CollectionUtils.isEmpty(dayList)) {
            return Collections.emptyList();
        }
        List<QwSopTempRules> rules = dayList.stream()
                .filter(e -> e != null && e.getList() != null)
                .flatMap(e -> e.getList().stream())
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        if (rules.isEmpty()) {
            return Collections.emptyList();
        }
        List<FsUserCourseVideoRedPackage> redPackageList = fsUserCourseVideoRedPackageService.listByRuleIds(PubFun.listToNewList(rules, QwSopTempRules::getId));
        Map<Long, FsUserCourseVideoRedPackage> redMap = PubFun.listToMapByGroupObject(redPackageList, FsUserCourseVideoRedPackage::getVideoId);
        List<FsUserCourseVideo> videoList = fsUserCourseVideoMapper.selectVideoByCourseId(rules.get(0).getCourseId());
        Map<Long, FsUserCourseVideo> videoMap = PubFun.listToMapByGroupObject(videoList, FsUserCourseVideo::getVideoId);
        return rules.stream()
                .filter(e -> e.getVideoId() != null && redMap.containsKey(e.getVideoId()) && videoMap.containsKey(e.getVideoId())).map(e -> {
                    FsUserCourseVideoRedPackage red = redMap.get(e.getVideoId());
                    FsUserCourseVideo video = videoMap.get(e.getVideoId());
                    QwSopTempRedPackageVo vo = new QwSopTempRedPackageVo();
                    vo.setId(red.getId());
                    vo.setRuleId(e.getId());
                    vo.setName(e.getName());
                    vo.setVideoId(e.getVideoId());
                    vo.setVideoName(video.getTitle());
                    vo.setCompanyId(red.getCompanyId());
                    vo.setRedPacketMoney(red.getRedPacketMoney());
                    vo.setDataType(red.getDataType());
                    return vo;
                }).collect(Collectors.toList());
    }

    @Override
    public void updateRedPackage(List<QwSopTempRedPackageVo> list) {
        fsUserCourseVideoRedPackageService.deleteFsUserCourseVideoRedPackageByIds(list.stream().map(QwSopTempRedPackageVo::getId).toArray(Long[]::new));
        List<FsUserCourseVideoRedPackage> redPackage = list.stream().map(e -> {
            FsUserCourseVideoRedPackage red = new FsUserCourseVideoRedPackage();
            red.setCompanyId(e.getCompanyId());
            red.setVideoId(e.getVideoId());
            red.setRedPacketMoney(e.getRedPacketMoney());
            red.setRuleId(e.getRuleId());
            red.setDataType(3);
            return red;
        }).collect(Collectors.toList());
        fsUserCourseVideoRedPackageService.batchSaveFsUserCourseVideoRedPackage(redPackage);
    }

    @Override
    public List<String> getSelectableRange() {
        SysConfig sysConfig = sysConfigService.selectConfigByConfigKey("course.config");
        CourseConfig courseConfig = JSON.parseObject(sysConfig.getConfigValue(), CourseConfig.class);
        List<CourseConfig.DisabledTimeVo> disabledTimeList = courseConfig.getDisabledTimeList();
        if (disabledTimeList == null) {
            return Collections.emptyList();
        }
        return TimeCalculator.calculateAvailableTimes(disabledTimeList);
    }


    @Override
    public void syncTemplate(Long courseId) {
        // 根据courseId查询所有相关的sop模板规则
        List<QwSopTempRules> rulesList = qwSopTempRulesService.listByCourseId(courseId);
        if (CollectionUtils.isEmpty(rulesList)) {
            return;
        }

        // 获取这些规则关联的模板ID集合
        Set<String> tempIds = rulesList.stream()
                .map(QwSopTempRules::getTempId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());

        // 查询相关联的sop模板
        if (CollectionUtils.isEmpty(tempIds)) {
            return;
        }
        // 只弄课程模板的
        List<QwSopTemp> tempList = qwSopTempMapper.selectListByIds(tempIds);
        tempList = tempList.stream().filter(f -> Objects.equals(f.getStatus(), "1")).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(tempList)) {
            return;
        }

        // 获取这些规则关联的模板ID集合
        Set<String> sopTempIds = tempList.stream()
                .map(QwSopTemp::getId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());

        List<QwSopTempContent> contentList = qwSopTempContentService.listByTempIds(sopTempIds);

        qwSopTempDayService.removeByTempIds(tempIds);
        qwSopTempRulesService.removeByTempIds(tempIds);
        qwSopTempContentService.removeByTempIds(tempIds);
        // 对每个模板执行同步操作
        for (QwSopTemp temp : tempList) {
            // 构造timeList timeDesc time
            rulesList.stream().filter(e -> e.getTempId().equals(temp.getId())).findFirst()
                    .ifPresent(first -> temp.setTime(LocalTime.parse(first.getTime() + ":00")));

            temp.setTimeList(rulesList.stream()
                    .filter(e -> e.getTempId().equals(temp.getId()) && Objects.equals(e.getIsOfficial(), "0")
                            && Objects.equals(e.getName(), "第1天")).map(QwSopTempRules::getTime)
                    .collect(Collectors.toList()));
            // 过滤并找到 dayId 最小的元素
            Optional<QwSopTempContent> minDayEntity = contentList.stream()
                    // 1. 过滤条件：tempId匹配 + isBindUrl为null
                    .filter(e -> e.getTempId().equals(temp.getId())
                            && Objects.isNull(e.getIsBindUrl()))
                    // 2. 按 dayId 升序排序，取第一个（最小）
                    .min(Comparator.comparingLong(QwSopTempContent::getDayId)); // 若dayId是Long，用comparingLong

            if (minDayEntity.isPresent()) {
                QwSopTempContent qwSopTempContent = minDayEntity.get();
                temp.setTimeDesc(contentList.stream().filter(e -> e.getTempId().equals(temp.getId())
                                && Objects.isNull(e.getIsBindUrl())
                                && Objects.equals(qwSopTempContent.getDayId(), e.getDayId())
                        )
                        .map(m -> JSONObject.parseObject(m.getContent()).getString("value")).collect(Collectors.toList()));
            }

            // 插入课程id
            temp.setCourseId(courseId);
            temp.setOpenOfficial("1");
            // 重新生成该模板的规则和内容
            threadPoolTaskExecutor.execute(() -> createSopTempRules(temp));
        }
    }

}
