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.dao.UserOrderDao;
import com.yonge.cooleshow.biz.dal.entity.Student;
import com.yonge.cooleshow.biz.dal.entity.Teacher;
import com.yonge.cooleshow.biz.dal.entity.TenantAlbum;
import com.yonge.cooleshow.biz.dal.entity.TenantAlbumMusic;
import com.yonge.cooleshow.biz.dal.entity.TenantGroupAlbum;
import com.yonge.cooleshow.biz.dal.entity.TenantStaff;
import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
import com.yonge.cooleshow.biz.dal.enums.SubjectTypeEnum;
import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMusicMapper;
import com.yonge.cooleshow.biz.dal.mapper.TenantGroupAlbumMapper;
import com.yonge.cooleshow.biz.dal.service.StudentService;
import com.yonge.cooleshow.biz.dal.service.TeacherService;
import com.yonge.cooleshow.biz.dal.service.TenantAlbumService;
import com.yonge.cooleshow.biz.dal.service.TenantGroupAlbumService;
import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
import com.yonge.cooleshow.biz.dal.wrapper.TenantGroupAlbumWrapper;
import com.yonge.toolset.base.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 机构小组专辑配置表
 * 2024-01-24 13:32:00
 */
@Slf4j
@Service
public class TenantGroupAlbumServiceImpl extends ServiceImpl<TenantGroupAlbumMapper, TenantGroupAlbum> implements TenantGroupAlbumService {

    @Autowired
    private StudentService studentService;

    @Autowired
    private TenantStaffService tenantStaffService;

    @Autowired
    private UserOrderDao userOrderDao;

    @Autowired
    private TenantAlbumMusicMapper tenantAlbumMusicMapper;

    @Autowired
    private TeacherService teacherService;

    @Autowired
    private TenantAlbumService tenantAlbumService;

	/**
     * 查询详情
     * @param id 详情ID
     * @return TenantGroupAlbum
     */
	@Override
    public TenantGroupAlbum detail(Long id) {
        
        return baseMapper.selectById(id);
    }
    
    /**
     * 分页查询
     * @param page IPage<TenantGroupAlbum>
     * @param query TenantGroupAlbumWrapper.TenantGroupAlbumQuery
     * @return IPage<TenantGroupAlbum>
     */
    @Override
    public IPage<TenantGroupAlbumWrapper.TenantGroupAlbumVo> selectPage(IPage<TenantGroupAlbumWrapper.TenantGroupAlbumVo> page, TenantGroupAlbumWrapper.TenantGroupAlbumQuery query) {
        
        return page.setRecords(baseMapper.selectPage(page, query));
    }
	
    /**
     * 添加
     * @param tenantGroupAlbum TenantGroupAlbumWrapper.TenantGroupAlbum
     * @return Boolean
     */
    @Override
    public Boolean add(TenantGroupAlbumWrapper.TenantGroupAlbum tenantGroupAlbum) {    	
        
        return this.save(JSON.parseObject(tenantGroupAlbum.jsonString(), TenantGroupAlbum.class));
    }

    /**
     * 更新
     * @param tenantGroupAlbum TenantGroupAlbumWrapper.TenantGroupAlbum
     * @return Boolean
     */
    @Override
    public Boolean update(TenantGroupAlbumWrapper.TenantGroupAlbum tenantGroupAlbum){

        return this.updateById(JSON.parseObject(tenantGroupAlbum.jsonString(), TenantGroupAlbum.class));       
    }

    @Override
    public List<TenantGroupAlbumWrapper.BuyTenantAlbum> buyAlbumInfo(Long tenantGroupAlbumId, Long userId, ClientEnum clientType) {
        // 学生端 查看小组专辑 获取专辑基本信息， 机构端查看机构专辑 获取专辑基本信息

        TenantGroupAlbumWrapper.BuyTenantAlbumQuery query = new TenantGroupAlbumWrapper.BuyTenantAlbumQuery();
        query.setTenantGroupAlbumId(tenantGroupAlbumId);
        if (tenantGroupAlbumId != null) {} else if (clientType == ClientEnum.STUDENT) {
            Student student = studentService.getById(userId);
            if (student.getTenantId() == null || student.getTenantId() <=0 || student.getTenantGroupId() == null) {
                throw new BizException("学生未加入机构或者小组");
            }
            query.setTenantId(student.getTenantId());
            query.setTenantGroupId(student.getTenantGroupId());
        } else if (clientType == ClientEnum.TENANT) {
            TenantStaff tenantStaff = tenantStaffService.getByUserId(userId);
            if(tenantStaff == null || tenantStaff.getTenantId() == null) {
                throw new BizException("机构员工不存在");
            }
            query.setTenantId(tenantStaff.getTenantId());
        }else if (clientType == ClientEnum.TEACHER) {
            Teacher teacher = teacherService.getById(userId);
            if(teacher == null || teacher.getTenantId() == null) {
                throw new BizException("老师机构信息不存在");
            }
            query.setTenantId(teacher.getTenantId());
        } else {
            throw new BizException("客户端类型错误");
        }

        List<TenantGroupAlbumWrapper.BuyTenantAlbum> buyAlbumInfo = baseMapper.getBuyAlbumInfo(query);
        if (CollectionUtils.isEmpty(buyAlbumInfo)) {
            return buyAlbumInfo;
        }
        // 查询专辑可用的分类的曲目数量
        // 机构专辑ID集合
        List<Long> tenantAlbumIds = buyAlbumInfo.stream().map(TenantGroupAlbumWrapper.BuyTenantAlbum::getId).collect(Collectors.toList());

        List<TenantAlbumMusic> list = tenantAlbumMusicMapper.getByAlbumAndEnable(tenantAlbumIds);
        // 根据专辑ID分组 在根据声部分类 分组
        Map<Long, Map<SubjectTypeEnum, Long>> map = list.stream()
            .collect(Collectors.groupingBy(TenantAlbumMusic::getTenantAlbumId, Collectors.groupingBy(TenantAlbumMusic::getSubjectType,Collectors.counting())));

        for (TenantGroupAlbumWrapper.BuyTenantAlbum buyTenantAlbum : buyAlbumInfo) {
            Map<SubjectTypeEnum, Long> subjectTypeEnumLongMap = map.get(buyTenantAlbum.getId());
            if (subjectTypeEnumLongMap != null) {
                buyTenantAlbum.setMusicCounts(subjectTypeEnumLongMap.getOrDefault(SubjectTypeEnum.MUSIC,0L).intValue());
                buyTenantAlbum.setEnsembleCounts(subjectTypeEnumLongMap.getOrDefault(SubjectTypeEnum.ENSEMBLE,0L).intValue());
                buyTenantAlbum.setSubjectCounts(subjectTypeEnumLongMap.getOrDefault(SubjectTypeEnum.SUBJECT,0L).intValue());
            } else {
                buyTenantAlbum.setMusicCounts(0);
                buyTenantAlbum.setEnsembleCounts(0);
                buyTenantAlbum.setSubjectCounts(0);
            }
            buyTenantAlbum.setMusicNum(buyTenantAlbum.getMusicCounts() + buyTenantAlbum.getEnsembleCounts()+buyTenantAlbum.getSubjectCounts());
        }

        // 如果学生购买 判断购买次数
        if (clientType == ClientEnum.STUDENT) {
            // 曲目ID集合
            List<Long> tenantGroupAlbumIds = buyAlbumInfo.stream().map(TenantGroupAlbumWrapper.BuyTenantAlbum::getTenantGroupAlbumId).collect(Collectors.toList());
            List<Long> studentTenantAlbumNum = userOrderDao.getStudentTenantAlbumNum(userId, tenantGroupAlbumIds);
            for (TenantGroupAlbumWrapper.BuyTenantAlbum item : buyAlbumInfo) {
                item.setBuyedTimes((int) studentTenantAlbumNum.stream().filter(x -> x.equals(item.getTenantGroupAlbumId())).count());
                if (item.getBuyedTimes() > item.getBuyTimes()) {
                    item.setBuyedTimes(item.getBuyTimes());
                }
            }
        }

        return buyAlbumInfo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateStatus(TenantGroupAlbumWrapper.UpdateStatus updateStatus) {
        List<Long> ids = Arrays.stream(updateStatus.getIds().split(",")).map(Long::valueOf).collect(Collectors.toList());
        List<TenantGroupAlbum> tenantGroupAlbumList = this.lambdaQuery().in(TenantGroupAlbum::getId, ids).list();
        if (CollectionUtils.isEmpty(tenantGroupAlbumList)) {
            return;
        }
        List<Long> tenantAlbumIds = tenantGroupAlbumList.stream().map(TenantGroupAlbum::getTenantAlbumId).distinct().collect(Collectors.toList());
        List<TenantAlbum> list = tenantAlbumService.lambdaQuery()
                .in(TenantAlbum::getId, tenantAlbumIds)
                .eq(TenantAlbum::getDelFlag, false)
                .list();
        if (list.stream().anyMatch(next -> Boolean.FALSE.equals(next.getStatus()))) {
            throw new BizException("专辑已经停用");
        }
        this.lambdaUpdate()
                .set(TenantGroupAlbum::getStatus, updateStatus.getStatus())
                .in(TenantGroupAlbum::getId, ids)
                .update();
    }
}