package com.qmth.distributed.print.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmth.teachcloud.common.bean.dto.TaskPrintClassDto;
import com.qmth.teachcloud.common.bean.dto.excel.BasicStudentImportDto;
import com.qmth.teachcloud.common.bean.params.BasicStudentParams;
import com.qmth.teachcloud.common.bean.result.BasicStudentResult;
import com.qmth.teachcloud.common.entity.BasicClazz;
import com.qmth.teachcloud.common.entity.BasicStudent;
import com.qmth.teachcloud.common.mapper.BasicStudentMapper;
import com.qmth.teachcloud.common.service.BasicClazzService;
import com.qmth.teachcloud.common.service.BasicStudentService;
import com.qmth.teachcloud.common.bean.dto.excel.DescribeImportDto;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.SysUser;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.service.BasicCampusService;
import com.qmth.teachcloud.common.service.TeachcloudCommonService;
import com.qmth.teachcloud.common.util.ServletUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 学校id 服务实现类
 * </p>
 *
 * @author wangliang
 * @since 2021-08-02
 */
@Service
public class BasicStudentServiceImpl extends ServiceImpl<BasicStudentMapper, BasicStudent> implements BasicStudentService {
    @Resource
    private BasicStudentMapper basicStudentMapper;
    @Resource
    private TeachcloudCommonService teachcloudCommonService;
    @Resource
    private BasicCampusService basicCampusService;
    @Resource
    private BasicClazzService basicClazzService;

    @Override
    public IPage<BasicStudentResult> basicStudentPage(String queryParams,Long campusId, Set<Long> clazzIdList,int pageNumber, int pageSize) {
        Long schoolId = SystemConstant.convertIdToLong(ServletUtil.getRequestHeaderSchoolId().toString());
//        Set<Long> orgIds = teachcloudCommonService.listSubOrgIds(null);
        Set<Long> orgIds = null;
        queryParams = SystemConstant.translateSpecificSign(queryParams);
        return basicStudentMapper.findBasicStudentPage(new Page<>(pageNumber, pageSize), queryParams, schoolId,campusId, clazzIdList,orgIds);
    }

    @Override
    public IPage<BasicStudent> listPage(Page<BasicStudent> page, String classId) {
        List<String> classIds = Arrays.asList(classId.split(","));
        QueryWrapper<BasicStudent> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(BasicStudent::getClazzId, classIds).orderByAsc(BasicStudent::getClazzId, BasicStudent::getStudentCode);
        return this.baseMapper.selectPage(page, queryWrapper);
    }

    @Override
    public List<TaskPrintClassDto> listByClass(Long schoolId, Set<String> stringList) {
        return this.baseMapper.listByClass(schoolId, stringList);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long saveBasicStudent(BasicStudentParams basicStudentParams, SysUser sysUser) {
        List<BasicStudentParams> basicStudentParamsList = new ArrayList<>();
        basicStudentParamsList.add(basicStudentParams);
        BasicStudent basicStudent = this.editEntityHelp(basicStudentParamsList, sysUser).get(0);
        this.saveOrUpdate(basicStudent);
        return basicStudent.getId();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean removeBasicStudentBatch(List<Long> idList) {
        if (idList.size() == 0) {
            throw ExceptionResultEnum.ERROR.exception("请选择要删除的目标");
        }
        return this.remove(new QueryWrapper<BasicStudent>().lambda().in(BasicStudent::getId,idList));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Map<String, Object> executeBasicStudentImportLogic(List<LinkedMultiValueMap<Integer, Object>> finalList, Map<String, Object> map) {
        SysUser sysUser = (SysUser) map.get(SystemConstant.SYS_USER);
        Long schoolId = sysUser.getSchoolId();

        List<BasicStudentParams> addBasicStudentParamsList = new ArrayList<>();
        for (int i = 0; i < finalList.size(); i++) {
            LinkedMultiValueMap<Integer, Object> excelMap = finalList.get(i);
            List<Object> basicStudentImportDtoList = excelMap.get(i);

            assert basicStudentImportDtoList != null;
            if (basicStudentImportDtoList.get(0) instanceof DescribeImportDto){
                continue;
            }
            List<BasicStudentImportDto> datasource = basicStudentImportDtoList.stream().map(e -> {
                BasicStudentImportDto basicStudentImportDto = new BasicStudentImportDto();
                BeanUtils.copyProperties(e, basicStudentImportDto);
                return basicStudentImportDto;
            }).collect(Collectors.toList());
            map.put("dataCount", datasource.size());

            for (int y = 0; y < Objects.requireNonNull(basicStudentImportDtoList).size(); y++) {
                BasicStudentImportDto basicStudentImportDto = (BasicStudentImportDto) basicStudentImportDtoList.get(y);

                // 取值
                String studentName = basicStudentImportDto.getStudentName();
                String studentCode = basicStudentImportDto.getStudentCode();
                String phoneNumber = basicStudentImportDto.getPhoneNumber();
                String clazz = basicStudentImportDto.getClazz();
                BasicClazz basicClazz = basicClazzService.getOne(new QueryWrapper<BasicClazz>().lambda()
                        .eq(BasicClazz::getEnable,true)
                        .eq(BasicClazz::getClazzName,clazz)
                        .eq(BasicClazz::getSchoolId,schoolId));
                if (Objects.isNull(basicClazz)){
                    throw ExceptionResultEnum.ERROR.exception("【班级】" + clazz + "还没有构建");
                }


                BasicStudentParams basicStudentParams = new BasicStudentParams();
                basicStudentParams.setStudentName(studentName);
                basicStudentParams.setStudentCode(studentCode);
                basicStudentParams.setPhoneNumber(phoneNumber);
                basicStudentParams.setClazzId(basicClazz.getId());

                BasicStudent tmp = this.getOne(new QueryWrapper<BasicStudent>().lambda()
                        .eq(BasicStudent::getSchoolId, sysUser.getSchoolId())
                        .eq(BasicStudent::getEnable, true)
                        .eq(BasicStudent::getStudentCode, studentCode));
                if (Objects.nonNull(tmp)) {
                    basicStudentParams.setId(tmp.getId());
                }
                addBasicStudentParamsList.add(basicStudentParams);
            }

            List<BasicStudent> basicStudentList = this.editEntityHelp(addBasicStudentParamsList, sysUser);
            this.saveOrUpdateBatch(basicStudentList);
        }

        return map;
    }

    /**
     * 学生保存助手方法（应对学生保存和导入批量保存）
     *
     * @param basicStudentParamsList 学生参数
     * @param sysUser                操作人
     * @return 结果
     */
    private List<BasicStudent> editEntityHelp(List<BasicStudentParams> basicStudentParamsList, SysUser sysUser) {
        Long schoolId = sysUser.getSchoolId();
        List<BasicStudent> editEntityList = new ArrayList<>();
        for (BasicStudentParams basicStudentParams : basicStudentParamsList) {
            // 普通参数
            String studentName = basicStudentParams.getStudentName();
            String studentCode = basicStudentParams.getStudentCode();
            String phoneNumber = basicStudentParams.getPhoneNumber();
            Long clazzId = basicStudentParams.getClazzId();
            BasicClazz basicClazz = basicClazzService.getById(clazzId);
            if (Objects.isNull(basicClazz)) {
                throw ExceptionResultEnum.ERROR.exception("所选班级不存在");
            }

            Long campusId = basicClazz.getCampusId();
            Long id = basicStudentParams.getId();

            // 检验学号在学校的唯一性
            BasicStudent checkCode = this.getOne(new QueryWrapper<BasicStudent>().lambda()
                    .eq(BasicStudent::getSchoolId, schoolId)
                    .eq(BasicStudent::getStudentCode, studentCode)
                    .eq(BasicStudent::getEnable, true));
            if (Objects.nonNull(checkCode)) {
                if (!checkCode.getId().equals(id)) {
                    throw ExceptionResultEnum.ERROR.exception("学生编号【" + studentCode + "】重复");
                }
            }

            // 检验有值的电话在学校的唯一性
            if (SystemConstant.strNotNull(phoneNumber)){
                BasicStudent checkPhone = this.getOne(new QueryWrapper<BasicStudent>().lambda()
                        .eq(BasicStudent::getSchoolId, schoolId)
                        .eq(BasicStudent::getPhoneNumber, phoneNumber)
                        .eq(BasicStudent::getEnable, true));
                if (Objects.nonNull(checkPhone)) {
                    if (!checkPhone.getId().equals(id)) {
                        throw ExceptionResultEnum.ERROR.exception("学生电话【" + phoneNumber + "】重复");
                    }
                }
            }

            // 组装基础参数
            Long orgId;
            BasicStudent basicStudent = new BasicStudent();
            basicStudent.setStudentCode(studentCode);
            basicStudent.setStudentName(studentName);
            basicStudent.setPhoneNumber(phoneNumber);
            basicStudent.setCampusId(campusId);
            basicStudent.setClazzId(clazzId);
            basicStudent.setSchoolId(schoolId);

            // 保存
            if (!SystemConstant.longNotNull(id)) {
                // id为空 -> 新增
                // 获取分布式id
                orgId = sysUser.getOrgId();
                id = SystemConstant.getDbUuid();
                basicStudent.setId(id);

                basicStudent.setCreateId(sysUser.getId());
            } else {
                // id不为空 -> 更新
                BasicStudent old = this.getById(id);
                if (Objects.isNull(old) || old.getEnable().equals(false)) {
                    throw ExceptionResultEnum.ERROR.exception("学生主键不存在或被禁用");
                }
                orgId = old.getOrgId();
                basicStudent.setId(id);
                basicStudent.setUpdateId(sysUser.getId());
            }
            basicStudent.setOrgId(orgId);
            editEntityList.add(basicStudent);
        }
        return editEntityList;
    }
}
