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

import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dayaedu.cbs.common.enums.EClientType;
import com.dayaedu.cbs.common.enums.school.ECourseType;
import com.dayaedu.cbs.openfeign.client.CoursewareFeignService;
import com.dayaedu.cbs.openfeign.wrapper.courseware.CbsCourseTypeWrapper;
import com.dayaedu.cbs.openfeign.wrapper.courseware.CbsLessonCoursewareWrapper;
import com.microsvc.toolkit.common.response.paging.PageInfo;
import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
import com.yonge.cooleshow.biz.dal.entity.*;
import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
import com.yonge.cooleshow.biz.dal.enums.SubjectTypeEnum;
import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMusicMapper;
import com.yonge.cooleshow.biz.dal.service.*;
import com.yonge.cooleshow.biz.dal.wrapper.LessonCoursewareWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumMusicWrapper;
import com.yonge.toolset.base.exception.BizException;
import lombok.extern.slf4j.Slf4j;
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 java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 机构专辑曲目
 * 2023-07-21 17:32:49
 */
@Slf4j
@Service
public class TenantAlbumMusicServiceImpl extends ServiceImpl<TenantAlbumMusicMapper, TenantAlbumMusic> implements TenantAlbumMusicService {


    @Autowired
    private UserTenantAlbumRecordService userTenantAlbumRecordService;

    @Autowired
    private MusicSheetService musicSheetService;

    @Autowired
    private SubjectService subjectService;

    @Autowired
    private MusicTagService musicTagService;

    @Autowired
    private TenantAlbumMusicMapper tenantAlbumMusicMapper;

    @Autowired
    private SysUserMapper sysUserMapper;


    @Autowired
    private TenantAlbumMusicService tenantAlbumMusicService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private MusicFavoriteService musicFavoriteService;

    @Autowired
    private  SysUserFeignService sysUserFeignService;

    @Autowired
    private TenantAlbumCategoryDetailService tenantAlbumCategoryDetailService;

    @Autowired
    private CoursewareFeignService coursewareFeignService;

    /**
     * 查询详情
     * @param id 详情ID
     * @return TenantAlbumMusic
     */
    @Override
    public TenantAlbumMusic detail(Long id) {
        
        return baseMapper.selectById(id);
    }
    
    /**
     * 分页查询
     * @param page IPage<TenantAlbumMusic>
     * @param query TenantAlbumMusicWrapper.TenantAlbumMusicQuery
     * @return IPage<TenantAlbumMusic>
     */
    @Override
    public IPage<TenantAlbumMusicWrapper.StudentTenantAlbumMusic> selectPage(IPage<TenantAlbumMusicWrapper.StudentTenantAlbumMusic> page,
                                                                             TenantAlbumMusicWrapper.StudentTenantAlbumMusicQuery query) {
        List<TenantAlbumMusicWrapper.StudentTenantAlbumMusic> musicSheets = new ArrayList<>();
        if (query.getSubjectType() != SubjectTypeEnum.COURSEWARE) {

            musicSheets = tenantAlbumMusicMapper.selectPage(page, query);
            if (CollectionUtils.isEmpty(musicSheets)) {
                return page.setRecords(musicSheets);
            }

            // 设置声部
            List<String> subjectIds = musicSheets.stream()
                .map(TenantAlbumMusicWrapper.StudentTenantAlbumMusic::getMusicSubject)
                .filter(Objects::nonNull)
                .flatMap(x -> Arrays.stream(x.split(",")))
                .distinct()
                .collect(Collectors.toList());
            Map<Integer, Subject> subjectMap = subjectService.getMapByIds(subjectIds);

            // 设置上传人
            List<Long> userIds = musicSheets.stream()
                .map(TenantAlbumMusicWrapper.StudentTenantAlbumMusic::getUserId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
            Map<Long, SysUser> userMap = sysUserService.getMapByIds(userIds);

            // 设置是否收藏
            List<Long> musicSheetIds = musicSheets.stream()
                .map(TenantAlbumMusicWrapper.StudentTenantAlbumMusic::getId)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());
            List<Long> favoriteIds = new ArrayList<>();
            if (query.getUserId() != null && query.getClientType() != null) {
                List<MusicFavorite> favoriteList = musicFavoriteService.lambdaQuery()
                    .in(MusicFavorite::getMusicSheetId, musicSheetIds)
                    .eq(MusicFavorite::getUserId, query.getUserId())
                    .eq(MusicFavorite::getClientType, query.getClientType().equals(ClientEnum.TENANT_STUDENT) ? ClientEnum.STUDENT : query.getClientType())
                    .list();
                favoriteIds = favoriteList.stream().map(MusicFavorite::getMusicSheetId).distinct().collect(Collectors.toList());

            }


            for (TenantAlbumMusicWrapper.StudentTenantAlbumMusic m : musicSheets) {
                if (StringUtils.isNotBlank(m.getMusicSubject())) {
                    String subjectNames = Arrays.stream(m.getMusicSubject().split(","))
                        .distinct()
                        .map(Integer::parseInt)
                        .map(subjectMap::get)
                        .filter(Objects::nonNull)
                        .map(Subject::getName)
                        .collect(Collectors.joining(","));
                    m.setMusicSubjectName(subjectNames);
                }
                SysUser sysUser = userMap.get(m.getUserId());
                if (sysUser != null) {
                    m.setUserName(sysUser.getUsername());
                }
                if (CollectionUtils.isNotEmpty(favoriteIds)) {
                    m.setFavorite(favoriteIds.contains(m.getId()));
                }
            }
        } else {
            // 查询专辑课件
            List<TenantAlbumMusic> list = tenantAlbumMusicService.lambdaQuery()
                .eq(TenantAlbumMusic::getTenantAlbumId, query.getAlbumId())
                .eq(TenantAlbumMusic::getSubjectType, SubjectTypeEnum.COURSEWARE)
                .eq(TenantAlbumMusic::getDelFlag, false)
                .orderByAsc(TenantAlbumMusic::getSortNumber)
                .list();
            if (CollectionUtils.isEmpty(list)) {
                return page.setRecords(musicSheets);
            }
            List<Long> coursewareIds = list.stream().map(TenantAlbumMusic::getMusicSheetId).collect(Collectors.toList());

            try {
                List<ECourseType> courseTypeList = courseTypeBySubject(query.getSubjectId());

                PageInfo<CbsLessonCoursewareWrapper.LessonCourseware> lessonCoursewarePageInfo = coursewareFeignService.lessonCoursewarePage(CbsLessonCoursewareWrapper.LessonCoursewareQuery.builder()
                    .page(query.getPage()).rows(query.getRows()).lessonCoursewareIds(coursewareIds).courseTypes(courseTypeList).keyword(query.getKeyword()).enableFlag(true)
                    .courseTypeCode(StringUtils.isNotBlank(query.getCourseTypeCode())?ECourseType.valueOf(query.getCourseTypeCode()):null).build()
                ).feignData();
                List<CbsLessonCoursewareWrapper.LessonCourseware> rows = lessonCoursewarePageInfo.getRows();
                if (CollectionUtils.isEmpty(rows)) {
                    return page.setRecords(musicSheets);
                }
                // 转map
                Map<Long, CbsLessonCoursewareWrapper.LessonCourseware> coursewareMap = rows.stream().collect(Collectors.toMap(CbsLessonCoursewareWrapper.LessonCourseware::getId, o -> o,(o1,o2)->o1));

                for (Long coursewareId : coursewareIds) {
                    CbsLessonCoursewareWrapper.LessonCourseware row = coursewareMap.get(coursewareId);
                    if (row == null) {
                        continue;
                    }
                    TenantAlbumMusicWrapper.StudentTenantAlbumMusic studentTenantAlbumMusic = new TenantAlbumMusicWrapper.StudentTenantAlbumMusic();
                    studentTenantAlbumMusic.setId(row.getId());
                    studentTenantAlbumMusic.setTenantAlbumId(query.getAlbumId());
                    studentTenantAlbumMusic.setMusicSheetName(row.getName());
                    studentTenantAlbumMusic.setTitleImg(row.getCoverImg());
                    studentTenantAlbumMusic.setMusicSubject(row.getCourseTypeCode());
                    studentTenantAlbumMusic.setMusicSubjectName(ECourseType.valueOf(row.getCourseTypeCode()).getName());
                    musicSheets.add(studentTenantAlbumMusic);

                }

                page.setRecords(musicSheets);
                page.setTotal(lessonCoursewarePageInfo.getTotal());
                return page;
            }catch (Exception e) {
                log.error("查询课件失败", e);
                throw new BizException("内容平台查询课件异常");
            }

        }
        return page.setRecords(musicSheets);
    }

    /**
     * 添加
     * @param tenantAlbumMusic TenantAlbumMusicWrapper.TenantAlbumMusic
     * @return Boolean
     */
    @Override
    public Boolean add(TenantAlbumMusicWrapper.TenantAlbumMusic tenantAlbumMusic) {

        return this.save(JSON.parseObject(tenantAlbumMusic.jsonString(), TenantAlbumMusic.class));
    }

    /**
     * 更新
     * @param tenantAlbumMusic TenantAlbumMusicWrapper.TenantAlbumMusic
     * @return Boolean
     */
    @Override
    public Boolean update(TenantAlbumMusicWrapper.TenantAlbumMusic tenantAlbumMusic){

        return this.updateById(JSON.parseObject(tenantAlbumMusic.jsonString(), TenantAlbumMusic.class));       
    }


    /**
     * 获取机构专辑曲目查询条件
     */
    @Override
    public TenantAlbumMusicWrapper.TenantAlbumMusicSelectData getTenantAlbumMusicQuery(TenantAlbumMusicWrapper.TenantAlbumMusicSelect query) {

        TenantAlbumMusicWrapper.TenantAlbumMusicSelectData data = new TenantAlbumMusicWrapper.TenantAlbumMusicSelectData();

        // 获取学生的专辑
        List<Long> albumIds = userTenantAlbumRecordService.getUseAlbumIdsByUserId(query.getUserId(), ClientEnum.STUDENT);
        if (CollectionUtils.isEmpty(albumIds)) {
            return data;
        }

        // 专辑曲目关联数据
        List<TenantAlbumMusic> list = tenantAlbumMusicMapper.getList(query,albumIds);
        if (CollectionUtils.isEmpty(list)) {
            return data;
        }

        List<Long> coursewareIds = list.stream().filter(o -> o.getSubjectType() == SubjectTypeEnum.COURSEWARE)
            .map(TenantAlbumMusic::getMusicSheetId).distinct().collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(coursewareIds) ) {
            CbsLessonCoursewareWrapper.LambdaQuery lambdaQuery = CbsLessonCoursewareWrapper.LambdaQuery.builder().ids(coursewareIds)
                .delFlag(false).enableFlag(true).build();
            List<CbsLessonCoursewareWrapper.Entity> entities = coursewareFeignService.lessonCoursewareLambdaQuery(lambdaQuery).feignData();

            List<ECourseType> courseTypeList = courseTypeBySubject(query.getSubjectId());
            List<String> courseTypes = entities.stream()
                .map(CbsLessonCoursewareWrapper.Entity::getCourseTypeCode)
                .filter(courseTypeCode -> courseTypeList.contains(ECourseType.valueOf(courseTypeCode)))
                .distinct().collect(Collectors.toList());
            data.setCourseTypeList(courseTypes);
        }

        List<Long> musicSheetIds = list.stream().filter(o -> o.getSubjectType() != SubjectTypeEnum.COURSEWARE)
            .map(TenantAlbumMusic::getMusicSheetId).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(musicSheetIds)) {
            return data;
        }

        Collection<MusicSheet> musicSheets = musicSheetService.listByIds(musicSheetIds);
        if (CollectionUtils.isEmpty(musicSheets)) {
            return data;
        }

        // 类型
        List<Long> typeIds =list.stream().map(TenantAlbumMusic::getType).distinct().filter(StringUtils::isNotBlank)
                .filter(NumberUtil::isNumber).map(Long::valueOf).collect(Collectors.toList());
        if (!typeIds.isEmpty()) {
            List<TenantAlbumCategoryDetail> typeList = tenantAlbumCategoryDetailService.lambdaQuery()
                    .in(TenantAlbumCategoryDetail::getId, typeIds).list();
            List<String> typeNameList = typeList.stream()
                    .map(TenantAlbumCategoryDetail::getValue).collect(Collectors.toList());
            data.setTypes(typeNameList);
            data.setTypeList(typeList);
        } else {
            data.setTypes(new ArrayList<>());
        }
        // 级别
        List<Long> levelIds =list.stream().map(TenantAlbumMusic::getLevel).distinct().filter(StringUtils::isNotBlank)
                .filter(NumberUtil::isNumber).map(Long::valueOf).collect(Collectors.toList());
        if (!levelIds.isEmpty()) {
            List<TenantAlbumCategoryDetail> levelList = tenantAlbumCategoryDetailService.lambdaQuery()
                    .in(TenantAlbumCategoryDetail::getId, levelIds).list();
            List<String> levelNameList = levelList.stream()
                    .map(TenantAlbumCategoryDetail::getValue).collect(Collectors.toList());
            data.setLevels(levelNameList);
            data.setLevelList(levelList);
        } else {
            data.setLevels(new ArrayList<>());
        }

        // 声部
        List<Long> subjectIds = musicSheets.stream()
                .map(MusicSheet::getMusicSubject)
                .filter(StringUtils::isNotBlank).distinct()
                .map(Long::parseLong).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(subjectIds)) {
            List<Subject> subjects = subjectService.findBySubjectByIdList(subjectIds);
            data.setSubjects(subjects);
        }

        // 标签
        List<Long> musicTagIds = musicSheets.stream().flatMap(o -> {
            if (StringUtils.isNotBlank(o.getMusicTag())) {
                return Arrays.stream(o.getMusicTag().split(","));
            }
            return Stream.empty();

        }).filter(StringUtils::isNotBlank).distinct().map(Long::parseLong).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(musicTagIds)) {

            List<MusicTag> tagList = musicTagService.listByIds(musicTagIds).parallelStream().collect(Collectors.toList());
            data.setTags(tagList);
        }
        data.setSubjects(new ArrayList<>());

        return data;

    }

    private List<ECourseType> courseTypeBySubject(Long subjectId) {
        List<ECourseType> courseTypeList = new ArrayList<>();

        // 有声部， 根据声部查询对应的课件类型
        List<CbsCourseTypeWrapper.CourseType> courseTypes = coursewareFeignService.courseTypeList().feignData();
        if (subjectId != null) {
            Subject subject = subjectService.get(subjectId);
            for (CbsCourseTypeWrapper.CourseType courseType : courseTypes) {
                if (StringUtils.isNotBlank(courseType.getSubjectIds()) ) {
                    if (subject !=null && subject.getCbsSubjectId() !=null) {
                        boolean contains = Arrays.asList(courseType.getSubjectIds().split(",")).contains(subject.getCbsSubjectId().toString());
                        if (contains) {
                            courseTypeList.add(ECourseType.valueOf(courseType.getTypeCode()));
                        }
                    }

                }  else {
                    courseTypeList.add(ECourseType.valueOf(courseType.getTypeCode()));
                }
            }
        }else {
            return courseTypes.stream().map(CbsCourseTypeWrapper.CourseType::getTypeCode).distinct()
                .map(ECourseType::valueOf).collect(Collectors.toList());
        }
        return courseTypeList;
    }

    @Override
    public List<Long> getTenantAlbumMusicIdsByIds(List<Long> tenantAlbumIds, List<SubjectTypeEnum> subjectTypes) {

        if (CollectionUtils.isEmpty(tenantAlbumIds)) {
            return Collections.emptyList();
        }
        List<TenantAlbumMusic> list = this.lambdaQuery()
            .in(TenantAlbumMusic::getTenantAlbumId, tenantAlbumIds)
            .in(CollectionUtils.isNotEmpty(subjectTypes),TenantAlbumMusic::getSubjectType,subjectTypes)
            .list();
        if (CollectionUtils.isEmpty(list)) {
            return Collections.emptyList();
        }
        return list.stream().map(TenantAlbumMusic::getMusicSheetId).collect(Collectors.toList());
    }

    @Override
    public List<Long> getMusicIdsByIds(List<Long> tenantAlbumIds) {

        return getTenantAlbumMusicIdsByIds(tenantAlbumIds,Arrays.asList(SubjectTypeEnum.MUSIC, SubjectTypeEnum.ENSEMBLE,SubjectTypeEnum.SUBJECT));
    }


    /**
     * 获取机构专辑曲目ID集合
     *
     * @param tenantId 机构ID
     */
    @Override
    public List<Long> getMusicIdsByTenantIds(Long tenantId) {
        return baseMapper.selectMusicIdsByTenantIds(tenantId);
    }

    @Override
    public LessonCoursewareWrapper.LessonCourseware getLessonCoursewareDetail(LessonCoursewareWrapper.LessonCourseQuery query) {
        CbsLessonCoursewareWrapper.LessonCourseware lessonCourseware = coursewareFeignService.lessonCoursewareDetail(query.getLessonCoursewareId()).feignData();
        if (lessonCourseware == null) {
            throw new BizException("课件不存在");
        }

        LessonCoursewareWrapper.LessonCourseware lessonCoursewareDto = JSON.parseObject(JSON.toJSONString(lessonCourseware), LessonCoursewareWrapper.LessonCourseware.class);
        lessonCoursewareDto.setPlay(false);

        if (query.getClient() == ClientEnum.STUDENT) {
            // 判断学生有咩有购买
            if (query.getAlbumId() != null) {
                UserTenantAlbumRecord albumRecord = userTenantAlbumRecordService.getNewestByTenantAlbumId(query.getAlbumId(), query.getUserId(), query.getClient());
                if (albumRecord != null && albumRecord.getEndTime().after(new Date())) {
                    lessonCoursewareDto.setPlay(true);
                }
            } else {
                List<Long> useAlbumIdsByUserId = userTenantAlbumRecordService.getUseAlbumIdsByUserId(query.getUserId(), query.getClient());
                if (CollectionUtils.isNotEmpty(useAlbumIdsByUserId)) {
                    List<Long> list = tenantAlbumMusicService.getTenantAlbumMusicIdsByIds(useAlbumIdsByUserId, Arrays.asList(SubjectTypeEnum.COURSEWARE));
                    if (list.contains(query.getLessonCoursewareId())) {
                        lessonCoursewareDto.setPlay(true);
                    }
                }
            }
        } else {
            lessonCoursewareDto.setPlay(true);
        }

        return lessonCoursewareDto;
    }
}