package com.fs.course.service.impl;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.fs.course.domain.FsUserCoursePeriod;
import com.fs.course.domain.FsUserCoursePeriodDays;
import com.fs.course.mapper.FsUserCoursePeriodDaysMapper;
import com.fs.course.mapper.FsUserCoursePeriodMapper;
import com.fs.course.param.FsBatchPeriodRedPackageParam;
import com.google.common.collect.Lists;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.fs.course.mapper.FsUserCourseVideoRedPackageMapper;
import com.fs.course.domain.FsUserCourseVideoRedPackage;
import com.fs.course.service.IFsUserCourseVideoRedPackageService;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional;

/**
 * 课程公司红包Service业务层处理
 *
 * @author fs
 * @date 2024-10-25
 */
@Service
public class FsUserCourseVideoRedPackageServiceImpl implements IFsUserCourseVideoRedPackageService
{
    @Autowired
    private FsUserCourseVideoRedPackageMapper fsUserCourseVideoRedPackageMapper;

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    @Autowired
    private FsUserCoursePeriodDaysMapper userCoursePeriodDaysMapper;

    @Autowired
    private FsUserCoursePeriodMapper userCoursePeriodMapper;

    /**
     * 查询课程公司红包
     *
     * @param id 课程公司红包主键
     * @return 课程公司红包
     */
    @Override
    public FsUserCourseVideoRedPackage selectFsUserCourseVideoRedPackageById(Long id)
    {
        return fsUserCourseVideoRedPackageMapper.selectFsUserCourseVideoRedPackageById(id);
    }

    /**
     * 查询课程公司红包列表
     *
     * @param fsUserCourseVideoRedPackage 课程公司红包
     * @return 课程公司红包
     */
    @Override
    public List<FsUserCourseVideoRedPackage> selectFsUserCourseVideoRedPackageList(FsUserCourseVideoRedPackage fsUserCourseVideoRedPackage)
    {
        return fsUserCourseVideoRedPackageMapper.selectFsUserCourseVideoRedPackageList(fsUserCourseVideoRedPackage);
    }

    /**
     * 新增课程公司红包
     *
     * @param fsUserCourseVideoRedPackage 课程公司红包
     * @return 结果
     */
    @Override
    public int insertFsUserCourseVideoRedPackage(FsUserCourseVideoRedPackage fsUserCourseVideoRedPackage)
    {
        return fsUserCourseVideoRedPackageMapper.insertFsUserCourseVideoRedPackage(fsUserCourseVideoRedPackage);
    }

    /**
     * 修改课程公司红包
     *
     * @param fsUserCourseVideoRedPackage 课程公司红包
     * @return 结果
     */
    @Override
    public int updateFsUserCourseVideoRedPackage(FsUserCourseVideoRedPackage fsUserCourseVideoRedPackage)
    {
        return fsUserCourseVideoRedPackageMapper.updateFsUserCourseVideoRedPackage(fsUserCourseVideoRedPackage);
    }

    /**
     * 批量删除课程公司红包
     *
     * @param ids 需要删除的课程公司红包主键
     * @return 结果
     */
    @Override
    public int deleteFsUserCourseVideoRedPackageByIds(Long[] ids)
    {
        return fsUserCourseVideoRedPackageMapper.deleteFsUserCourseVideoRedPackageByIds(ids);
    }

    /**
     * 删除课程公司红包信息
     *
     * @param id 课程公司红包主键
     * @return 结果
     */
    @Override
    public int deleteFsUserCourseVideoRedPackageById(Long id)
    {
        return fsUserCourseVideoRedPackageMapper.deleteFsUserCourseVideoRedPackageById(id);
    }

    @Override
    public int batchSaveFsUserCourseVideoRedPackage(List<FsUserCourseVideoRedPackage> fsUserCourseVideoRedPackageList) {
        return fsUserCourseVideoRedPackageMapper.batchSaveFsUserCourseVideoRedPackage(fsUserCourseVideoRedPackageList);
    }

    @Override
    public int batchDeleteParams(List<FsUserCourseVideoRedPackage> videoRedPackageList) {
        return fsUserCourseVideoRedPackageMapper.batchDeleteParams(videoRedPackageList);
    }

    @Override
    @Transactional
    public void batchSaveCompanyRedPackage(List<FsUserCourseVideoRedPackage> fsUserCourseVideoRedPackageList) {
        if (fsUserCourseVideoRedPackageList == null || fsUserCourseVideoRedPackageList.isEmpty()) {
            return;
        }

        List<FsUserCourseVideoRedPackage> existingData = fsUserCourseVideoRedPackageMapper
                .selectByParamsList(fsUserCourseVideoRedPackageList);

        // 创建匹配键集合，用于辅助快速查找
        Set<String> existingKeys = new HashSet<>();
        for (FsUserCourseVideoRedPackage data : existingData) {
            String key = generateKey(data.getPeriodId(), data.getVideoId(), data.getCompanyId());
            existingKeys.add(key);
        }

        //需要修改和新增的数据
        List<FsUserCourseVideoRedPackage> updateList = new ArrayList<>();
        List<FsUserCourseVideoRedPackage> insertList = new ArrayList<>();

        for (FsUserCourseVideoRedPackage redPackage : fsUserCourseVideoRedPackageList) {
            String key = generateKey(redPackage.getPeriodId(), redPackage.getVideoId(), redPackage.getCompanyId());

            if (existingKeys.contains(key)) {
                // 存在则加入更新列表
                updateList.add(redPackage);
            } else {
                // 不存在则加入新增列表
                insertList.add(redPackage);
            }
        }

        if (!updateList.isEmpty()) {
//            result += fsUserCourseVideoRedPackageMapper.batchUpdateFsUserCourseVideoRedPackage(updateList);
            this.batchUpdateRedPackage(updateList);
        }
        if (!insertList.isEmpty()) {
            fsUserCourseVideoRedPackageMapper.batchSaveFsUserCourseVideoRedPackage(insertList);
        }
    }

    private String generateKey(Long periodId, Long videoId, Long companyId) {
        return periodId + "_" + videoId + "_" + companyId;
    }

    @Override
    public List<FsUserCourseVideoRedPackage> listByCompanyIdAndVideoIds(Long companyId, List<Long> videoIdList) {
        return fsUserCourseVideoRedPackageMapper.listByCompanyIdAndVideoIds(companyId, videoIdList);
    }

    @Override
    public List<FsUserCourseVideoRedPackage> listByRuleIds(List<Long> ids) {
        return fsUserCourseVideoRedPackageMapper.listByRuleIds(ids);
    }

    private void batchUpdateRedPackage(List<FsUserCourseVideoRedPackage> list) {
        // 分批次处理（避免一次性提交太多，为后续如果数据量太大做准备）
        List<List<FsUserCourseVideoRedPackage>> batches = Lists.partition(list, 500);
        batches.forEach(batch -> {
            SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
            try {
                FsUserCourseVideoRedPackageMapper mapper = sqlSession.getMapper(FsUserCourseVideoRedPackageMapper.class);
                batch.forEach(mapper::updateRedPackageByParams);
                sqlSession.commit();
            } finally {
                sqlSession.close();
            }
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchRedPacketByPeriod(List<FsBatchPeriodRedPackageParam> periodRedPackageList) {
        // 1、提取所有传入的营期id
        Set<Long> periodIds = periodRedPackageList.stream()
                .map(FsBatchPeriodRedPackageParam::getPeriodId)
                .collect(Collectors.toSet());

        // 2、查询传入的营期信息，主要作用是获取营期的公司ids
        List<FsUserCoursePeriod> fsUserCoursePeriods = userCoursePeriodMapper.selectFsUserCoursePeriodsByIds(periodIds);
        Map<Long, FsUserCoursePeriod> periodMap = fsUserCoursePeriods.stream()
                .collect(Collectors.toMap(FsUserCoursePeriod::getPeriodId, Function.identity()));

        // 3、批量查询营期课程信息
        List<FsUserCoursePeriodDays> fsUserCoursePeriodDays = userCoursePeriodDaysMapper.selectCourseVideoList(periodIds);
        Map<Long, List<FsUserCoursePeriodDays>> fsUserCoursePeriodDaysMap = fsUserCoursePeriodDays.stream()
                .collect(Collectors.groupingBy(FsUserCoursePeriodDays::getPeriodId));

        // 4、组装数据
        List<FsUserCourseVideoRedPackage> fsRedPackageList = new ArrayList<>();
        periodRedPackageList.forEach(v -> {
            Long periodId = v.getPeriodId();
            String[] companyIds = periodMap.get(periodId).getCompanyId().split(",");

            List<FsUserCoursePeriodDays> periodVideos = fsUserCoursePeriodDaysMap.getOrDefault(periodId, Collections.emptyList());

            // 将营期id、视频id、公司id组装成一条数据
            for (String companyId : companyIds) {
                periodVideos.forEach(c -> {
                    FsUserCourseVideoRedPackage fsUserCourseVideoRedPackage = new FsUserCourseVideoRedPackage();
                    fsUserCourseVideoRedPackage.setCompanyId(Long.parseLong(companyId));
                    fsUserCourseVideoRedPackage.setVideoId(c.getVideoId());
                    fsUserCourseVideoRedPackage.setRedPacketMoney(v.getRedPacketMoney());
                    fsUserCourseVideoRedPackage.setPeriodId(periodId);
                    fsUserCourseVideoRedPackage.setDataType(2);
                    fsRedPackageList.add(fsUserCourseVideoRedPackage);
                });
            }
        });

        // 5、 新增或修改
        this.batchSaveCompanyRedPackage(fsRedPackageList);
    }

    @Override
    public List<FsUserCourseVideoRedPackage> selectByRuleIds(List<Long> ruleIds) {
        return fsUserCourseVideoRedPackageMapper.selectByRuleIds(ruleIds);
    }


}
