package com.ssj.service.sys.template;

import com.alibaba.dubbo.config.annotation.Service;
import com.ssj.bean.sys.compositioncomment.domain.CompositionComment;
import com.ssj.bean.sys.template.CommentTemplate;
import com.ssj.dao.sys.template.CommentTemplateDao;
import com.ssj.enums.CompositionTypeEnum;
import com.ssj.framework.core.common.service.BaseServiceImpl;
import com.ssj.framework.core.persistence.DynamicSpecifications;
import com.ssj.framework.core.persistence.SearchFilter;
import com.ssj.framework.core.util.StringUtil;
import com.ssj.service.kmt.dto.CompositionCommentDto;
import com.ssj.service.kmt.dto.CompositionCommentLevelDto;
import com.ssj.service.kmt.dto.CompositionCommentModuleDto;
import com.ssj.service.kmt.dto.CompositionCommentTypeDto;
import com.ssj.service.kmt.request.CompositionDetailRequest;
import com.ssj.service.mapper.CommentTemplateMapper;
import com.ssj.service.sys.compositioncomment.service.CompositionCommentService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @author Mount Liu
 * @date 2019/8/13
 */
@Service(version = "1.0")
@Transactional
public class CommentTemplateServiceImpl extends BaseServiceImpl<CommentTemplate, String> implements CommentTemplateService {

    @Autowired
    private CommentTemplateDao dao;

    @Autowired
    private CompositionCommentService compositionCommentService;

    @Autowired
    private CommentTemplateMapper commentTemplateMapper;

    @Override
    public PagingAndSortingRepository<CommentTemplate, String> getDao() {
        return dao;
    }


    @Override
    public Page<CommentTemplate> findByPage(Map<String, Object> params, Pageable sp) {
        Map<String, SearchFilter> filters = SearchFilter.parse(params);
        Specification<CommentTemplate> specification = DynamicSpecifications.bySearchFilter(filters.values(), CommentTemplate.class);
        return  dao.findAll(specification,sp);
    }


    public List<CompositionCommentTypeDto> findAllCommentTemplateGroup(String grade, String homeworkPictureId){
        List<CompositionComment> selectedCompositionCommentList = null;
        if (StringUtils.isNotBlank(homeworkPictureId)) {
             selectedCompositionCommentList = compositionCommentService.findByHomeworkPictureId(homeworkPictureId);
        }
        List<CommentTemplate> list = dao.findByGradeOrderBySort(grade);
        List<CompositionCommentTypeDto> compositionCommentTypeDtoList = new LinkedList<>();
        List<CompositionComment> finalSelectedCompositionCommentList = selectedCompositionCommentList;
        list.stream()
                .collect(Collectors.groupingBy(CommentTemplate::getType, LinkedHashMap::new, Collectors.toList()))
                .forEach((type, compositionCommentModuleList) -> {
                    CompositionCommentTypeDto compositionCommentTypeDto = new CompositionCommentTypeDto();
                    compositionCommentTypeDto.setTypeName(CompositionTypeEnum.getDescriptionByCode(type));
                    List<CompositionCommentModuleDto> compositionCommentModuleDtoList = new LinkedList<>();
                    compositionCommentModuleList.stream()
                            .collect(Collectors.groupingBy(CommentTemplate::getModule, LinkedHashMap::new, Collectors.toList()))
                            .forEach((module, compositionCommentLevelList) -> {
                                CompositionCommentModuleDto compositionCommentModuleDTO = new CompositionCommentModuleDto();
                                compositionCommentModuleDTO.setCompositionCommentModule(module);
                                List<CompositionCommentLevelDto> compositionCommentLevelDtoList = new LinkedList<>();
                                compositionCommentLevelList.stream()
                                        .collect(Collectors.groupingBy(CommentTemplate::getRank, LinkedHashMap::new, Collectors.toList()))
                                        .forEach((level, compositionCommentList) -> {
                                            CompositionCommentLevelDto compositionCommentLevelDto = new CompositionCommentLevelDto();
                                            compositionCommentLevelDto.setLevel(level);
                                            List<CompositionCommentDto> compositionCommentDtoList = new LinkedList<>();
                                            compositionCommentList.forEach(commentTemplate -> {
                                                CompositionCommentDto compositionCommentDto = new CompositionCommentDto();
                                                compositionCommentDto.setCompositionCommentId(commentTemplate.getId());
                                                compositionCommentDto.setCompositionComment(commentTemplate.getComment());
                                                if (CollectionUtils.isNotEmpty(finalSelectedCompositionCommentList)) {
                                                    boolean selected = finalSelectedCompositionCommentList.stream()
                                                            .anyMatch(it -> Objects.equals(it.getCommentTemplateId(), commentTemplate.getId()));
                                                    compositionCommentDto.setSelected(selected ? 1 : 0);
                                                }
                                                compositionCommentDtoList.add(compositionCommentDto);
                                            });
                                            compositionCommentLevelDto.setCompositionCommentList(compositionCommentDtoList);
                                            compositionCommentLevelDtoList.add(compositionCommentLevelDto);
                                        });
                                compositionCommentModuleDTO.setCompositionCommentLevelList(compositionCommentLevelDtoList);
                                compositionCommentModuleDtoList.add(compositionCommentModuleDTO);
                            });
                    compositionCommentTypeDto.setCompositionCommentModuleList(compositionCommentModuleDtoList);
                    compositionCommentTypeDtoList.add(compositionCommentTypeDto);
                });

        return compositionCommentTypeDtoList;
    }

    @Override
    public List<CommentTemplate> findByIds(List<String> ids) {
        return dao.findByIdIn(ids);
    }

    @Override
    public List<CommentTemplate> findByHomeworkPictureId(String homeworkPictureId) {
        return dao.findByHomeworkPictureId(homeworkPictureId);
    }

    @Override
    public List<CompositionCommentTypeDto> findTypeNameAndModule(String grade, String homeworkPictureId) {
        List<CommentTemplate> list = commentTemplateMapper.findCommentTypeAndModuleByGrade(grade);
        List<CompositionCommentTypeDto> compositionCommentTypeDtoList = new LinkedList<>();
        if (CollectionUtils.isNotEmpty(list)){
            boolean needCountSelectedCompositionComment = false;
            if (StringUtils.isNotBlank(homeworkPictureId)) {
                needCountSelectedCompositionComment = true;
            }
            boolean finalNeedCountSelectedCompositionComment = needCountSelectedCompositionComment;
            list.stream()
                    .collect(Collectors.groupingBy(CommentTemplate::getType, LinkedHashMap::new, Collectors.toList()))
                    .forEach((type, compositionCommentModuleList) -> {
                        CompositionCommentTypeDto compositionCommentTypeDto = new CompositionCommentTypeDto();
                        compositionCommentTypeDto.setTypeName(CompositionTypeEnum.getDescriptionByCode(type));
                        List<CompositionCommentModuleDto> compositionCommentModuleDtoList = new LinkedList<>();
                        compositionCommentModuleList
                                .forEach((template) -> {
                                    CompositionCommentModuleDto compositionCommentModuleDTO = new CompositionCommentModuleDto();
                                    compositionCommentModuleDTO.setCompositionCommentModule(template.getModule());
                                    if (finalNeedCountSelectedCompositionComment) {
                                        int selectedCompositionCommentCount =
                                                commentTemplateMapper.countSelectedCompositionComment(homeworkPictureId,
                                                        compositionCommentModuleDTO.getCompositionCommentModule());
                                        compositionCommentModuleDTO.setSelectedCount(selectedCompositionCommentCount);
                                    }
                                    compositionCommentModuleDtoList.add(compositionCommentModuleDTO);
                                });
                        compositionCommentTypeDto.setCompositionCommentModuleList(compositionCommentModuleDtoList);
                        compositionCommentTypeDtoList.add(compositionCommentTypeDto);
                    });
        }
        return compositionCommentTypeDtoList;
    }

    @Override
    public List<CompositionCommentLevelDto> findCommentDetailByTypeAndModule(CompositionDetailRequest request) {
        int type = StringUtil.isBlank(request.getTypeName()) ? -1 : CompositionTypeEnum.getCodeByDescription(request.getTypeName());
        List<CommentTemplate> list = commentTemplateMapper.findCommentDetailByTypeAndModule(request.getGrade(),
                request.getHomeworkPictureId(), request.getCompositionCommentModule(), type);

        List<CompositionCommentLevelDto> compositionCommentLevelDtoList = new LinkedList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            list.stream()
                    .collect(Collectors.groupingBy(CommentTemplate::getRank, LinkedHashMap::new, Collectors.toList()))
                    .forEach((level, compositionCommentList) -> {
                        CompositionCommentLevelDto compositionCommentLevelDto = new CompositionCommentLevelDto();
                        compositionCommentLevelDto.setLevel(level);
                        List<CompositionCommentDto> compositionCommentDtoList = new LinkedList<>();
                        compositionCommentList.forEach(commentTemplate -> {
                            CompositionCommentDto compositionCommentDto = new CompositionCommentDto();
                            compositionCommentDto.setCompositionCommentId(commentTemplate.getId());
                            compositionCommentDto.setCompositionComment(commentTemplate.getComment());
                            compositionCommentDto.setSelected(commentTemplate.getType());
                            compositionCommentDtoList.add(compositionCommentDto);
                        });
                        compositionCommentLevelDto.setCompositionCommentList(compositionCommentDtoList);
                        compositionCommentLevelDtoList.add(compositionCommentLevelDto);
                    });
        }
        return compositionCommentLevelDtoList;
    }
}
