package com.ym.mec.biz.service.impl;

import com.ym.mec.biz.dal.dao.*;
import com.ym.mec.biz.dal.dto.MusicalListDetailDto;
import com.ym.mec.biz.dal.entity.*;
import com.ym.mec.biz.dal.enums.*;
import com.ym.mec.biz.service.*;
import com.ym.mec.common.dal.BaseDAO;
import com.ym.mec.common.exception.BizException;
import com.ym.mec.common.page.WrapperUtil;
import com.ym.mec.common.service.impl.BaseServiceImpl;
import com.ym.mec.util.collection.MapUtil;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import static com.ym.mec.biz.dal.enums.DealStatusEnum.SUCCESS;
import static com.ym.mec.biz.dal.enums.OrderDetailTypeEnum.*;
import static com.ym.mec.biz.dal.enums.PaymentStatusEnum.YES;

@Service
public class StudentPaymentOrderDetailServiceImpl extends BaseServiceImpl<Long, StudentPaymentOrderDetail> implements StudentPaymentOrderDetailService {

    @Autowired
    private StudentPaymentOrderDetailDao studentPaymentOrderDetailDao;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private TeacherDao teacherDao;
    @Autowired
    private MusicGroupDao musicGroupDao;
    @Autowired
    private OrganizationDao organizationDao;
    @Autowired
    private MusicGroupPurchaseListDao musicGroupPurchaseListDao;
    @Autowired
    private StudentRegistrationDao studentRegistrationDao;
    @Autowired
    private SubjectDao subjectDao;
    @Autowired
    private SubjectChangeDao subjectChangeDao;
    @Autowired
    private StudentCourseFeeDetailDao studentCourseFeeDetailDao;
    @Autowired
    private SellOrderService sellOrderService;
    @Autowired
    private ActivityUserMapperService activityUserMapperService;
    @Autowired
    private StudentInstrumentService studentInstrumentService;
    @Autowired
    private CloudTeacherOrderService cloudTeacherOrderService;
    @Autowired
    private StudentPaymentOrderService studentPaymentOrderService;
    @Autowired
    private MusicGroupPaymentCalenderDetailService musicGroupPaymentCalenderDetailService;

    @Override
    public BaseDAO<Long, StudentPaymentOrderDetail> getDAO() {
        return studentPaymentOrderDetailDao;
    }

    @Override
    public StudentPaymentOrderDetailDao getDao() {
        return studentPaymentOrderDetailDao;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int batchAdd(List<StudentPaymentOrderDetail> studentPaymentOrderDetailList) {
        return Optional.ofNullable(studentPaymentOrderDetailList)
                .filter(CollectionUtils::isNotEmpty)
                .map(studentPaymentOrderDetailDao::batchAdd)
                .orElse(0);
    }

    @Override
	public int batchUpdate(List<StudentPaymentOrderDetail> studentPaymentOrderDetailList) {
		return studentPaymentOrderDetailDao.batchUpdate(studentPaymentOrderDetailList);
	}

	@Transactional(rollbackFor = Exception.class)
    @Override
    public int allocateAndAdd(List<StudentPaymentOrderDetail> studentPaymentOrderDetailList, BigDecimal couponRemitFee) {
        return Optional.ofNullable(studentPaymentOrderDetailList)
                .filter(CollectionUtils::isNotEmpty)
                .map(l -> allocateAmount(l, couponRemitFee))
                .map(studentPaymentOrderDetailDao::batchAdd)
                .orElse(0);
    }

    /**
     * 按比例分摊优惠券减免金额
     *
     * @param studentPaymentOrderDetailList 订单详情
     * @param couponRemitFee                总优惠金额
     */
    @Override
    public List<StudentPaymentOrderDetail> allocateAmount(List<StudentPaymentOrderDetail> studentPaymentOrderDetailList, BigDecimal couponRemitFee) {
        //按比例分摊优惠券减免金额
        if (couponRemitFee.compareTo(BigDecimal.ZERO) > 0) {
            //待分配减免
            BigDecimal waitRemitFee = couponRemitFee;
            //已使用减免金额
            BigDecimal useRemitFee = BigDecimal.ZERO;
            List<StudentPaymentOrderDetail> collect = studentPaymentOrderDetailList.stream().filter(e -> e.getPrice().compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
            if (collect.size() == 0) {
                throw new BizException("订单金额异常");
            }
            BigDecimal totalAmount = WrapperUtil.sumList(collect, StudentPaymentOrderDetail::getPrice);
            for (int i = 0; i < collect.size(); i++) {
                StudentPaymentOrderDetail orderDetail = collect.get(i);
                //如果是最后一件商品
                if (i == collect.size() - 1) {
                    orderDetail.setPrice(orderDetail.getPrice().subtract(waitRemitFee));
                    orderDetail.setRemitFee(orderDetail.getRemitFee().add(waitRemitFee));
                } else {
                    //获取比例
                    BigDecimal ratioAmount = orderDetail.getPrice().divide(totalAmount, 6, RoundingMode.HALF_UP);
                    //获取分配的减免金额
                    BigDecimal multiply = ratioAmount.multiply(couponRemitFee).setScale(2, RoundingMode.HALF_UP);
                    waitRemitFee = waitRemitFee.subtract(multiply);
                    useRemitFee = useRemitFee.add(multiply);
                    orderDetail.setPrice(orderDetail.getPrice().subtract(multiply));
                    orderDetail.setRemitFee(orderDetail.getRemitFee().add(multiply));
                }
            }
            return collect;
        }
        return studentPaymentOrderDetailList;
    }

    @Override
    public List<StudentPaymentOrderDetail> findApplyOrderSuccess(String musicGroupId, DealStatusEnum status) {
        return studentPaymentOrderDetailDao.findApplyOrderSuccess(musicGroupId, status);
    }

    @Override
    public List<Goods> getMusicalList(String musicGroupId) {
        List<StudentPaymentOrderDetail> applyOrder = findApplyOrderSuccess(musicGroupId, DealStatusEnum.SUCCESS);
        if (applyOrder == null || applyOrder.size() == 0) {
            return null;
        }
        StringBuilder goodsIdsStr = new StringBuilder();
        for (StudentPaymentOrderDetail studentPaymentOrderDetail : applyOrder) {
            if (studentPaymentOrderDetail == null) continue;
            if (StringUtils.isNotBlank(studentPaymentOrderDetail.getGoodsIdList())) {
                goodsIdsStr.append(studentPaymentOrderDetail.getGoodsIdList()).append(",");
            }
        }
        if (StringUtils.isBlank(goodsIdsStr.toString())) {
            return null;
        }

        String[] goodSIdArr = goodsIdsStr.toString().split(",");

        List<Goods> goodies = goodsService.findGoodsByIds(goodsIdsStr.toString());
        MusicGroup musicGroup = musicGroupDao.get(musicGroupId);
        Organization organization = organizationDao.get(musicGroup.getOrganId());
        goodies.forEach(e -> {
            e.setSellCount(0);
            //当作乐团名称字段处理
            e.setMemo(musicGroup.getName());
            //当作分部名称字段处理
            e.setBrief(organization.getName());
            for (String goodsIdStr : goodSIdArr) {
                if (e.getId().equals(Integer.parseInt(goodsIdStr))) {
                    e.setSellCount(e.getSellCount() + 1);
                }
            }
        });
        //乐器更换的
        SubjectChange changeGoods = subjectChangeDao.getChangeGoods(musicGroupId);
        if (changeGoods == null) {
            return goodies;
        }
        String originalGoodsIds = "";
        String changeGoodsIds = "";
        if (StringUtils.isNotBlank(changeGoods.getMusicGroupName())) {
            originalGoodsIds += StringUtils.isNotBlank(originalGoodsIds) ? "," + changeGoods.getMusicGroupName() : changeGoods.getMusicGroupName();
        }
        if (StringUtils.isNotBlank(changeGoods.getOriginalAccessories())) {
            originalGoodsIds += StringUtils.isNotBlank(originalGoodsIds) ? "," + changeGoods.getOriginalAccessories() : changeGoods.getOriginalAccessories();
        }
        if (StringUtils.isNotBlank(changeGoods.getTransNo())) {
            changeGoodsIds += StringUtils.isNotBlank(changeGoodsIds) ? "," + changeGoods.getTransNo() : changeGoods.getTransNo();
        }
        if (StringUtils.isNotBlank(changeGoods.getChangeAccessories())) {
            changeGoodsIds += StringUtils.isNotBlank(changeGoodsIds) ? "," + changeGoods.getChangeAccessories() : changeGoods.getChangeAccessories();
        }
        if (StringUtils.isNotBlank(changeGoodsIds)) {
            String[] changGoodsIdsArr = changeGoodsIds.split(",");
            List<Goods> addGoodies = new ArrayList<>();
            for (String goodsId : changGoodsIdsArr) {
                boolean has = false;
                for (Goods goods : goodies) {
                    if (goodsId.equals(goods.getId().toString())) {
                        goods.setSellCount(goods.getSellCount() + 1);
                        has = true;
                        break;
                    }
                }

                for (Goods addGoods : addGoodies) {
                    if (goodsId.equals(addGoods.getId().toString())) {
                        addGoods.setSellCount(addGoods.getSellCount() + 1);
                        has = true;
                        break;
                    }
                }
                if (!has) {
                    Goods goods = goodsService.get(Integer.parseInt(goodsId));
                    goods.setSellCount(1);
                    goods.setMemo(musicGroup.getName());
                    //当作分部名称字段处理
                    goods.setBrief(organization.getName());
                    addGoodies.add(goods);
                }
            }
            if (addGoodies.size() > 0) {
                goodies.addAll(addGoodies);
            }
        }

        if (StringUtils.isNotBlank(originalGoodsIds)) {
            String[] originalGoodsIdsArr = originalGoodsIds.split(",");
            for (String goodsId : originalGoodsIdsArr) {
                for (Goods goods : goodies) {
                    if (goodsId.equals(goods.getId().toString())) {
                        goods.setSellCount(goods.getSellCount() - 1);
                        break;
                    }
                }
            }
        }
        goodies.removeIf(goods -> goods.getSellCount() <= 0);
        return goodies;
    }

    @Override
    public Boolean verifyMusicalList(String musicGroupId) throws BizException {
        //乐器采购清单是否确认
        Map<String, Object> param = new HashMap<>();
        param.put("musicGroupId", musicGroupId);
        int count = musicGroupPurchaseListDao.queryCount(param);
        if (count > 0) {
            throw new BizException("采购清单已经确认");
        }

        List<Goods> musicalList = getMusicalList(musicGroupId);
        Date date = new Date();
        List<MusicGroupPurchaseList> musicGroupPurchaseLists = new ArrayList<>();
        //发放清单没有时确认特殊处理
        if (musicalList == null || musicalList.size() == 0) {
            musicalList = new ArrayList<>();
            Goods goods = new Goods();
            goods.setId(0);
            goods.setSellCount(0);
            musicalList.add(goods);
        }

        for (Goods goods : musicalList) {
            MusicGroupPurchaseList musicGroupPurchaseList = new MusicGroupPurchaseList();
            musicGroupPurchaseList.setGoodsId(goods.getId());
            musicGroupPurchaseList.setMusicGroupId(musicGroupId);
            musicGroupPurchaseList.setPurchaseNum(goods.getSellCount());
            musicGroupPurchaseList.setCreateTime(date);
            musicGroupPurchaseList.setUpdateTime(date);
            musicGroupPurchaseLists.add(musicGroupPurchaseList);
        }
        musicGroupPurchaseListDao.batchInsert(musicGroupPurchaseLists);
        return true;
    }

    @Override
    public List<Goods> findApplyOrderGoods(Long orderId) {
        List<StudentPaymentOrderDetail> applyOrderGoods = studentPaymentOrderDetailDao.findApplyOrderGoods(orderId);

        if (applyOrderGoods == null || applyOrderGoods.size() == 0) {
            return null;
        }
        String goodsIdsStr = "";
        for (StudentPaymentOrderDetail studentPaymentOrderDetail : applyOrderGoods) {
            if (studentPaymentOrderDetail.getGoodsIdList() != null && !studentPaymentOrderDetail.getGoodsIdList().isEmpty()) {
                goodsIdsStr += studentPaymentOrderDetail.getGoodsIdList() + ",";
            }
        }
        if (goodsIdsStr.isEmpty()) {
            return null;
        }
        goodsIdsStr = goodsIdsStr.substring(0, goodsIdsStr.length() - 1);

        String[] goodSIdArr = goodsIdsStr.split(",");

        List<Goods> goodies = goodsService.findGoodsByIds(goodsIdsStr);

        for (Goods goods : goodies) {
            goods.setSellCount(0);
            for (String goodsIdStr : goodSIdArr) {
                if (goods.getId().equals(Integer.parseInt(goodsIdStr))) {
                    goods.setSellCount(goods.getSellCount() + 1);
                }
            }
            if (StringUtils.isBlank(goods.getComplementGoodsIdList())) continue;
            goods.setGoodsList(goodsService.findGoodsByIds(goods.getComplementGoodsIdList()));
        }
        return goodies;
    }

    @Override
    public List<StudentPaymentOrderDetail> findUserApplyOrder(Integer userId, String musicGroupId, DealStatusEnum status) {
        return studentPaymentOrderDetailDao.findUserApplyOrder(userId, musicGroupId, status);
    }

    @Override
    public List<MusicalListDetailDto> getMusicalListDetail(String musicGroupId, Integer studentId) {

        List<MusicalListDetailDto> musicalListDetailDtos = new ArrayList<MusicalListDetailDto>();

        List<String> musicGroupIdList = new ArrayList<String>();
        musicGroupIdList.add(musicGroupId);

        List<StudentRegistration> studentRegistrationList = studentRegistrationDao.findByMusicGroupIds(musicGroupIdList, StudentMusicGroupStatusEnum.NORMAL);

        if (studentRegistrationList == null || studentRegistrationList.size() == 0) {
            return musicalListDetailDtos;
        }

        List<Integer> userIds = studentRegistrationList.stream().distinct().map(StudentRegistration::getUserId).collect(Collectors.toList());

        List<SubjectChange> subjectChangeList = subjectChangeDao.getStudentGoods(musicGroupId);
        Map<Integer, SubjectChange> subjectChangeMap = subjectChangeList.stream().collect(Collectors.toMap(SubjectChange::getStudentId, t -> t));

        SubjectChange subjectChange = null;

        MusicGroup musicGroup = musicGroupDao.get(musicGroupId);
        Organization organization = organizationDao.get(musicGroup.getOrganId());
        Map<Integer, String> usernameMap = MapUtil.convertIntegerMap(teacherDao.queryUsernameByIds(userIds));
        Map<Integer, String> userSubjectMap = subjectDao.getRegisterSubject(musicGroupId, userIds).stream().collect(Collectors.toMap(StudentRegistration::getUserId, StudentRegistration::getSubjectName));
        Integer userId = null;

        for (StudentRegistration studentRegistration : studentRegistrationList) {

            MusicalListDetailDto dto = new MusicalListDetailDto();

            userId = studentRegistration.getUserId();

            List<StudentPaymentOrder> studentPaymentOrderList = new ArrayList<StudentPaymentOrder>();

            if (studentRegistration.getMusicGroupPaymentCalenderId() == null) {
                studentPaymentOrderList = studentPaymentOrderService.findMusicGroupApplyOrderByStatus(userId, musicGroupId, SUCCESS);
            } else {
                studentPaymentOrderList = studentPaymentOrderService.queryByBatchNo(userId, studentRegistration.getMusicGroupPaymentCalenderId() + "",
                        DealStatusEnum.SUCCESS);
            }

            List<Long> paymentOrderIdList = studentPaymentOrderList.stream().map(t -> t.getId()).collect(Collectors.toList());

            subjectChange = subjectChangeMap.get(studentRegistration.getUserId());

            if ((paymentOrderIdList == null || paymentOrderIdList.size() == 0) && subjectChange == null) {
                continue;
            }

            List<StudentPaymentOrderDetail> orderDetailList = new ArrayList<StudentPaymentOrderDetail>();

            if (paymentOrderIdList != null && paymentOrderIdList.size() > 0) {
                orderDetailList = studentPaymentOrderDetailDao.getWithIds(paymentOrderIdList);
            }

            Map<OrderDetailTypeEnum, BigDecimal> userOrderTypeMap = new HashMap<OrderDetailTypeEnum, BigDecimal>();
            ;

            BigDecimal amount = BigDecimal.ZERO;
            KitGroupPurchaseTypeEnum kitGroupPurchaseType = null;
            String musicalId = null;
            StringBuffer accessoriesId = new StringBuffer();
            BigDecimal orderTotalAmount = BigDecimal.ZERO;

            boolean isCalculatedOfAccessories = false;
            boolean isChangeMusical = false;
            boolean isChangeAccessories = false;

            for (StudentPaymentOrderDetail spod : orderDetailList) {

                if (spod.getType() == OrderDetailTypeEnum.COURSE || spod.getType() == OrderDetailTypeEnum.HIGH_ONLINE_COURSE
                        || spod.getType() == OrderDetailTypeEnum.SINGLE || spod.getType() == OrderDetailTypeEnum.VIP
                        || spod.getType() == OrderDetailTypeEnum.HIGH || spod.getType() == OrderDetailTypeEnum.MIX
                        || spod.getType() == OrderDetailTypeEnum.DEMO || spod.getType() == OrderDetailTypeEnum.COMPREHENSIVE
                        || spod.getType() == OrderDetailTypeEnum.ENLIGHTENMENT || spod.getType() == OrderDetailTypeEnum.TRAINING_SINGLE
                        || spod.getType() == OrderDetailTypeEnum.TRAINING_MIX || spod.getType() == OrderDetailTypeEnum.HIGH_ONLINE
                        || spod.getType() == OrderDetailTypeEnum.MUSIC_NETWORK || spod.getType() == OrderDetailTypeEnum.CLASSROOM || spod.getType() == OrderDetailTypeEnum.THEORY_COURSE) {
                    spod.setType(OrderDetailTypeEnum.COURSE);
                    //courseAmount = courseAmount.add(spod.getPrice().subtract(spod.getRemitFee()));
                } else if (spod.getType() == OrderDetailTypeEnum.MUSICAL) {
                    if (subjectChange != null && spod.getPaymentOrderId() <= subjectChange.getOriginalOrderId()) {
                        if (subjectChange.getChangeMusical() == null) {
                            continue;
                        }
                        kitGroupPurchaseType = subjectChange.getKitGroupPurchaseType();
                        musicalId = subjectChange.getChangeMusical() + "";
                        spod.setPrice(subjectChange.getChangeMusicalPrice());
                        spod.setRemitFee(BigDecimal.ZERO);
                        isChangeMusical = true;
                    } else {
                        kitGroupPurchaseType = spod.getKitGroupPurchaseType();
                        musicalId = spod.getGoodsIdList();
                        //musicalAmount = musicalAmount.add(spod.getPrice());
                    }
                } else if (spod.getType() == OrderDetailTypeEnum.ACCESSORIES) {
                    if (subjectChange != null && (subjectChange.getOriginalOrderId() != null && spod.getPaymentOrderId() <= subjectChange.getOriginalOrderId())) {
                        if (StringUtils.isBlank(subjectChange.getChangeAccessories()) || isCalculatedOfAccessories == true) {
                            continue;
                        }
                        isCalculatedOfAccessories = true;
                        accessoriesId = accessoriesId.append(subjectChange.getChangeAccessories()).append(",");
                        //accessoriesAmount = accessoriesAmount.add(subjectChange.getChangeAccessoriesPrice());
                        spod.setPrice(subjectChange.getChangeAccessoriesPrice());
                        spod.setRemitFee(BigDecimal.ZERO);
                        isChangeAccessories = true;
                    } else {
                        accessoriesId = accessoriesId.append(spod.getGoodsIdList()).append(",");
                        //accessoriesAmount = accessoriesAmount.add(spod.getPrice());
                    }
                }

                amount = userOrderTypeMap.get(spod.getType());
                if (amount != null) {
                    amount = amount.add(spod.getPrice().subtract(spod.getRemitFee()));
                } else {
                    amount = spod.getPrice().subtract(spod.getRemitFee());
                }
                userOrderTypeMap.put(spod.getType(), amount);

                orderTotalAmount = orderTotalAmount.add(spod.getPrice().subtract(spod.getRemitFee()));
            }

            if (orderDetailList.size() == 0) {
                if (subjectChange != null) {
                    if (subjectChange.getChangeMusical() != null) {
                        kitGroupPurchaseType = subjectChange.getKitGroupPurchaseType();
                        musicalId = subjectChange.getChangeMusical() + "";
                        userOrderTypeMap.put(OrderDetailTypeEnum.MUSICAL, subjectChange.getChangeMusicalPrice());
                        orderTotalAmount = orderTotalAmount.add(subjectChange.getChangeMusicalPrice());
                    }
                    if (StringUtils.isNotBlank(subjectChange.getChangeAccessories())) {
                        accessoriesId = accessoriesId.append(subjectChange.getChangeAccessories()).append(",");
                        userOrderTypeMap.put(OrderDetailTypeEnum.ACCESSORIES, subjectChange.getChangeAccessoriesPrice());
                        orderTotalAmount = orderTotalAmount.add(subjectChange.getChangeAccessoriesPrice());
                    }
                }
            } else if (isChangeAccessories == false || isChangeMusical == false) {
                if (subjectChange != null) {
                    if (subjectChange.getChangeMusical() != null && isChangeMusical == false) {
                        kitGroupPurchaseType = subjectChange.getKitGroupPurchaseType();
                        musicalId = subjectChange.getChangeMusical() + "";
                        userOrderTypeMap.put(OrderDetailTypeEnum.MUSICAL, subjectChange.getChangeMusicalPrice());
                        orderTotalAmount = orderTotalAmount.add(subjectChange.getChangeMusicalPrice());
                    }
                    if (StringUtils.isNotBlank(subjectChange.getChangeAccessories()) && isChangeAccessories == false) {
                        accessoriesId = accessoriesId.append(subjectChange.getChangeAccessories()).append(",");
                        userOrderTypeMap.put(OrderDetailTypeEnum.ACCESSORIES, subjectChange.getChangeAccessoriesPrice());
                        orderTotalAmount = orderTotalAmount.add(subjectChange.getChangeAccessoriesPrice());
                    }
                }
            }

            dto.setAccessoriesAmount(userOrderTypeMap.get(OrderDetailTypeEnum.ACCESSORIES));
            dto.setCourseAmount(userOrderTypeMap.get(OrderDetailTypeEnum.COURSE));
            dto.setMusicalAmount(userOrderTypeMap.get(OrderDetailTypeEnum.MUSICAL));
            dto.setMaintenanceAmount(userOrderTypeMap.get(OrderDetailTypeEnum.MAINTENANCE));
            dto.setCloudTeacherAmount(userOrderTypeMap.get(OrderDetailTypeEnum.CLOUD_TEACHER) == null ? userOrderTypeMap
                    .get(OrderDetailTypeEnum.CLOUD_TEACHER_PLUS) : userOrderTypeMap.get(OrderDetailTypeEnum.CLOUD_TEACHER));

            if (StringUtils.isNoneBlank(accessoriesId.toString())) {
                String accessoriesIdList = StringUtils.removeEnd(accessoriesId.toString(), ",");
                Map<Integer, Goods> goodsMap = goodsService.findGoodsByIds(accessoriesIdList).stream().collect(Collectors.toMap(Goods::getId, Goods -> Goods));

                String[] accessoriesIds = StringUtils.split(accessoriesIdList, ',');

                StringBuffer sb = new StringBuffer();
                for (String s : accessoriesIds) {
                    if (StringUtils.isBlank(s)) {
                        continue;
                    }
                    sb.append(goodsMap.get(Integer.parseInt(s)).getName()).append(",");
                }
                dto.setAccessoriesName(StringUtils.removeEnd(sb.toString(), ","));
            }

            if (StringUtils.isNoneBlank(musicalId)) {
                dto.setMusicalName(goodsService.findGoodsByIds(musicalId).stream().map(Goods::getName).collect(Collectors.joining(",")));
            }
            dto.setKitGroupPurchaseTypeEnum(kitGroupPurchaseType);
            dto.setMusicGroupName(musicGroup.getName());
            dto.setOrganName(organization.getName());
            dto.setOrderAmount(orderTotalAmount);
            dto.setUserId(userId);
            dto.setSubjectName(userSubjectMap.get(userId));
            dto.setUsername(usernameMap.get(userId));

            musicalListDetailDtos.add(dto);
        }

        return musicalListDetailDtos;
    }

    @Override
    public StudentPaymentOrderDetail findApplyOrderMusical(Long orderId) {
        return studentPaymentOrderDetailDao.findApplyOrderMusical(orderId);
    }

    @Override
    public List<StudentPaymentOrderDetail> getOrderDetail(Long orderId) {

        if (orderId == null) {
            return new ArrayList<StudentPaymentOrderDetail>();
        }

        List<Long> orderIdList = new ArrayList<Long>();
        orderIdList.add(orderId);

        return getOrderDetail(orderIdList);
    }

    @Override
    public List<StudentPaymentOrderDetail> getOrderDetail(List<Long> orderIdList) {
        List<StudentPaymentOrderDetail> studentPaymentOrderDetailList = studentPaymentOrderDetailDao.getOrderDetailByOrderId(orderIdList);

        for (StudentPaymentOrderDetail spod : studentPaymentOrderDetailList) {
            if (spod.getType() == OrderDetailTypeEnum.ACCESSORIES || spod.getType() == OrderDetailTypeEnum.MUSICAL
                    || spod.getType() == OrderDetailTypeEnum.TEACHING) {
                List<Goods> goods = goodsService.findGoodsByIds(spod.getGoodsIdList());
                if (goods != null && goods.size() > 0) {
                    spod.setName(goods.stream().map(t -> t.getName()).collect(Collectors.joining(",")));
                }
            }
        }

        return studentPaymentOrderDetailList;
    }

    @Override
    public List<String> getOrderDetailType(Long orderId) {
        return studentPaymentOrderDetailDao.getOrderDetailType(orderId);
    }

    @Override
    public List<StudentPaymentOrderDetail> getOrderGoodsDetail(Long orderId) {
        return studentPaymentOrderDetailDao.getOrderDetail(orderId);
    }

    @Override
    public List<StudentPaymentOrderDetail> queryOrderDetail(Long orderId) {
        return studentPaymentOrderDetailDao.findApplyOrderGoods(orderId);
    }

    public void addOrderDetailTo(StudentPaymentOrder studentPaymentOrder, MusicGroup musicGroup, StudentRegistration studentRegistration) {
        //SurplusCourseFee
        List<StudentPaymentOrderDetail> allDetails = this.findByOrderId(studentPaymentOrder.getId());
        BigDecimal courseFee = allDetails.stream().filter(o -> !(o.getType() == MUSICAL)
                        && !(o.getType() == VIP)
                        && !(o.getType() == PRACTICE)
                        && !(o.getType() == MAINTENANCE)
                        && !(o.getType() == CLOUD_TEACHER)
                        && !(o.getType() == CLOUD_TEACHER_PLUS)
                        && !(o.getType() == ACCESSORIES))
                .map(o -> o.getPrice().subtract(o.getRemitFee() == null ? BigDecimal.ZERO : o.getRemitFee()))
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        if (studentRegistration.getTemporaryCourseFee() != null) {
            studentRegistration.setTemporaryCourseFee(new BigDecimal(0));
        }
        studentRegistration.setPaymentStatus(YES);
        studentRegistration.setMusicGroupStatus(StudentMusicGroupStatusEnum.NORMAL);
        if (studentPaymentOrder.getClassGroupId() == null || !studentPaymentOrder.getClassGroupId().equals(206)) {
            studentRegistration.setPayingStatus(0);
        }
        if (courseFee.compareTo(BigDecimal.ZERO) > 0) {
            //累加充值金额
            studentRegistration.setSurplusCourseFee(studentRegistration.getSurplusCourseFee().add(courseFee));
            //添加日志
            StudentCourseFeeDetail studentCourseFeeDetail = new StudentCourseFeeDetail();
            studentCourseFeeDetail.setTenantId(studentPaymentOrder.getTenantId());
            studentCourseFeeDetail.setStudentRegistrationId(studentRegistration.getId());
            studentCourseFeeDetail.setAmount(courseFee);
            studentCourseFeeDetail.setSurplusCourseFee(studentRegistration.getSurplusCourseFee());
            studentCourseFeeDetail.setMemo("乐团缴费充值");
            studentCourseFeeDetail.setOperator(studentPaymentOrder.getUserId());
            studentCourseFeeDetailDao.insert(studentCourseFeeDetail);
        }

        //缴费项目详情
        musicGroupPaymentCalenderDetailService.addCalenderDetail(studentPaymentOrder, studentRegistration);

        List<OrderDetailTypeEnum> detailTypeEnums = allDetails.stream().map(StudentPaymentOrderDetail::getType).collect(Collectors.toList());
        //销售订单详情
        if (allDetails.size() > 0 && (detailTypeEnums.contains(MUSICAL) || detailTypeEnums.contains(ACCESSORIES) || detailTypeEnums.contains(TEACHING))) {
            BigDecimal couponRemitFee = studentPaymentOrder.getCouponRemitFee();
            if (couponRemitFee.compareTo(BigDecimal.ZERO) > 0) {
                BigDecimal musicFee = allDetails.stream()
                        .filter(o -> o.getType() == MUSICAL || o.getType() == ACCESSORIES || o.getType() == TEACHING)
                        .map(StudentPaymentOrderDetail::getPrice)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal expectAmount = studentPaymentOrder.getExpectAmount();
                //获取比例
                BigDecimal ratioAmount = musicFee.divide(expectAmount, 6, BigDecimal.ROUND_HALF_UP);
                //获取分配的减免金额
                couponRemitFee = couponRemitFee.multiply(ratioAmount).setScale(2, BigDecimal.ROUND_HALF_UP);
            }
            sellOrderService.addOrderDetail2SellOrder(allDetails, studentPaymentOrder, musicGroup, couponRemitFee);
        }

        //活动小课包处理
        List<StudentPaymentOrderDetail> activity = allDetails.stream().filter(o -> o.getType() == PRACTICE || o.getType() == VIP).collect(Collectors.toList());
        if (activity != null && activity.size() > 0) {
            activityUserMapperService.addOrderDetail2Activity(studentPaymentOrder, activity);
        }

        //学生乐器与月保处理
        if (detailTypeEnums.contains(MUSICAL)) {
            StudentPaymentOrderDetail musical = allDetails.stream().filter(o -> o.getType() == MUSICAL).findFirst().get();
            Long studentInstrumentId = studentInstrumentService.addOrderDetail2Instrument(studentPaymentOrder, Integer.valueOf(musical.getGoodsIdList()));
            if (detailTypeEnums.contains(MAINTENANCE)) {
                StudentPaymentOrderDetail repair = allDetails.stream().filter(o -> o.getType() == MAINTENANCE).findFirst().get();
                repair.setStudentInstrumentId(studentInstrumentId);
                studentPaymentOrderDetailDao.update(repair);
            }
        }

        //学生云教练处理
        if (detailTypeEnums.contains(CLOUD_TEACHER)) {
            if(studentPaymentOrder.getType() == OrderTypeEnum.APPLY){
                studentRegistration.setHasCloudTeacher(1);
            }
            BigDecimal cloudTeacherFee = allDetails.stream().filter(o -> o.getType() == CLOUD_TEACHER)
                    .map(o -> o.getPrice().subtract(o.getRemitFee() == null ? BigDecimal.ZERO : o.getRemitFee()))
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            cloudTeacherOrderService.addOrderDetail2CloudTeacher(studentPaymentOrder, cloudTeacherFee);
        }
        studentRegistrationDao.update(studentRegistration);
    }

    @Override
    public List<StudentPaymentOrderDetail> findByOrderId(Long paymentOrderId) {
        List<StudentPaymentOrderDetail> paymentOrderDetails = studentPaymentOrderDetailDao.findByOrderId(paymentOrderId);
        for (StudentPaymentOrderDetail paymentOrderDetail : paymentOrderDetails) {
            paymentOrderDetail.setGoodsList(goodsService.findGoodsByIds(paymentOrderDetail.getGoodsIdList()));
        }
        return paymentOrderDetails;
    }
}