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

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.yonge.cooleshow.biz.dal.entity.MusicCompareRecordStat;
import com.yonge.cooleshow.biz.dal.entity.MusicTag;
import com.yonge.cooleshow.biz.dal.enums.EQueryOp;
import com.yonge.cooleshow.biz.dal.enums.FeatureType;
import com.yonge.cooleshow.biz.dal.mapper.MusicCompareRecordStatMapper;
import com.yonge.cooleshow.biz.dal.service.MusicCompareRecordStatService;
import com.yonge.cooleshow.biz.dal.service.MusicTagService;
import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
import com.yonge.cooleshow.biz.dal.wrapper.music.MusicCompareWrapper;
import com.yonge.toolset.mybatis.support.PageUtil;
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.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 曲目练习统计表 服务实现类
 * </p>
 *
 * @author Eric
 * @since 2022-10-17
 */
@Service
public class MusicCompareRecordStatServiceImp extends ServiceImpl<MusicCompareRecordStatMapper, MusicCompareRecordStat> implements MusicCompareRecordStatService {

    @Autowired
    private MusicTagService musicTagService;

    /**
     * 曲目统计汇总信息
     *
     * @param sysUserId 用户ID
     * @param info      MusicCompareWrapper.StatQueryInfo
     * @return MusicCompareWrapper.RecordStat
     */
    @Override
    public MusicCompareWrapper.RecordStat findMusicCompareRecordStatInfo(Long sysUserId, MusicCompareWrapper.StatQueryInfo info) {

        // 统计汇总信息
        MusicCompareWrapper.RecordStat wrapper = MusicCompareWrapper.RecordStat.builder()
                .trainMusicNums(0L)
                .trainDuration(0L)
                .trainFrequency(0L)
                .evaluateMusicNums(0L)
                .evaluateDuration(0L)
                .evaluateFrequency(0L)
                .recordInfos(Lists.newArrayList())
                .build();

        // 指标统计信息
        Lists.newArrayList(EQueryOp.values()).parallelStream().forEach(dataType -> {


            MusicCompareWrapper.StatQueryInfo queryInfo = JSON.parseObject(info.jsonString(), MusicCompareWrapper.StatQueryInfo.class);

            switch (dataType) {
                case FUNCTION_1: // 练习曲目
                    {
                        List<StatGroupWrapper> groupWrappers = getBaseMapper().selectMusicCompareRecordStatInfo(queryInfo.trainMusic(true));

                        if (CollectionUtils.isNotEmpty(groupWrappers)) {

                            StatGroupWrapper groupWrapper = groupWrappers.get(0);

                            wrapper.trainMusicNums(groupWrapper.getMusicNum())
                                    .trainDuration(groupWrapper.getDurationNum() / 60)
                                    .trainFrequency(groupWrapper.getFrequencyNum());
                        }
                    }
                    break;
                case FUNCTION_2: // 评测曲目
                    {
                        List<StatGroupWrapper> groupWrappers = getBaseMapper().selectMusicCompareRecordStatInfo(queryInfo.evaluateMusic(true));

                        if (CollectionUtils.isNotEmpty(groupWrappers)) {

                            StatGroupWrapper groupWrapper = groupWrappers.get(0);

                            wrapper.evaluateMusicNums(groupWrapper.getMusicNum())
                                    .evaluateDuration(groupWrapper.getDurationNum() / 60)
                                    .evaluateFrequency(groupWrapper.getFrequencyNum());
                        }
                    }
                    break;
                default:
                    break;
            }
        });

        // 曲目统计信息
        IPage<MusicCompareWrapper.RecordInfo> page = findMusicCompareRecordPage(PageUtil.getPage(info), info);
        if (Objects.nonNull(page)) {

            wrapper.setRecordInfos(page.getRecords());
        }

        return wrapper;
    }

    /**
     * 曲目统计信息查询
     *
     * @param page  IPage<MusicCompareWrapper.RecordInfo>
     * @param query MusicCompareWrapper.StatQueryInfo
     * @return IPage<MusicCompareWrapper.RecordInfo>
     */
    @Override
    public IPage<MusicCompareWrapper.RecordInfo> findMusicCompareRecordPage(IPage<MusicCompareWrapper.RecordInfo> page, MusicCompareWrapper.StatQueryInfo query) {

        // 用户曲目统计信息
        List<MusicCompareWrapper.RecordInfo> recordInfos = getBaseMapper().selectMusicCompareRecordPage(page, query);

        if (CollectionUtils.isNotEmpty(recordInfos)) {

            List<String> collect = recordInfos.stream()
                    .filter(x -> StringUtils.isNotEmpty(x.getMusicTag()))
                    .flatMap(x -> Arrays.stream(x.getMusicTag().split(",")))
                    .distinct().collect(Collectors.toList());

            Map<Long, String> tagNameMap = musicTagService.lambdaQuery()
                    .eq(MusicTag::getType, "MUSIC")
                    .in(MusicTag::getId, collect)
                    .list().stream()
                    .collect(Collectors.toMap(MusicTag::getId, MusicTag::getName, (o, n) -> n));

            String tagName;
            for (MusicCompareWrapper.RecordInfo item : recordInfos) {

                if (StringUtils.isNotEmpty(item.getMusicTag())) {

                    List<Long> tagIds = Arrays.stream(item.getMusicTag().split(","))
                            .map(Long::parseLong).distinct().collect(Collectors.toList());

                    tagName = tagNameMap.entrySet().stream()
                            .filter(x -> tagIds.contains(x.getKey()))
                            .map(Map.Entry::getValue).collect(Collectors.joining(","));

                    item.setMusicTagName(tagName);
                }

                // 设置练习时长，评测时长
                item.trainDuration(item.getTrainDuration() / 60)
                        .evaluateDuration(item.getEvaluateDuration() / 60);
            }
        }

        return page.setRecords(recordInfos);
    }

    /**
     * 批量更新曲目统计汇总
     *
     * @param recordInfos List<MusicCompareWrapper.RecordInfo>
     */
    @Override
    public void batchUpdateMusicCompareRecordStat(List<MusicCompareWrapper.RecordInfo> recordInfos) {

        for (MusicCompareWrapper.RecordInfo record : recordInfos) {

            // 判断曲目统计消息是新增还是更新
            MusicCompareRecordStat musicRecord = lambdaQuery()
                    .eq(MusicCompareRecordStat::getMusicSheetId, record.getMusicSheetId())
                    .eq(MusicCompareRecordStat::getUserId, record.getUserId())
                    .eq(MusicCompareRecordStat::getClientId, record.getClientId())
                    .one();

            if (Objects.isNull(musicRecord)) {

                // 初始化数据默认值
                if (Objects.isNull(record.getTrainDuration())) {
                    record.setTrainDuration(0L);
                }
                if (Objects.isNull(record.getTrainFrequency())) {
                    record.setTrainFrequency(0L);
                }
                if (Objects.isNull(record.getEvaluateDuration())) {
                    record.setEvaluateDuration(0L);
                }
                if (Objects.isNull(record.getEvaluateFrequency())) {
                    record.setEvaluateFrequency(0L);
                }

                // 新增记录
                save(JSON.parseObject(record.jsonString(), MusicCompareRecordStat.class));
            } else {
                record.setId(musicRecord.getId());
                // 更新记录
                updateById(JSON.parseObject(record.jsonString(), MusicCompareRecordStat.class));
            }
        }
    }

    /**
     * 曲目评测记录查询
     *
     * @param page  MusicCompareWrapper.RecordEvaluate
     * @param query MusicCompareWrapper.EvaluteQueryInfo
     * @return IPage<MusicCompareWrapper.RecordEvaluate>
     */
    @Override
    public IPage<MusicCompareWrapper.RecordEvaluate> findMusicCompareRecordEvaluatePage(IPage<MusicCompareWrapper.RecordEvaluate> page,
                                                                                        MusicCompareWrapper.EvaluteQueryInfo query) {
        if (FeatureType.CLOUD_STUDY_EVALUATION == query.getFeature()) {

            // 只查询生成评测试报告数据
            query.setScoreData(true);
        }
        // 分页查询条件
        List<MusicCompareWrapper.RecordEvaluate> evaluates = getBaseMapper().selectMusicCompareEvaluatePage(page, query);

        return page.setRecords(evaluates);
    }
}
