package com.rongwei.trainingcommon.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rongwei.rwadmincommon.system.vo.SysUserVo;
import com.rongwei.rwcommon.base.BaseDo;
import com.rongwei.rwcommon.base.R;
import com.rongwei.rwcommon.utils.SecurityUtil;
import com.rongwei.rwcommon.utils.StringUtils;
import com.rongwei.safecommon.utils.JSCommonUtils;
import com.rongwei.training.domain.ExamPaperDo;
import com.rongwei.training.domain.PaperSubjectAssignDo;
import com.rongwei.training.domain.SubjectDo;
import com.rongwei.training.domain.SubjectOptionsDo;
import com.rongwei.trainingcommon.sys.dao.*;
import com.rongwei.trainingcommon.sys.service.SubjectOptionsService;
import com.rongwei.trainingcommon.sys.service.SubjectService;
import com.rongwei.trainingcommon.sys.utils.TrainingUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

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

import static com.rongwei.safecommon.utils.SaveConstans.TRAINING_SUBJECT_OPTION_OPTIONSCODE;
import static com.rongwei.safecommon.utils.SaveConstans.TRAINING_SUBJECT_TYPE_IMPOER;


@Service("subjectService")
public class SubjectServiceImpl extends ServiceImpl<SubjectDao, SubjectDo> implements SubjectService {

    private final Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    private PlanPaperDao planPaperDao;
    @Autowired
    private ExamPaperDao examPaperDao;
    @Autowired
    private PaperSubjectAssignDao paperSubjectAssignDao;
    @Autowired
    private PaperSubjectAutoDao paperSubjectAutoDao;
    @Autowired
    private SubjectService subjectService;

    @Autowired
    private SubjectOptionsService subjectOptionsService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R checkInfo(List<String> subjectIds) {
        /*******************************根据考题ID获取 分别获取作为固定考题和随机考题的试卷信息**************************/
        log.info("开始获取固定考题对应的试卷信息");
        List<PaperSubjectAssignDo> subjectAssignList = paperSubjectAssignDao.selectList(new QueryWrapper<PaperSubjectAssignDo>()
                .lambda().in(PaperSubjectAssignDo::getSubjectid, subjectIds).eq(BaseDo::getDeleted, "0"));
        log.info("获取固定考题对应的试卷信息结束,试卷信息 :{}", subjectAssignList);
        // 筛选出不在固定考题表中的 题目ID 删除
        List<String> toDeleteSubjectId = subjectIds.stream()
                .filter(subjectId -> !subjectAssignList.stream()
                        .map(PaperSubjectAssignDo::getSubjectid)
                        .collect(Collectors.toList())
                        .contains(subjectId)).collect(Collectors.toList());
        // 获取不到信息直接删除
        if (!toDeleteSubjectId.isEmpty()) {
            subjectService.update(new LambdaUpdateWrapper<SubjectDo>().in(SubjectDo::getId, toDeleteSubjectId).set(BaseDo::getDeleted, "1"));
            log.info("已删除考题: {}", toDeleteSubjectId);
        }
        // xiahan TODO: 2020/11/23 随机考题的信息无法获取
        // 根据考题ID+考题名称 进行分组
        Map<String, Set<String>> mapInfo = subjectAssignList.stream()
                .collect(Collectors.groupingBy(subjectAssignDo -> subjectAssignDo.getSubjectid() + ";" + subjectAssignDo.getSubjectname(),
                        Collectors.mapping(PaperSubjectAssignDo::getPaperid, Collectors.toSet())));
        // 返回的信息
        Map<String, List<String>> msgInfoMap = new HashMap<>();
        mapInfo.forEach((subjectId, paperIds) -> {
            // 获取试卷信息
            List<ExamPaperDo> examPaperDos = examPaperDao.selectList(new QueryWrapper<ExamPaperDo>().lambda()
                    .in(ExamPaperDo::getId, paperIds).eq(BaseDo::getDeleted, "0"));
            if (examPaperDos.isEmpty()) {
                subjectService.update(new LambdaUpdateWrapper<SubjectDo>().eq(SubjectDo::getId, subjectId.split(";")[0]).set(BaseDo::getDeleted, "1"));
            } else {
                msgInfoMap.put(subjectId.split(";")[1], examPaperDos.stream()
                        .map(ExamPaperDo::getExaminationname)
                        .distinct()
                        .collect(Collectors.toList()));
            }
        });
        if (msgInfoMap.isEmpty()) {
            return R.ok();
        }
        StringBuffer msg = new StringBuffer("所选考题: (");
        msg.append(String.join(",", msgInfoMap.keySet())).append(")");
        msg.append("已被试卷: (").append(msgInfoMap.values().stream().flatMap(Collection::stream).distinct().collect(Collectors.joining(",")));
        msg.append(")").append("使用,不可删除.");
        return R.errorWithMsg(msg.toString());
    }

    @Override
    public R importFile(MultipartFile multipartFile) {
        try {
            List<SubjectDo> subjectDoList =new ArrayList<>();
            SubjectDo subjectDo;
            List<SubjectOptionsDo> subjectOptionsDoList =new ArrayList<>();
            SubjectOptionsDo subjectOptionsDo;
            Date date = new Date();
            SysUserVo currentUser = TrainingUtils.getCurrentUser();
            Sheet sheet = new XSSFWorkbook(multipartFile.getInputStream()).getSheetAt(0);
            Row row ;
            int lastRowNum = sheet.getLastRowNum();
            for (int i=1;i<=lastRowNum;i++){
                //从第二行还是读取数据
                 row = sheet.getRow(i);

                 //主表
                subjectDo=new SubjectDo();
                subjectDo.setId(SecurityUtil.getUUID());
                subjectDo.setSubjecttype(TRAINING_SUBJECT_TYPE_IMPOER.getOrDefault(row.getCell(0).getStringCellValue(),"")); //考题类型
                subjectDo.setSubjectname( row.getCell(1).getStringCellValue());  //考题名称

                if (currentUser!=null){
                    subjectDo.setTenantid(TrainingUtils.getCurrentUserFactoryId(currentUser));
                    subjectDo.setCreateusername(currentUser.getName());
                    subjectDo.setCreateuserid(currentUser.getId());
                    subjectDo.setModifyusername(currentUser.getName());
                    subjectDo.setModifyuserid(currentUser.getId());
                }
                subjectDo.setCreatedate(date);
                subjectDo.setModifydate(date);
                subjectDoList.add(subjectDo);

                //子表
                Set<Integer> indexs = TRAINING_SUBJECT_OPTION_OPTIONSCODE.keySet();
                for (Integer index :indexs){
                    if (row.getCell(index)!=null){
                        subjectOptionsDo =new SubjectOptionsDo();
                        subjectOptionsDo.setId(SecurityUtil.getUUID());
                        subjectOptionsDo.setSubjectid(subjectDo.getId());
                        subjectOptionsDo.setOptionscode(TRAINING_SUBJECT_OPTION_OPTIONSCODE.get(index));  // 选项编号
                        subjectOptionsDo.setOptionsname(row.getCell(index).getStringCellValue());  //选项内容
                        subjectOptionsDo.setOptionsparsing(row.getCell(index+1)==null?"":row.getCell(index+1).toString());  //选项解析
                        subjectOptionsDo.setTrueoptions(getTrueoptionsBySubTpye(row.getCell(2).getStringCellValue(),subjectOptionsDo,subjectDo.getSubjecttype()));  //是否正确答案
                        subjectOptionsDo.setTenantid(subjectDo.getTenantid());
                        subjectOptionsDo.setCreatedate(date);
                        subjectOptionsDo.setModifydate(date);
                        if (currentUser!=null){
                        subjectOptionsDo.setCreateusername(currentUser.getName());
                        subjectOptionsDo.setCreateuserid(currentUser.getId());
                        subjectOptionsDo.setModifyusername(currentUser.getName());
                        subjectOptionsDo.setModifyuserid(currentUser.getId());
                        }

                        subjectOptionsDoList.add(subjectOptionsDo);
                    }
                }
            }

            if (subjectDoList.size()>0){
                subjectService.saveBatch(subjectDoList,100);
            }

            if (subjectOptionsDoList.size()>0){
                subjectOptionsService.saveBatch(subjectOptionsDoList,100);
            }

        } catch (Exception e) {
            log.error("导出失败：{} ",e.getMessage());
            R.error("考题导入异常");
        }
        return R.ok();
    }

    /**
     * 根据开题类型 判断考题选项是否正确答案
     * @param answer
     * @param subjectOptionsDo
     * @param subjecttype
     * @return
     */
    public String getTrueoptionsBySubTpye(String answer, SubjectOptionsDo subjectOptionsDo, String subjecttype){

        if (subjecttype.equals("30")) { //判断
            return subjectOptionsDo.getOptionsname().equals("对")?"y":"n";
        } else if (subjecttype.equals("20")) {  //多选
            return answer.indexOf(subjectOptionsDo.getOptionscode())>-1?"y":"n";
        }else if (subjecttype.equals("10")) {  //单选
            return answer.equals(subjectOptionsDo.getOptionscode())?"y":"n";
        }
        return null;
    }
}
