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.yonge.cooleshow.biz.dal.entity.Student;
import com.yonge.cooleshow.biz.dal.entity.Subject;
import com.yonge.cooleshow.biz.dal.entity.Teacher;
import com.yonge.cooleshow.biz.dal.entity.UserMusicStar;
import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
import com.yonge.cooleshow.biz.dal.mapper.UserMusicMapper;
import com.yonge.cooleshow.biz.dal.mapper.UserMusicStarMapper;
import com.yonge.cooleshow.biz.dal.service.*;
import com.yonge.cooleshow.biz.dal.wrapper.UserMusicStarWrapper;
import com.yonge.cooleshow.common.constant.SysConfigConstant;
import com.yonge.cooleshow.common.entity.HttpResponseResult;
import com.yonge.toolset.base.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户曲目作品点赞记录
 * 2023-10-30 14:59:53
 */
@Slf4j
@Service
public class UserMusicStarServiceImpl extends ServiceImpl<UserMusicStarMapper, UserMusicStar> implements UserMusicStarService {

    @Autowired
    private UserMusicMapper userMusicMapper;

    @Autowired
    private StudentService studentService;

    @Autowired
    private TeacherService teacherService;

    @Autowired
    private SubjectService subjectService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysConfigService sysConfigService;

    /**
     * 查询详情
     * @param id 详情ID
     * @return UserMusicStar
     */
    @Override
    public UserMusicStar detail(Long id) {

        return baseMapper.selectById(id);
    }

    /**
     * 分页查询
     * @param page IPage<UserMusicStar>
     * @param query UserMusicStarWrapper.UserMusicStarQuery
     * @return IPage<UserMusicStar>
     */
    @Override
    public IPage<UserMusicStarWrapper.UserMusicStar> selectPage(IPage<UserMusicStar> page, UserMusicStarWrapper.UserMusicStarQuery query) {

        IPage<UserMusicStar> pages = page.setRecords(baseMapper.selectPage(page, query));
        IPage<UserMusicStarWrapper.UserMusicStar> musicStarIPage = pages.convert(o -> JSON.parseObject(JSON.toJSONString(o), UserMusicStarWrapper.UserMusicStar.class));

        List<UserMusicStarWrapper.UserMusicStar> userMusicStars = musicStarIPage.getRecords();
        if (CollectionUtils.isEmpty(userMusicStars)){
            return musicStarIPage;
        }

        userMusicStars = JSON.parseArray(JSON.toJSONString(userMusicStars), UserMusicStarWrapper.UserMusicStar.class);

        // 学生ID集合
        List<Long> studentIds = userMusicStars.stream().filter(o -> o.getClientType() == ClientEnum.STUDENT)
            .map(UserMusicStarWrapper.UserMusicStar::getUserId).collect(Collectors.toList());

        Map<Long, Student> studentMap = studentService.getMapByIds(studentIds);


        // 老师ID集合
        List<Long> teacherIds = userMusicStars.stream().filter(o -> o.getClientType() == ClientEnum.TEACHER)
            .map(UserMusicStarWrapper.UserMusicStar::getUserId).collect(Collectors.toList());

        Map<Long, Teacher> teacherMap = teacherService.getMapByIds(teacherIds);
        studentIds.addAll(teacherIds);
        Map<Long, com.yonge.cooleshow.biz.dal.entity.SysUser> userMap = sysUserService.getMapByIds(studentIds);

        String teacherAvatar = sysConfigService.findConfigValue(SysConfigConstant.TEACHER_AVATAR);
        String studentAvatar = sysConfigService.findConfigValue(SysConfigConstant.STUDENT_AVATAR);
        for (UserMusicStarWrapper.UserMusicStar userMusicStar : userMusicStars) {

            com.yonge.cooleshow.biz.dal.entity.SysUser sysUser = userMap.get(userMusicStar.getUserId());
            if (sysUser != null) {
                userMusicStar.setUserName(sysUser.getUsername());
                userMusicStar.setUserAvatar(sysUser.getAvatar());
            }
            if (userMusicStar.getClientType() == ClientEnum.STUDENT) {
                Student student = studentMap.get(userMusicStar.getUserId());
                if (student != null) {
                    userMusicStar.setSubjectId(student.getSubjectId());
                }
                if (StringUtil.isEmpty(userMusicStar.getUserAvatar())) {
                    userMusicStar.setUserAvatar(studentAvatar);
                }
            } else {
                Teacher teacher = teacherMap.get(userMusicStar.getUserId());
                if (teacher != null) {
                    userMusicStar.setSubjectId(teacher.getSubjectId());
                }
                if (StringUtil.isEmpty(userMusicStar.getUserAvatar())) {
                    userMusicStar.setUserAvatar(teacherAvatar);
                }
            }
        }

        // 声部ID集合
        List<String> subjectIds = studentMap.values().stream().map(Student::getSubjectId).collect(Collectors.toList());
        subjectIds.addAll(teacherMap.values().stream().map(Teacher::getSubjectId).collect(Collectors.toList()));

        Map<Integer, Subject> subjectMap =
            subjectService.getMapByIds(subjectIds);

        for (UserMusicStarWrapper.UserMusicStar userMusicStar : userMusicStars) {


            if (StringUtil.isEmpty(userMusicStar.getSubjectId())) {
                continue;
            }
            if (StringUtils.isNotBlank(userMusicStar.getSubjectId())) {

                List<Integer> collect = Arrays.stream(userMusicStar.getSubjectId().split(",")).map(Integer::parseInt).collect(Collectors.toList());
                List<Subject> subjects = new ArrayList<>();
                for (Integer integer : collect) {
                    Subject subject = subjectMap.get(integer);
                    if (subject != null) {
                        subjects.add(subject);
                    }
                }
                userMusicStar.setSubjectName(subjects.stream().map(Subject::getName).collect(Collectors.joining(",")));

            }

        }
        return musicStarIPage.setRecords(userMusicStars);
    }

    /**
     * 添加
     * @param userMusicStar UserMusicStarWrapper.UserMusicStar
     * @return Boolean
     */
    @Override
    public Boolean add(UserMusicStarWrapper.UserMusicStar userMusicStar) {

        return this.save(JSON.parseObject(userMusicStar.jsonString(), UserMusicStar.class));
    }

    /**
     * 更新
     * @param userMusicStar UserMusicStarWrapper.UserMusicStar
     * @return Boolean
     */
    @Override
    public Boolean update(UserMusicStarWrapper.UserMusicStar userMusicStar){

        return this.updateById(JSON.parseObject(userMusicStar.jsonString(), UserMusicStar.class));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void star(UserMusicStarWrapper.Star star) {

        this.lambdaUpdate()
            .eq(UserMusicStar::getUserId, star.getUserId())
            .eq(UserMusicStar::getUserMusicId, star.getUserMusicId())
            .eq(UserMusicStar::getClientType, star.getClientType())
            .remove();

        if (star.getStar()) {
            UserMusicStar userMusicStar = new UserMusicStar();
            userMusicStar.setClientType(star.getClientType());
            userMusicStar.setUserId(star.getUserId());
            userMusicStar.setUserMusicId(star.getUserMusicId());
            this.save(userMusicStar);
        }
        userMusicMapper.updateStar(star.getUserMusicId());


    }

    @Override
    public Map<Long, Integer> getStarCountMapByUserMusicIds(List<Long> userMusicIds) {
        if (CollectionUtils.isEmpty(userMusicIds)) {
            return new HashMap<>();
        }
        List<UserMusicStarWrapper.StarCount> starCounts = baseMapper.getStarCountMapByUserMusicIds(userMusicIds);
        Map<Long, Integer> starCountMap = new HashMap<>();
        for (UserMusicStarWrapper.StarCount starCount : starCounts) {
            starCountMap.put(starCount.getUserMusicId(), starCount.getStarCount());
        }
        return starCountMap;
    }

    @Override
    public Map<Long, Boolean> getStarFlagMapByUserMusicIds(List<Long> userMusicIds, String clientType, String userId) {
        if (CollectionUtils.isEmpty(userMusicIds)) {
            return new HashMap<>();
        }
        if (StringUtil.isEmpty(clientType)) {
            return new HashMap<>();
        }
        if (StringUtil.isEmpty(userId)) {
            return new HashMap<>();
        }
        List<UserMusicStar> list = this.lambdaQuery()
            .eq(UserMusicStar::getClientType, clientType)
            .eq(UserMusicStar::getUserId, userId)
            .in(UserMusicStar::getUserMusicId, userMusicIds)
            .list();
        if (CollectionUtils.isEmpty(list)) {
            return new HashMap<>();
        }
        return list.stream().collect(Collectors.toMap(UserMusicStar::getUserMusicId, o->true, (k1, k2) -> k1));
    }
}
