package com.yonge.cooleshow.biz.dal.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.yonge.cooleshow.biz.dal.dao.CourseRelationMusicAlbumDao;
import com.yonge.cooleshow.biz.dal.entity.CourseGroup;
import com.yonge.cooleshow.biz.dal.entity.CourseRelationMusicAlbum;
import com.yonge.cooleshow.biz.dal.entity.MusicSheetPurchaseRecord;
import com.yonge.cooleshow.biz.dal.entity.UserOrder;
import com.yonge.cooleshow.biz.dal.entity.VideoLessonGroup;
import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
import com.yonge.cooleshow.biz.dal.enums.album.PurchaseRecordTypeEnum;
import com.yonge.cooleshow.biz.dal.enums.course.CourseRelationTypeEnum;
import com.yonge.cooleshow.biz.dal.enums.course.CourseTypeEnum;
import com.yonge.cooleshow.biz.dal.service.CourseGroupService;
import com.yonge.cooleshow.biz.dal.service.CourseRelationMusicAlbumService;
import com.yonge.cooleshow.biz.dal.service.MusicSheetPurchaseRecordService;
import com.yonge.cooleshow.biz.dal.service.VideoLessonGroupService;
import com.yonge.cooleshow.biz.dal.wrapper.course.CourseRelationWrapper;
import com.yonge.cooleshow.common.enums.EStatus;
import com.yonge.toolset.base.util.ThreadPool;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;


@Slf4j
@Service
public class CourseRelationMusicAlbumServiceImpl extends ServiceImpl<CourseRelationMusicAlbumDao, CourseRelationMusicAlbum> implements CourseRelationMusicAlbumService {

    @Autowired
    private MusicSheetPurchaseRecordService musicSheetPurchaseRecordService;
    @Autowired
    private VideoLessonGroupService videoLessonGroupService;
    @Autowired
    private CourseGroupService courseGroupService;

    /**
     * 异常更新课程关联曲目专辑
     *
     * @param groupId 课程组ID
     * @param courseType 课程组类型
     */
    @Override
    public void asyncUpdateCourseRelationMusicAlbumInfo(Long groupId, CourseTypeEnum courseType) {

        // 课程组关联曲目、专辑信息
        List<CourseRelationMusicAlbum> musicAlbums = lambdaQuery()
                .eq(CourseRelationMusicAlbum::getCourseGroupId, groupId)
                .list();

        if (CollectionUtils.isEmpty(musicAlbums)) {
            return;
        }

        ThreadPool.getExecutor().submit(() -> {

            try {

                Map<CourseRelationTypeEnum, List<CourseRelationMusicAlbum>> musicAlbumGroupMap = musicAlbums.stream()
                        .collect(Collectors.groupingBy(CourseRelationMusicAlbum::getUseRelationType));

                // 推荐类型直接删除购买记录
                if (musicAlbumGroupMap.containsKey(CourseRelationTypeEnum.RECOMMEND)) {

                    List<Long> deleteRelationIds = musicAlbumGroupMap.get(CourseRelationTypeEnum.RECOMMEND).stream()
                            .map(CourseRelationMusicAlbum::getId).distinct().collect(Collectors.toList());

                    // 删除用户购买关系
                    if (CollectionUtils.isNotEmpty(deleteRelationIds)) {

                        musicSheetPurchaseRecordService.lambdaUpdate()
                                .in(MusicSheetPurchaseRecord::getCourseMusicAlbumId, deleteRelationIds)
                                .remove();
                    }

                }

                // 赠送按状态进行数据同步更新
                if (musicAlbumGroupMap.containsKey(CourseRelationTypeEnum.GIFT)) {

                    Map<Integer, List<CourseRelationMusicAlbum>> collect = musicAlbumGroupMap.get(CourseRelationTypeEnum.GIFT).stream()
                            .collect(Collectors.groupingBy(CourseRelationMusicAlbum::getDelFlog));

                    for (Map.Entry<Integer, List<CourseRelationMusicAlbum>> entry : collect.entrySet()) {

                        if (EStatus.DISABLE.match(entry.getKey())) {

                            // 删除购买关系
                            List<Long> deleteIds = entry.getValue().stream()
                                    .map(CourseRelationMusicAlbum::getId).distinct().collect(Collectors.toList());

                            if (CollectionUtils.isNotEmpty(deleteIds)) {

                                // 删除用户购买关系
                                musicSheetPurchaseRecordService.lambdaUpdate()
                                        .in(MusicSheetPurchaseRecord::getCourseMusicAlbumId, deleteIds)
                                        .remove();
                            }
                        }

                        if (EStatus.ENABLE.match(entry.getKey())) {

                            // 更新购买关系
                            for (CourseRelationMusicAlbum item : entry.getValue()) {

                                musicSheetPurchaseRecordService.lambdaUpdate()
                                        .eq(MusicSheetPurchaseRecord::getCourseMusicAlbumId, item.getCourseId())
                                        .set(MusicSheetPurchaseRecord::getMusicSheetId, item.getMusicAlbumId())
                                        .set(MusicSheetPurchaseRecord::getPurchaseType, PurchaseRecordTypeEnum.valueOf(item.getRelationType().getCode()))
                                        .update();
                            }
                        }

                        if (EStatus.SELECTED.match(entry.getKey())) {

                            List<Long> giftIds = entry.getValue().stream()
                                    .map(CourseRelationMusicAlbum::getId).distinct().collect(Collectors.toList());

                            if (CollectionUtils.isNotEmpty(giftIds)) {

                                // 同步更新课程购买用户数据
                                saveCoursePurchaseUserRecordInfo(groupId, courseType, giftIds, entry);
                            }

                        }
                    }
                }

            } catch (Exception e) {
                log.error("asyncUpdateCourseRelationMusicAlbumInfo groupId={}, courseType={}", groupId, courseType, e);
            }

        });

    }

    /**
     * 更新课程购买用户数据
     * @param groupId 课程组ID
     * @param courseType CourseTypeEnum
     * @param giftIds 课程赠送关联ID
     * @param entry Map.Entry<Integer, List<CourseRelationMusicAlbum>>
     */
    private void saveCoursePurchaseUserRecordInfo(Long groupId, CourseTypeEnum courseType, List<Long> giftIds,
                                                     Map.Entry<Integer, List<CourseRelationMusicAlbum>> entry) {

        long teacherId;
        // 给已购买用户重新添加购买数据
        if (CourseTypeEnum.VIDEO == courseType) {
            // 视频课购买
            teacherId = Optional.ofNullable(videoLessonGroupService.getById(groupId))
                    .map(VideoLessonGroup::getId).orElse(0L);
        } else {
            // 其他课程购买
            teacherId = Optional.ofNullable(courseGroupService.getById(groupId))
                    .map(CourseGroup::getTeacherId).orElse(0L);
        }

        CourseRelationWrapper.PurchaseRecordQueryInfo queryInfo = CourseRelationWrapper.PurchaseRecordQueryInfo
                .builder()
                .courseType(courseType)
                .orderStatus(OrderStatusEnum.PAID)
                .groupId(groupId)
                .build();

        // 分页查询课程用户购买信息
        Page<UserOrder> pageInfo = new Page<>(1, 10);
        getBaseMapper().selectCoursePurchaseUserInfo(pageInfo, queryInfo);

        int limit = 100;
        int pages = ((int) pageInfo.getTotal() - 1) / limit + 1;

        List<UserOrder> records;
        List<CourseRelationWrapper.MusicAlbumRecord> musicAlbumRecords;
        Map<Long, Long> purchaseIdMap;
        for (int page = 1; page <= pages; page++) {

            records = getBaseMapper().selectCoursePurchaseUserInfo(new Page<>(page, limit), queryInfo);

            for (UserOrder record : records) {

                // 查询用户购买记录
                purchaseIdMap = musicSheetPurchaseRecordService.lambdaQuery()
                        .eq(MusicSheetPurchaseRecord::getStudentId, record.getUserId())
                        .eq(MusicSheetPurchaseRecord::getOrderStatus, OrderStatusEnum.PAID)
                        .in(MusicSheetPurchaseRecord::getCourseMusicAlbumId, giftIds)
                        .list().stream()
                        .collect(Collectors.toMap(MusicSheetPurchaseRecord::getCourseMusicAlbumId, MusicSheetPurchaseRecord::getId, (o, n) -> n));

                musicAlbumRecords = Lists.newArrayList();
                // 补录用户购买赠送曲目、专辑
                for (CourseRelationMusicAlbum item : entry.getValue()) {

                    musicAlbumRecords.add(CourseRelationWrapper.MusicAlbumRecord
                            .builder()
                            .clientType(record.getOrderClient())
                            .musicSheetId(item.getMusicAlbumId())
                            .orderNo(record.getOrderNo())
                            .purchasePrice(BigDecimal.ZERO)
                            .purchaseTime(DateTime.now().toDate())
                            .teacherId(teacherId)
                            .originalPrice(BigDecimal.ZERO)
                            .musicSheetServiceFee(BigDecimal.ZERO)
                            .orderStatus(OrderStatusEnum.PAID)
                            .studentId(record.getUserId())
                            .purchaseType(PurchaseRecordTypeEnum.valueOf(item.getRelationType().getCode()))
                            .courseMusicAlbumId(item.getId())
                            .id(purchaseIdMap.get(item.getId()))
                            .build());
                }

                if (CollectionUtils.isNotEmpty(musicAlbumRecords)) {

                    // 批量插入课程赠送曲目、专辑数据
                    musicSheetPurchaseRecordService.saveBatch(JSON.parseArray(JSON.toJSONString(musicAlbumRecords),
                            MusicSheetPurchaseRecord.class), 30);
                }
            }
        }

        // 更新课程关联曲目状态
        lambdaUpdate()
                .in(CourseRelationMusicAlbum::getId, giftIds)
                .set(CourseRelationMusicAlbum::getDelFlog, EStatus.ENABLE.getValue())
                .update();
    }


}