package com.ruoyi.syzy.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

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.alibaba.fastjson2.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.ruoyi.common.exception.CustomException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.sign.Md5Utils;
import com.ruoyi.syzy.domain.BBusiHollandQuestionOptions;
import com.ruoyi.syzy.domain.BBusiHollandQuestions;
import com.ruoyi.syzy.domain.BBusiHollandRecordDetails;
import com.ruoyi.syzy.domain.BBusiHollandRecords;
import com.ruoyi.syzy.domain.BBusiHollandRules;
import com.ruoyi.syzy.domain.BBusiHollandSteps;
import com.ruoyi.syzy.mapper.BBusiHollandQuestionOptionsMapper;
import com.ruoyi.syzy.mapper.BBusiHollandQuestionsMapper;
import com.ruoyi.syzy.mapper.BBusiHollandRecordDetailsMapper;
import com.ruoyi.syzy.mapper.BBusiHollandRecordsMapper;
import com.ruoyi.syzy.mapper.BBusiHollandRulesMapper;
import com.ruoyi.syzy.mapper.BBusiHollandStepsMapper;
import com.ruoyi.syzy.service.IBBusiHollandRecordsService;

/**
 * 霍兰德测评记录Service业务层处理
 * 
 * @author mingxue
 * @date 2021-08-15
 */
@Service
public class BBusiHollandRecordsServiceImpl implements IBBusiHollandRecordsService {
    @Autowired
    private BBusiHollandRecordsMapper recordsMapper;
    @Autowired
    private BBusiHollandRecordDetailsMapper recordDetailsMapper;
    @Autowired
    private BBusiHollandRulesMapper rulesMapper;
    @Autowired
    private BBusiHollandQuestionOptionsMapper optionsMapper;
    @Autowired
    private BBusiHollandQuestionsMapper questionsMapper;
    @Autowired
    private BBusiHollandStepsMapper stepsMapper;

    /**
     * 查询霍兰德测评记录
     * 
     * @param id 霍兰德测评记录ID
     * @return 霍兰德测评记录
     */
    @Override
    public BBusiHollandRecords selectBBusiHollandRecordsById(Long id) {
        return recordsMapper.selectBBusiHollandRecordsById(id);
    }

    /**
     * 查询霍兰德测评记录
     */
    @Override
    public BBusiHollandRecords info(String code) {
        BBusiHollandRecords exam = new BBusiHollandRecords();
        exam.setCode(code);
        List<BBusiHollandRecords> coll = recordsMapper.selectBBusiHollandRecordsList(exam);
        BBusiHollandRecords res = coll.stream().findFirst().orElse(null);
        if (null != res) {
            res.setRule(getRuleByCode(res.getRuleCode()));
            res.setDetails(listDetailByRecord(code));
        }
        return res;
    }

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

    private List<BBusiHollandRecordDetails> listDetailByRecord(String recordCode) {
        if (StringUtils.isBlank(recordCode)) {
            return Lists.newArrayList();
        }
        BBusiHollandRecordDetails exam = new BBusiHollandRecordDetails();
        exam.setRecordCode(recordCode);
        exam.setStatus(1);
        final List<BBusiHollandRecordDetails> coll = recordDetailsMapper.selectBBusiHollandRecordDetailsList(exam);
        Set<Long> questionIdSet = Sets.newHashSet();
        coll.forEach(row -> {
            questionIdSet.add(row.getQuestionId());
        });
        if (questionIdSet.size() > 0) {
            Map<Long, Map<Long, String>> quesNoLabelMap = buildOptionCacheByQuestionId(questionIdSet);
            coll.forEach(row -> {
                try {
                    List<String> options = new ArrayList<>();
                    Map<Long, String> cache = quesNoLabelMap.get(row.getQuestionId());
                    List<Long> arr = JSON.parseArray(row.getAnswer(), Long.class);
                    for (Long key : arr) {
                        options.add(MapUtils.getString(cache, key, ""));
                    }
                    row.setOptions(options);
                } catch (Exception ige) {
                }
            });
        }
        return coll;
    }

    private Map<Long, Map<Long, String>> buildOptionCacheByQuestionId(Collection<Long> questionIds) {
        Map<String, Object> cond = Maps.newHashMap();
        cond.put("questionIds", questionIds);
        Map<Long, Map<Long, String>> quesNoLabelMap = Maps.newHashMap();
        List<BBusiHollandQuestionOptions> optionsList = optionsMapper.selectBBusiHollandQuestionOptionsList2(cond);
        for (BBusiHollandQuestionOptions options : optionsList) {
            Map<Long, String> noLabelMap = quesNoLabelMap.get(options.getQuestionId());
            if (null == noLabelMap) {
                noLabelMap = Maps.newHashMap();
                quesNoLabelMap.put(options.getQuestionId(), noLabelMap);
            }
            noLabelMap.putIfAbsent(options.getNo(), options.getLabel());
        }
        return quesNoLabelMap;
    }

    /**
     * 查询霍兰德测评记录列表
     * 
     * @param bBusiHollandRecords 霍兰德测评记录
     * @return 霍兰德测评记录
     */
    @Override
    public List<BBusiHollandRecords> selectBBusiHollandRecordsList(BBusiHollandRecords bBusiHollandRecords) {
        return recordsMapper.selectBBusiHollandRecordsList(bBusiHollandRecords);
    }

    /**
     * 新增霍兰德测评记录
     * 
     * @param data 霍兰德测评记录
     * @return 结果
     */
    @Override
    public int insertBBusiHollandRecords(BBusiHollandRecords data) {
        data.setCode(Md5Utils.hash(System.currentTimeMillis() + data.getCustomerCode()));
        data.setCreateTime(DateUtils.getNowDate());
        Set<Long> idList = new HashSet<>();
        Map<Long, BBusiHollandQuestions> questionCache = new HashMap<>(6);
        Map<Long, BBusiHollandSteps> stepCache = new HashMap<>(6);
        Map<String, Integer> scoreMap = new HashMap<>(6);
        data.getDetails().forEach(row -> {
            idList.add(row.getQuestionId());
        });
        List<BBusiHollandQuestions> list = questionsMapper.selectBBusiHollandQuestionsByIdList(idList);
        idList.clear();
        list.forEach(row -> {
            questionCache.put(row.getId(), row);
            idList.add(row.getStepId());
        });
        stepsMapper.selectBBusiHollandStepsByIdList(idList).forEach(row -> {
            stepCache.put(row.getId(), row);
        });
        for (BBusiHollandRecordDetails row : data.getDetails()) {
            row.setRecordCode(data.getCode());
            row.setCustomerCode(data.getCustomerCode());
            BBusiHollandQuestions questions = questionCache.get(row.getQuestionId());
            if (null == questions) {
                throw new CustomException("问题[" + row.getQuestionId() + "]不存在", 501);
            }
            row.setQuestionTitle(questions.getTitle());
            row.setRuleCode(questions.getRuleCode());
            BBusiHollandSteps step = stepCache.get(questions.getStepId());
            if (null == step) {
                throw new CustomException("问题[" + row.getQuestionId() + "]步骤不存在", 501);
            }
            row.setStepId(step.getId());
            row.setStepTitle(step.getTitle());
            List<Integer> answer = JSON.parseArray(row.getAnswer(), Integer.class);
            final String key = row.getRuleCode().toUpperCase();
            Integer score = scoreMap.get(key);
            if (null == score) {
                score = 0;
            }
            if (Long.valueOf(5).equals(row.getStepId())) {
                for (Integer num : answer) {
                    score += num;
                }
            } else {
                score += answer.size();
            }
            scoreMap.put(key, score);
            row.setStatus(1);
        }
        recordDetailsMapper.insertBatch(data.getDetails());
        //
        List<String> ruleCodes = new ArrayList<String>(scoreMap.size());
        scoreMap.entrySet().stream().sorted(new Comparator<Map.Entry<String, Integer>>() {

            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                return o2.getValue().compareTo(o1.getValue());
            }
        }).forEach(row -> {
            ruleCodes.add(row.getKey());
        });
        data.setRuleCode(StringUtils.join(ruleCodes.subList(0, 3), ""));
        //
        data.setScorer(MapUtils.getInteger(scoreMap, "R", 0));
        data.setScorei(MapUtils.getInteger(scoreMap, "I", 0));
        data.setScorea(MapUtils.getInteger(scoreMap, "A", 0));
        data.setScores(MapUtils.getInteger(scoreMap, "S", 0));
        data.setScoree(MapUtils.getInteger(scoreMap, "E", 0));
        data.setScorec(MapUtils.getInteger(scoreMap, "C", 0));
        data.setStatus(1);
        return recordsMapper.insertBBusiHollandRecords(data);
    }

    /**
     * 修改霍兰德测评记录
     * 
     * @param bBusiHollandRecords 霍兰德测评记录
     * @return 结果
     */
    @Override
    public int updateBBusiHollandRecords(BBusiHollandRecords bBusiHollandRecords) {
        return recordsMapper.updateBBusiHollandRecords(bBusiHollandRecords);
    }

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

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