package cn.iocoder.yudao.module.base.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.UUID;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.base.entity.DlDriveSchoolCoachCourse;
import cn.iocoder.yudao.module.base.entity.DlDriveSchoolCourse;
import cn.iocoder.yudao.module.base.entity.DriveSchoolCourseDeduct;
import cn.iocoder.yudao.module.base.mapper.DlDriveSchoolCourseMapper;
import cn.iocoder.yudao.module.base.mapper.DriveSchoolCourseDeductMapper;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolCoachCourseService;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolCourseDeductService;
import cn.iocoder.yudao.module.base.service.DlDriveSchoolCourseService;
import cn.iocoder.yudao.module.base.vo.CourseSchemeVO;
import cn.iocoder.yudao.module.base.vo.DlDriveSchoolCoachVO;
import cn.iocoder.yudao.module.base.vo.DlDriveSchoolCourseNewVO;
import cn.iocoder.yudao.module.base.vo.DlDriveSchoolCourseVO;
import cn.iocoder.yudao.module.course.entity.SchoolCourseScheme;
import cn.iocoder.yudao.module.course.mapper.SchoolCourseSchemeMapper;
import cn.iocoder.yudao.module.course.service.SchoolCourseSchemeService;
import cn.iocoder.yudao.module.course.vo.SchoolCourseSchemeVO;
import cn.iocoder.yudao.module.jx.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;


import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 驾校教练 Service 实现类
 *
 * @author pqz
 */
@Service
@Validated
public class DlDriveSchoolCourseServiceImpl extends ServiceImpl<DlDriveSchoolCourseMapper, DlDriveSchoolCourse> implements DlDriveSchoolCourseService {

    @Resource
    private DlDriveSchoolCourseMapper courseMapper;
    @Resource
    private DlDriveSchoolCoachCourseService coachCourseService;
    @Resource
    private DlDriveSchoolCourseDeductService driveSchoolCourseDeductService;
    @Autowired
    private SchoolCourseSchemeService schoolCourseSchemeService;
    @Autowired
    private SchoolCourseSchemeMapper schoolCourseSchemeMapper;
    @Autowired
    private DriveSchoolCourseDeductMapper schoolCourseDeductMapper;

    /**
     * 分页查询驾校课程
     *
     * @param pageReqVO {@link DlDriveSchoolCourseVO}
     * @param page      分页参数
     * @return com.baomidou.mybatisplus.core.metadata.IPage<cn.iocoder.yudao.module.base.vo.DlDriveSchoolCourseVO>
     * @author PQZ
     * @date 22:04 2025/1/16
     **/
    @Override
    public IPage<DlDriveSchoolCourseVO> queryListPage(DlDriveSchoolCourseVO pageReqVO, Page<DlDriveSchoolCourseVO> page) {
        return courseMapper.queryListPage(pageReqVO, page);
    }

    /**
     * 不分页查询驾校课程
     *
     * @param courseVO {@link DlDriveSchoolCourseVO}
     * @return java.util.List<cn.iocoder.yudao.module.base.vo.DlDriveSchoolCourseVO>
     * @author PQZ
     * @date 22:07 2025/1/16
     **/
    @Override
    public List<DlDriveSchoolCourse> queryList(DlDriveSchoolCourseVO courseVO) {
        LambdaQueryWrapper<DlDriveSchoolCourse> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(BaseDO::getDeleted, 0).eq(DlDriveSchoolCourse::getIfDisplay,"0");
        if (StringUtils.isNotEmpty(courseVO.getName())) {
            lambdaQueryWrapper.like(DlDriveSchoolCourse::getName, courseVO.getName());
        }
        if (courseVO.getTenantId() != null) {
            lambdaQueryWrapper.eq(DlDriveSchoolCourse::getTenantId, courseVO.getTenantId());
        }

        return list(lambdaQueryWrapper);
    }

    /**
     * 保存课程信息
     *
     * @param courseVO {@link DlDriveSchoolCourseVO}
     * @author PQZ
     * @date 22:12 2025/1/16
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveDriveSchoolCourse(DlDriveSchoolCourseNewVO courseVO) {
        boolean isNew = (courseVO.getId() == null);

        DlDriveSchoolCourse course = BeanUtils.toBean(courseVO, DlDriveSchoolCourse.class);

        if (isNew) {
            // 先保存课程，生成 courseId
            save(course);

            List<CourseSchemeVO> schemeList = courseVO.getSchemeList();
            if (schemeList == null || schemeList.isEmpty()) {
                throw new RuntimeException("新增课程时必须至少包含一个提成方案");
            }

            for (CourseSchemeVO schemeVO : schemeList) {
                // 构建方案对象，主键为 UUID
                String schemeId = UUID.randomUUID().toString().replace("-", "");

                SchoolCourseScheme scheme = SchoolCourseScheme.builder()
                        .id(schemeId)
                        .name(schemeVO.getSchemeName())
                        .courseId(course.getId())
                        .isDefault(Boolean.TRUE.equals(schemeVO.getIsDefault()))
                        .build();

                schoolCourseSchemeService.save(scheme);

                // 保存方案对应的提成明细
                List<DriveSchoolCourseDeduct> deductList = schemeVO.getDeductList();
                if (deductList != null && !deductList.isEmpty()) {
                    for (DriveSchoolCourseDeduct deduct : deductList) {
                        deduct.setCourseId(course.getId());
                        deduct.setSchemeId(schemeId);
                        deduct.setId(null);
                    }
                    driveSchoolCourseDeductService.saveBatch(deductList);
                }
            }
        } else {
            // 修改课程，保留提成方案及提成明细不变
            updateById(course);
        }

        // 保存教练课程关系
        coachCourseService.saveCoachCourse(course.getId(), courseVO.getName(), courseVO.getType(), courseVO.getCoachList());
    }
    /*public void saveDriveSchoolCourse(DlDriveSchoolCourseVO courseVO) {
        DlDriveSchoolCourse course = BeanUtils.toBean(courseVO, DlDriveSchoolCourse.class);
        saveOrUpdate(course);
        coachCourseService.saveCoachCourse(course.getId(), courseVO.getName(), courseVO.getType(), courseVO.getCoachList());
        // 删除提成配置
        driveSchoolCourseDeductService.remove(Wrappers.<DriveSchoolCourseDeduct>lambdaQuery()
                .eq(DriveSchoolCourseDeduct::getCourseId, course.getId()));
        //设置提成信息课程id
        courseVO.getDeductList().forEach(deduct -> {
            deduct.setCourseId(course.getId());
            deduct.setId(null);
        });

        // 保存提成信息
        driveSchoolCourseDeductService.saveBatch(courseVO.getDeductList());
    }*/


    /**
     * 删除课程信息
     *
     * @param id 课程id
     * @author PQZ
     * @date 22:14 2025/1/16
     **/
    @Override
    public void deleteCourse(String id) {
        // 删除前判断是否有已报名课程的订单
        Integer count = courseMapper.orderCountByCourseId(id);
        if(count > 0){
            throw new RuntimeException("该课程有已报名订单，无法删除");
        }else{
            removeById(id);
        }

    }

    /**
     * 通过id查询课程信息
     *
     * @param id 课程id
     * @return cn.iocoder.yudao.module.base.vo.DlDriveSchoolCourseVO
     * @author PQZ
     * @date 22:15 2025/1/16
     **/
    @Override
    public DlDriveSchoolCourseVO queryDetailById(String id) {
        DlDriveSchoolCourse course = getById(id);
        //查询课程信息
        DlDriveSchoolCourseVO result = BeanUtils.toBean(course, DlDriveSchoolCourseVO.class);
        //课程关联教练
        List<DlDriveSchoolCoachVO> coachList = transCoachList(coachCourseService.queryByCourseId(id));
        result.setCoachList(coachList);
        // 使用 Stream API 按 coachId 分组
        Map<String, List<String>> groupedCoachMap = coachList.stream()
                .collect(Collectors.groupingBy(
                        DlDriveSchoolCoachVO::getCoachName,
                        Collectors.mapping(coach -> "科目" + coach.getSubject(), Collectors.toList())
                ));
        // 将 groupedCoachMap 转换为字符串格式
        String resultString = groupedCoachMap.entrySet().stream()
                .map(entry -> entry.getKey() + "[" + String.join(" ", entry.getValue()) + "]")
                .collect(Collectors.joining(", "));
        result.setCoachListText(resultString);
        // 查询提成配置
        List<DriveSchoolCourseDeduct> deducts = driveSchoolCourseDeductService.list(Wrappers.<DriveSchoolCourseDeduct>lambdaQuery()
                .eq(DriveSchoolCourseDeduct::getCourseId, id));
        if (CollUtil.isEmpty(deducts)) {
            // 科目一到科目四都为0
            for (int i = 1; i <= 4; i++) {
                DriveSchoolCourseDeduct deduct = new DriveSchoolCourseDeduct();
                deduct.setCourseId(id);
                deduct.setCourseSubject(i + "");
                deduct.setDeduct(new BigDecimal("0"));
                deducts.add(deduct);
            }
        }
        result.setDeductList(deducts);
        return result;
    }


    /**
     * 数据类型转换
     *
     * @param coachList TODO
     * @return java.util.List<cn.iocoder.yudao.module.base.vo.DlDriveSchoolCoachVO>
     * @author PQZ
     * @date 14:25 2025/2/8
     **/
    private List<DlDriveSchoolCoachVO> transCoachList(List<DlDriveSchoolCoachCourse> coachList) {
        List<DlDriveSchoolCoachVO> transList = new ArrayList<>();
        if (!coachList.isEmpty()) {
            coachList.forEach(item -> {
                DlDriveSchoolCoachVO vo = new DlDriveSchoolCoachVO();
                vo.setCoachId(item.getCoachId());
                vo.setCoachName(item.getCoachName());
                vo.setSubject(item.getSubject());
                vo.setCoachPhone(item.getCoachPhone());
                transList.add(vo);
            });
        }
        return transList;
    }

    /**
     * 根据课程id查询提成方案列表
     */
    @Override
    public List<SchoolCourseScheme> getSchemeList(String courseId) {
        List<SchoolCourseScheme> schemes = schoolCourseSchemeMapper.selectList(
                new LambdaQueryWrapper<SchoolCourseScheme>()
                        .eq(SchoolCourseScheme::getCourseId, courseId)
                        .eq(SchoolCourseScheme::getDeleted, false)
        );

        if (CollectionUtils.isEmpty(schemes)) {
            return Collections.emptyList();
        }

        // 批量查询这些方案的提成明细（一次性查询，避免循环查库）
        List<String> schemeIds = schemes.stream()
                .map(SchoolCourseScheme::getId)
                .collect(Collectors.toList());

        List<DriveSchoolCourseDeduct> allDeducts = schoolCourseDeductMapper.selectList(
                new LambdaQueryWrapper<DriveSchoolCourseDeduct>()
                        .in(DriveSchoolCourseDeduct::getSchemeId, schemeIds)
                        .eq(DriveSchoolCourseDeduct::getDeleted, false)
        );

        // 将提成明细按 schemeId 分组
        Map<String, List<DriveSchoolCourseDeduct>> deductsByScheme = allDeducts.stream()
                .collect(Collectors.groupingBy(DriveSchoolCourseDeduct::getSchemeId));

        // 组装前端需要的结构
        return schemes.stream().map(scheme -> {
            // 提取当前方案的所有提成记录
            List<DriveSchoolCourseDeduct> deducts = deductsByScheme.getOrDefault(scheme.getId(), Collections.emptyList());

            // 转换为前端需要的字段格式（科目0-4分别映射）
            Map<String, BigDecimal> deductMap = deducts.stream()
                    .collect(Collectors.toMap(
                            DriveSchoolCourseDeduct::getCourseSubject,
                            DriveSchoolCourseDeduct::getDeduct,
                            (v1, v2) -> v1
                    ));

            // 设置到 scheme 对象中
            SchoolCourseSchemeVO result = BeanUtils.toBean(scheme, SchoolCourseSchemeVO.class);
            /*result.setId(scheme.getId());
            result.setCourseId(scheme.getCourseId());
            result.setIsDefault(scheme.getIsDefault());
            result.setCourseId(scheme.getCourseId());*/

            result.setName(scheme.getName());
            result.setSubject0Deduct(deductMap.getOrDefault("0", BigDecimal.ZERO));
            result.setSubject1Deduct(deductMap.getOrDefault("1", BigDecimal.ZERO));
            result.setSubject2Deduct(deductMap.getOrDefault("2", BigDecimal.ZERO));
            result.setSubject3Deduct(deductMap.getOrDefault("3", BigDecimal.ZERO));
            result.setSubject4Deduct(deductMap.getOrDefault("4", BigDecimal.ZERO));

            return result;
        }).collect(Collectors.toList());
    }


}
