package com.ruoyi.syzy.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.ruoyi.syzy.domain.*;
import com.ruoyi.syzy.mapper.*;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.sign.Md5Utils;
import com.ruoyi.syzy.service.IBBusiMbtiRecordsService;

/**
 * MBTI测评记录Service业务层处理
 * 
 * @author mingxue
 * @date 2021-08-15
 */
@Service
public class BBusiMbtiRecordsServiceImpl implements IBBusiMbtiRecordsService {
    @Autowired
    private BBusiMbtiStepsMapper stepsMapper;
    @Autowired
    private BBusiMbtiQuestionsMapper questionsMapper;
    @Autowired
    private BBusiMbtiRulesMapper rulesMapper;
    @Autowired
    private BBusiMbtiRecordsMapper recordsMapper;
    @Autowired
    private BBusiMbtiRecordDetailsMapper recordDetailsMapper;
    @Autowired
    private BBusiMbtiMajorMapper mbtiMajorMapper;

    /**
     * 查询MBTI测评记录
     * 
     * @param id MBTI测评记录ID
     * @return MBTI测评记录
     */
    @Override
    public BBusiMbtiRecords selectBBusiMbtiRecordsById(Long id) {
        return recordsMapper.selectBBusiMbtiRecordsById(id);
    }


    @Override
    public List<BBusiMbtiMajor> major(String code) {
        BBusiMbtiRecords exam = new BBusiMbtiRecords();
        exam.setCode(code);
        BBusiMbtiRecords res = recordsMapper.selectBBusiMbtiRecordsList(exam).stream().findFirst().orElse(null);
        if (null != res) {
            return majors(res.getRuleCode());
        }
        return Lists.newArrayList();
    }

    @Override
    public List<BBusiMbtiMajor> majors(String ruleCode) {
        List<BBusiMbtiMajor> categoryList = Lists.newArrayList();
        BBusiMbtiMajor cond = new BBusiMbtiMajor();
        cond.setCode(ruleCode);
        Map<String, BBusiMbtiMajor> categoryMap = Maps.newHashMap();
        mbtiMajorMapper.selectBBusiMbtiMajorList(cond).forEach(t -> {
            BBusiMbtiMajor category = categoryMap.get(t.getCategory());
            if (null == category) {
                category = new BBusiMbtiMajor();
                category.setCategory(t.getCategory());
                category.setMajors(Lists.newArrayList());
                categoryList.add(category);
                categoryMap.put(t.getCategory(), category);
            }
            t.setCode(null);
            t.setCategory(null);
            category.getMajors().add(t);
        });
        return categoryList;
    }

    @Override
    public BBusiMbtiRecords info(String code) {
        BBusiMbtiRecords exam = new BBusiMbtiRecords();
        exam.setCode(code);
        BBusiMbtiRecords res = recordsMapper.selectBBusiMbtiRecordsList(exam).stream().findFirst().orElse(null);
        if (null != res) {
            res.setRule(getRuleByCode(res.getRuleCode()));
            res.setDetails(listDetailByRecord(code));
        }
        return res;
    }

    private BBusiMbtiRules getRuleByCode(String ruleCode) {
        BBusiMbtiRules exam = new BBusiMbtiRules();
        exam.setCode(ruleCode);
        exam.setStatus(1);
        BBusiMbtiRules rule = rulesMapper.selectBBusiMbtiRulesList(exam).stream().findFirst().orElse(null);
        if (null == rule && ruleCode.length() != 1) {
            return getRuleByCode(ruleCode.substring(0, 1));
        } else {
            return rule;
        }
    }

    private List<BBusiMbtiRecordDetails> listDetailByRecord(String recordCode) {
        BBusiMbtiRecordDetails exam = new BBusiMbtiRecordDetails();
        exam.setRecordCode(recordCode);
        exam.setStatus(1);
        return recordDetailsMapper.selectBBusiMbtiRecordDetailsList(exam);
    }

    /**
     * 查询MBTI测评记录列表
     * 
     * @param bBusiMbtiRecords MBTI测评记录
     * @return MBTI测评记录
     */
    @Override
    public List<BBusiMbtiRecords> selectBBusiMbtiRecordsList(BBusiMbtiRecords bBusiMbtiRecords) {
        return recordsMapper.selectBBusiMbtiRecordsList(bBusiMbtiRecords);
    }

    /**
     * 新增MBTI测评记录
     * 
     * @param data MBTI测评记录
     * @return 结果
     */
    @Override
    public int insertBBusiMbtiRecords(BBusiMbtiRecords data) {
        data.setCode(Md5Utils.hash(System.currentTimeMillis() + data.getCustomerCode()));
        data.setCreateTime(DateUtils.getNowDate());
        Set<Long> idList = new HashSet<>();
        data.getDetails().forEach(row -> {
            idList.add(row.getQuestionId());
        });
        List<BBusiMbtiQuestions> qList = questionsMapper.selectByIdList(idList);
        Map<Long, BBusiMbtiQuestions> questionMap = new HashMap<>(qList.size());
        idList.clear();
        qList.forEach(row -> {
            questionMap.put(row.getId(), row);
            idList.add(row.getStepId());
        });
        final List<BBusiMbtiSteps> stepList = stepsMapper.selectByIdList(idList);
        Map<Long, BBusiMbtiSteps> stepCache = stepList.stream().collect(Collectors.toMap(BBusiMbtiSteps::getId, v -> v, (k1, k2) -> k1));
        final Map<String, Integer> scoreMap = new HashMap<>(6);
        for (BBusiMbtiRecordDetails row : data.getDetails()) {
            row.setRecordCode(data.getCode());
            row.setCustomerCode(data.getCustomerCode());
            row.setAnswer(StringUtils.trim(row.getAnswer()));
            Integer score = scoreMap.get(row.getAnswer());
            scoreMap.put(row.getAnswer(), score == null ? 1 : score + 1);
            //
            BBusiMbtiQuestions questions = questionMap.get(row.getQuestionId());
            if (null == questions) {
                throw new CustomException("问题[" + row.getQuestionId() + "]不存在", 501);
            }
            row.setQuestionTitle(questions.getTitle());
            row.setOptionA(questions.getOptionA());
            row.setOptionB(questions.getOptionB());
            row.setValueA(questions.getValueA());
            row.setValueB(questions.getValueB());
            row.setStatus(1);
            row.setStepId(questions.getStepId());
            BBusiMbtiSteps step = stepCache.get(questions.getStepId());
            if (null == step) {
                throw new CustomException("问题[" + row.getQuestionId() + "]步骤不存在", 501);
            }
            row.setStepTitle(step.getTitle());
        }
        recordDetailsMapper.insertBatch(data.getDetails());
        data.setScoreE(MapUtils.getIntValue(scoreMap, "E", 0));
        data.setScoreI(MapUtils.getIntValue(scoreMap, "I", 0));
        data.setScoreS(MapUtils.getIntValue(scoreMap, "S", 0));
        data.setScoreN(MapUtils.getIntValue(scoreMap, "N", 0));
        data.setScoreT(MapUtils.getIntValue(scoreMap, "T", 0));
        data.setScoreF(MapUtils.getIntValue(scoreMap, "F", 0));
        data.setScoreJ(MapUtils.getIntValue(scoreMap, "J", 0));
        data.setScoreP(MapUtils.getIntValue(scoreMap, "P", 0));
        List<String> ruleCodes = new ArrayList<>(4);
        ruleCodes.add(data.getScoreI() >= data.getScoreE() ? "I" : "E");
        ruleCodes.add(data.getScoreN() >= data.getScoreS() ? "N" : "S");
        ruleCodes.add(data.getScoreF() >= data.getScoreT() ? "F" : "T");
        ruleCodes.add(data.getScoreP() >= data.getScoreJ() ? "P" : "J");
        data.setRuleCode(StringUtils.join(ruleCodes, ""));
        data.setStatus(1);
        return recordsMapper.insertBBusiMbtiRecords(data);
    }

    /**
     * 修改MBTI测评记录
     * 
     * @param bBusiMbtiRecords MBTI测评记录
     * @return 结果
     */
    @Override
    public int updateBBusiMbtiRecords(BBusiMbtiRecords bBusiMbtiRecords) {
        return recordsMapper.updateBBusiMbtiRecords(bBusiMbtiRecords);
    }

    /**
     * 批量删除MBTI测评记录
     * 
     * @param ids 需要删除的MBTI测评记录ID
     * @return 结果
     */
    @Override
    public int deleteBBusiMbtiRecordsByIds(Long[] ids) {
        return recordsMapper.deleteBBusiMbtiRecordsByIds(ids);
    }

    /**
     * 删除MBTI测评记录信息
     * 
     * @param id MBTI测评记录ID
     * @return 结果
     */
    @Override
    public int deleteBBusiMbtiRecordsById(Long id) {
        return recordsMapper.deleteBBusiMbtiRecordsById(id);
    }
}
