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

import cn.hutool.core.lang.UUID;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.module.base.entity.DriveSchoolCourseDeduct;
import cn.iocoder.yudao.module.base.mapper.DriveSchoolCourseDeductMapper;
import cn.iocoder.yudao.module.base.vo.SchemeFormDTO;
import cn.iocoder.yudao.module.course.entity.SchoolCourseOrder;
import cn.iocoder.yudao.module.course.entity.SchoolCourseScheme;
import cn.iocoder.yudao.module.course.mapper.SchoolCourseOrderMapper;
import cn.iocoder.yudao.module.course.mapper.SchoolCourseSchemeMapper;
import cn.iocoder.yudao.module.course.service.SchoolCourseOrderService;
import cn.iocoder.yudao.module.course.service.SchoolCourseSchemeService;
import cn.iocoder.yudao.module.course.vo.SchoolCourseSchemeVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Service
@Validated
public class SchoolCourseSchemeServiceImpl extends ServiceImpl<SchoolCourseSchemeMapper, SchoolCourseScheme> implements SchoolCourseSchemeService {

    @Resource
    private SchoolCourseSchemeMapper schemeMapper;
    @Resource
    private DriveSchoolCourseDeductMapper deductMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveOrUpdateScheme(SchemeFormDTO dto) {
        // 判断是否新增
        boolean isUpdate = dto.getId() != null;

        // 设置ID（如果是新增则生成UUID）
        String schemeId = isUpdate ? dto.getId() : UUID.randomUUID().toString().replace("-", "");
        // 保存/更新方案主表
        SchoolCourseScheme scheme = new SchoolCourseScheme()
                .setId(schemeId)
                .setName(dto.getName())
                .setCourseId(dto.getCourseId())
                .setIsDefault(dto.getIsDefault());

        if (isUpdate) {
            schemeMapper.updateById(scheme);
//            deductMapper.deleteBySchemeId(dto.getId());
        } else {
            schemeMapper.insert(scheme);
        }

        // 保存提成配置
        saveDeductConfigs(scheme.getId(), dto);

        // 处理默认方案
        if (Boolean.TRUE.equals(dto.getIsDefault())) {
            schemeMapper.cancelOtherDefault(scheme.getCourseId(), scheme.getId());
        }
    }

    private void saveDeductConfigs(String schemeId, SchemeFormDTO dto) {
        upsertDeduct(schemeId, dto.getCourseId(), "0", dto.getSubject0Deduct());
        upsertDeduct(schemeId, dto.getCourseId(), "1", dto.getSubject1Deduct());
        upsertDeduct(schemeId, dto.getCourseId(), "2", dto.getSubject2Deduct());
        upsertDeduct(schemeId, dto.getCourseId(), "3", dto.getSubject3Deduct());
        upsertDeduct(schemeId, dto.getCourseId(), "4", dto.getSubject4Deduct());
    }

    private void upsertDeduct(String schemeId, String courseId, String subject, BigDecimal amount) {
        if (amount == null) {
            return;
        }

        DriveSchoolCourseDeduct deduct = deductMapper.selectOne(
                new LambdaQueryWrapper<DriveSchoolCourseDeduct>()
                        .eq(DriveSchoolCourseDeduct::getSchemeId, schemeId)
                        .eq(DriveSchoolCourseDeduct::getCourseSubject, subject)
                        .eq(DriveSchoolCourseDeduct::getDeleted, false)
        );

        if (deduct != null) {
            // 更新已有记录
            deduct.setDeduct(amount);
            deductMapper.updateById(deduct);
        } else {
            // 插入新记录
            DriveSchoolCourseDeduct newDeduct = new DriveSchoolCourseDeduct()
                    .setSchemeId(schemeId)
                    .setCourseId(courseId)
                    .setCourseSubject(subject)
                    .setDeduct(amount);
            deductMapper.insert(newDeduct);
        }
    }
    private void addDeductIfPositive(List<DriveSchoolCourseDeduct> list, String schemeId,
                                     String courseId, String subject, BigDecimal amount) {
        if (amount != null && amount.compareTo(BigDecimal.ZERO) > 0) {
            list.add(new DriveSchoolCourseDeduct()
                    .setSchemeId(schemeId)
                    .setCourseId(courseId)
                    .setCourseSubject(subject)
                    .setDeduct(amount));
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteScheme(String id) {
        // 校验存在
        validateSchemeExists(id);
        // 检查是否有订单在使用当前方案
        Integer count = schemeMapper.getOrderCountBySchemeId(id);
        if(count > 0){
            throw new RuntimeException("有订单正在使用该方案，不能删除");
        }else{
            // 删除关联提成
//            deductMapper.deleteBySchemeId(id);
            deductMapper.delete(new LambdaQueryWrapper<DriveSchoolCourseDeduct>()
                    .eq(DriveSchoolCourseDeduct::getSchemeId, id));
            // 删除方案
            schemeMapper.deleteById(id);

        }

    }

    private void validateSchemeExists(String id) {
        if (schemeMapper.selectById(id) == null) {
            throw new RuntimeException("方案不存在");
        }
    }

    @Override
    public SchoolCourseSchemeVO getSchemeDetail(String id) {
        // 1. 查询方案基础信息
        SchoolCourseScheme scheme = schemeMapper.selectById(id);
        if (scheme == null) {
            throw new RuntimeException("方案不存在");
        }

        // 2. 查询关联提成配置
        List<DriveSchoolCourseDeduct> deducts = deductMapper.selectBySchemeId(id);

        // 3. 转换为前端需要的结构
        return convertToDetailVO(scheme, deducts);
    }

    /**
     * 根据课程id和科目获取默认提成金额
     */
    @Override
    public BigDecimal getCourseDeduct(String courseId, Integer subject) {
        return schemeMapper.getCourseDeduct(courseId, subject);
    }

    /**
     * 根据提成方案id和科目获取对应提成金额
     */
    @Override
    public BigDecimal getSchemeById(String id, Integer subject) {
        return schemeMapper.getSchemeById(id, subject);
    }

    private SchoolCourseSchemeVO convertToDetailVO(SchoolCourseScheme scheme, List<DriveSchoolCourseDeduct> deducts) {
        SchoolCourseSchemeVO vo = new SchoolCourseSchemeVO();
        vo.setId(scheme.getId());
        vo.setName(scheme.getName());
        vo.setCourseId(scheme.getCourseId());
        vo.setIsDefault(scheme.getIsDefault());

        // 初始化所有科目为0
        vo.setSubject0Deduct(BigDecimal.ZERO);
        vo.setSubject1Deduct(BigDecimal.ZERO);
        vo.setSubject2Deduct(BigDecimal.ZERO);
        vo.setSubject3Deduct(BigDecimal.ZERO);
        vo.setSubject4Deduct(BigDecimal.ZERO);

        // 填充实际存在的提成配置
        deducts.forEach(deduct -> {
            switch (deduct.getCourseSubject()) {
                case "0":
                    vo.setSubject0Deduct(deduct.getDeduct());
                    break;
                case "1":
                    vo.setSubject1Deduct(deduct.getDeduct());
                    break;
                case "2":
                    vo.setSubject2Deduct(deduct.getDeduct());
                    break;
                case "3":
                    vo.setSubject3Deduct(deduct.getDeduct());
                    break;
                case "4":
                    vo.setSubject4Deduct(deduct.getDeduct());
                    break;
            }
        });

        return vo;
    }


}
