package cn.exploring.engine.server.db.service;

import cn.exploring.engine.server.db.dao.ClassInfoMapper;
import cn.exploring.engine.server.db.domain.ClassInfo;
import cn.exploring.engine.server.db.domain.ClassInfoExample;
import cn.exploring.engine.server.db.domain.StudentInfo;
import cn.exploring.engine.server.db.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class ClassService {

    @Resource
    ClassInfoMapper classInfoMapper;

    @Resource
    private StudentInfoService studentInfoService;

    public Map<Integer, String> getClassNameMap() {
        ClassInfoExample example = new ClassInfoExample();
        ClassInfoExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false);
        List<ClassInfo> dataList = classInfoMapper.selectByExample(example);
        return dataList.stream().map(x -> {
            Map oneData = new HashMap();
            oneData.put(x.getId(), x.getClassName());
            return oneData;
        }).reduce(new HashMap(), (x, y) -> {
            x.putAll(y);
            return x;
        });
    }

    public List<ClassInfo> selectClass(String className, List<Integer> idList) {
        ClassInfoExample example = new ClassInfoExample();
        ClassInfoExample.Criteria criteria = example.createCriteria();
        if (idList != null && idList.size() > 0) {
            criteria.andIdIn(idList);
        }
        if (!StringUtils.isEmpty(className)) {
            criteria.andClassNameEqualTo(className);
        }
        criteria.andDeletedEqualTo(false);
        return classInfoMapper.selectByExample(example);
    }

    public Map webSelectClass(String className,  Integer page, Integer limit, String sort, String order) {
        ClassInfoExample example = new ClassInfoExample();
        ClassInfoExample.Criteria criteria = example.createCriteria();

        criteria.andDeletedEqualTo(false);
        if (!StringUtils.isEmpty(className)) {
            criteria.andClassNameLike("%" + className + "%");
        }
        PageHelper.startPage(page, limit);
        example.setOrderByClause(sort + " "  + order);
        List<ClassInfo> dataList =  classInfoMapper.selectByExample(example);
        Long total = PageInfo.of(dataList).getTotal();
        return new HashMap(){{
            put("total", total);
            put("items", dataList);
        }};
    }

    /**
     * 添加班级信息
     * @param className
     * @return
     */
    public String addClassInfo(String className) {
        List<ClassInfo> classInfoList = selectClass(className, null);
        if (classInfoList != null && classInfoList.size() != 0) {
            return "当前已存在该班级";
        }
        ClassInfo classInfo = new ClassInfo();
        LocalDateTime now = LocalDateTime.now();
        classInfo.setAddTime(now);
        classInfo.setUpdateTime(now);
        classInfo.setDeleted(false);
        classInfo.setClassName(className);
        classInfoMapper.insertSelective(classInfo);
        return null;
    }

    public void updateClassInfo(ClassInfo classInfo) {
        LocalDateTime now = LocalDateTime.now();
        classInfo.setUpdateTime(now);
        classInfoMapper.updateByPrimaryKey(classInfo);
    }

    public String batchDeletedData(List<Integer> idList) {
        List<ClassInfo> classInfoList = selectClass(null, idList);
        Map<Integer, String> classNameMap = classInfoList.stream().collect(Collectors.toMap(ClassInfo::getId, ClassInfo::getClassName));
        Map<Integer, List<StudentInfo>> classStudentMap = studentInfoService.selectStudentByClassIdListGroupByClassId(idList);
        if (!CollectionUtils.isEmpty(classStudentMap) && classStudentMap.values().stream().anyMatch(list -> !CollectionUtils.isEmpty(list))) {
            return classStudentMap.entrySet().stream().filter(entry -> !CollectionUtils.isEmpty(entry.getValue()))
                    .map(entry -> StrUtil.format("班级[{}]存在{}名学生无法删除", classNameMap.get(entry.getKey()), entry.getValue().size()))
                    .collect(Collectors.joining(", "));
        }

        classInfoList.forEach(x -> {
            x.setDeleted(null);
            updateClassInfo(x);
        });
        return null;
    }

    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public List<ClassInfo> listAll() {
        return classInfoMapper.selectByExample(new ClassInfoExample().createCriteria()
                        .andDeletedEqualTo(ClassInfo.NOT_DELETED)
                .example());
    }

    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public ClassInfo selectByPrimaryKey(Integer id) {
        return Objects.isNull(id) ? null
                : classInfoMapper.selectByExample(new ClassInfoExample().createCriteria()
                                .andDeletedEqualTo(ClassInfo.NOT_DELETED)
                                .andIdEqualTo(id)
                        .example()).stream().findFirst().orElse(null);
    }

}
