package com.supervision.manage.dto;

import cn.hutool.core.annotation.Alias;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.supervision.model.AskPatientAnswer;
import com.supervision.model.AskTemplateQuestionLibrary;
import com.supervision.model.CommonDic;
import com.supervision.model.MaterialLibrary;
import lombok.Data;

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

@Data
public class MedicalRecAnswerExcelDTO {

    /**
     * 问诊类目1
     */
    @Alias(value = "* 问诊类目Ⅰ")
    private String questionTypeOne;

    /**
     * 问诊类目2 对应于 vp_ask_template_question_library 表中的 dict_id对应的 name_zh
     */
    @Alias(value = "* 问诊类目Ⅱ")
    private String questionTypeTwo;

    /**
     * 问题
     */
    @Alias(value = "* 知识")
    private String question;

    /**
     * 回答
     */
    @Alias(value = "* 回答")
    private String answer;

    /**
     * 回答视频名称
     */
    @Alias(value = "* 视频名称")
    private String answerVideoName;

    @Alias(value = "错误信息")
    private static String errorReason;

    private List<ErrorCodeEnum> errorCodeEnums = new ArrayList<>();

    /**
     * 问诊问题库id
     */
    private String libraryQuestionId;

    /**
     * 问诊问题id 对应于 vp_ask_patient_answer 表中的 id
     */
    private String askPatientAnswerId;

    /**
     * 回答资源id
     */
    private String answerResourceId;

    private String dictId;

    private String dictNamePath;

    // 默认视频后缀
    private String answerVideoSuffix = ".mp4";


    public static final List<String> READ_ANSWER_VIDEO_TITLE = CollUtil.newArrayList("* 问诊类目Ⅰ", "* 问诊类目Ⅱ", "* 知识", "* 回答","* 视频名称");

    public static final List<String> WRITE_ANSWER_VIDEO_TITLE = CollUtil.newArrayList("问诊类目Ⅰ", "问诊类目Ⅱ", "* 知识", "* 回答","* 视频名称","错误原因");

    public static final Map<String,String> READ_HEADER_ALIAS = getReadAlias();

    public static final Map<String,String> WRITE_HEADER_ALIAS = getWriteAlias();


    public void doAction(List<AskTemplateQuestionLibrary> questionLibraryList,
                         List<AskPatientAnswer> askPatientAnswerList,
                         List<MaterialLibrary> materialLibraryList,
                         List<CommonDic> questionTypeDicList,
                         Map<String,List<String>> questionMap){

        if (StrUtil.isNotEmpty(this.answerVideoName)){
            List<String> split = StrUtil.split(this.answerVideoName, ".");
            if (split.size() > 1){
                answerVideoSuffix = "." + split.get(split.size() - 1);
                answerVideoName = CollUtil.getFirst(split);
            }
        }
        this.absentCheck();
        this.matchQuestionDicId(questionTypeDicList);
        this.matchQuestion(questionLibraryList,questionMap);
        this.matchAskPatientAnswer(askPatientAnswerList);
        this.matchAnswerResource(materialLibraryList);
    }

    public AskPatientAnswer toAskPatientAnswer(){
        AskPatientAnswer askPatientAnswer = new AskPatientAnswer();
        askPatientAnswer.setId(this.askPatientAnswerId);
        askPatientAnswer.setAnswerResourceId(this.answerResourceId);
        askPatientAnswer.setLibraryQuestionId(this.libraryQuestionId);
        askPatientAnswer.setAnswer(this.answer);
        // 默认自定义回答
        askPatientAnswer.setAnswerType(1);
        return askPatientAnswer;
    }


    public Map<String,Object> toExcelMap(){
        Map<String,Object> map = new HashMap<>();
        map.put("questionTypeOne",this.questionTypeOne);
        map.put("questionTypeTwo",this.questionTypeTwo);
        map.put("question",this.question);
        map.put("answer",this.answer);
        map.put("answerVideoName",this.answerVideoName);
        if (CollUtil.isNotEmpty(errorCodeEnums)){
            String errorMessage = errorCodeEnums.stream().map(i -> i.desc).collect(Collectors.joining(";"));
            map.put("errorReason",errorMessage);
        }
        return map;
    }
    public void absentCheck(){
        if (StrUtil.isEmpty(questionTypeOne)){
            errorCodeEnums.add(ErrorCodeEnum.QUESTION_TYPE_ONE_EMPTY);
        }
        if (StrUtil.isEmpty(questionTypeTwo)){
            errorCodeEnums.add(ErrorCodeEnum.QUESTION_TYPE_TWO_EMPTY);
        }
        if (StrUtil.isEmpty(question)){
            errorCodeEnums.add(ErrorCodeEnum.QUESTION_EMPTY);
        }
        if (StrUtil.isEmpty(answer)){
            errorCodeEnums.add(ErrorCodeEnum.ANSWER_EMPTY);
        }
        if (StrUtil.isEmpty(answerVideoName)){
            errorCodeEnums.add(ErrorCodeEnum.ANSWER_VIDEO_NAME_EMPTY);
        }
    }

    /**
     * 匹配问题库
     * @param questionLibraryList 问题库
     */
    public void matchQuestion(List<AskTemplateQuestionLibrary> questionLibraryList,Map<String,List<String>> questionMap){
        if (StrUtil.isEmpty(this.question)){
            return;
        }
        if (CollUtil.isEmpty(questionLibraryList)){
            errorCodeEnums.add(ErrorCodeEnum.QUESTION_NOT_FIND);
        }
        for (AskTemplateQuestionLibrary questionLibrary : questionLibraryList) {
            String description = questionLibrary.getStandardQuestion();
            List<String> questionList = questionMap.get(questionLibrary.getId());
            if (this.question.equals(description)){
                this.libraryQuestionId = questionLibrary.getId();
                return;
            }
            if (CollUtil.isNotEmpty(questionList) && questionList.contains(this.question)){
                this.libraryQuestionId = questionLibrary.getId();
                return;
            }
        }
        errorCodeEnums.add(ErrorCodeEnum.QUESTION_NOT_FIND);
    }

    /**
     * 匹配患者回答
     * @param askPatientAnswerList 只匹配libraryQuestionId不为空的数据
     */
    public void matchAskPatientAnswer(List<AskPatientAnswer> askPatientAnswerList){
        if (StrUtil.isEmpty(this.libraryQuestionId)
                || StrUtil.isEmpty(this.answer) || CollUtil.isEmpty(askPatientAnswerList)){
            return;
        }

        for (AskPatientAnswer askPatientAnswer : askPatientAnswerList) {
            String questionId = askPatientAnswer.getLibraryQuestionId();
            String answerAnswer = askPatientAnswer.getAnswer();
            if (this.libraryQuestionId.equals(questionId) && this.answer.equals(answerAnswer)){
                this.askPatientAnswerId = askPatientAnswer.getId();
                //errorCodeEnums.add(ErrorCodeEnum.ASK_PATIENT_ANSWER_REPEAT);
                return;
            }
        }
    }

    public void matchAnswerResource(List<MaterialLibrary> materialLibraryList){
        if (StrUtil.isEmpty(this.answerVideoName)){
            return;
        }
        if(CollUtil.isEmpty(materialLibraryList)){
            errorCodeEnums.add(ErrorCodeEnum.ANSWER_VIDEO_NAME_NOT_FIND);
        }

        // 完整视频名称
        String fullAnswerVideoName = this.answerVideoName + answerVideoSuffix;

        for (MaterialLibrary materialLibrary : materialLibraryList) {
            if (fullAnswerVideoName.equals(materialLibrary.getMaterialName())){
                this.answerResourceId = materialLibrary.getFileResourceId();
                return;
            }
        }
        errorCodeEnums.add(ErrorCodeEnum.ANSWER_VIDEO_NAME_NOT_FIND);
    }

    public void matchQuestionDicId(List<CommonDic> questionTypeDicList) {
        if (StrUtil.isEmpty(this.questionTypeTwo) || StrUtil.isEmpty(questionTypeOne)) {
            return;
        }

        for (CommonDic questionTypeDic : questionTypeDicList) {
            if (this.questionTypeTwo.equals(questionTypeDic.getNameZh())) {
                String nameZhPath = questionTypeDic.getNameZhPath();
                if (StrUtil.isEmpty(nameZhPath)) {
                    continue;
                }
                // 一共两个级别
                List<String> split = StrUtil.split(nameZhPath, "/");
                if (!this.questionTypeOne.equals(CollUtil.getFirst(split))) {
                    // 如果类目一匹配不正确,也不进行处理
                    continue;
                }
                this.dictId = String.valueOf(questionTypeDic.getId());
                this.dictNamePath = questionTypeDic.getNameZhPath();
                return;
            }
        }
        errorCodeEnums.add(ErrorCodeEnum.DICE_NOT_FIND);
    }


    private static Map<String,String> getReadAlias(){
        Map<String, String> map = new LinkedHashMap<>();
        map.put("问诊类目Ⅰ","questionTypeOne");
        map.put("问诊类目Ⅱ", "questionTypeTwo");
        map.put("* 知识", "question");
        map.put("* 回答", "answer");
        map.put("* 视频名称", "answerVideoName");
        return map;
    }

    private static Map<String,String> getWriteAlias(){
        Map<String, String> map = new LinkedHashMap<>();
        map.put("questionTypeOne","问诊类目Ⅰ");
        map.put("questionTypeTwo", "问诊类目Ⅱ");
        map.put("question", "* 知识");
        map.put("answer", "* 回答");
        map.put("answerVideoName", "* 视频名称");
        map.put("errorReason", "错误原因");
        return map;
    }

    /**
     * 转换为AskTemplateQuestionLibrary
     * @return AskTemplateQuestionLibrary 不对answer进行设置
     */
    public AskTemplateQuestionLibrary toAskTemplateQuestionLibrary() {
        AskTemplateQuestionLibrary questionLibrary = new AskTemplateQuestionLibrary();
        if (StrUtil.isNotEmpty(this.dictId)){
            questionLibrary.setDictId(Long.parseLong(this.dictId));
        }
        questionLibrary.setStandardQuestion(this.question);
        return questionLibrary;
    }

    public enum ErrorCodeEnum{
         QUESTION_TYPE_ONE_EMPTY("0001","问诊类目Ⅰ不能为空"),
         QUESTION_TYPE_TWO_EMPTY("0002","问诊类目Ⅱ不能为空"),
         QUESTION_EMPTY("0003","知识不能为空"),
         ANSWER_EMPTY("0004","回答不能为空"),
         ANSWER_VIDEO_NAME_EMPTY("0005","视频名称不能为空"),
         QUESTION_NOT_FIND("40001","知识未训练"),
         ANSWER_VIDEO_NAME_NOT_FIND("40002","视频不存在"),
        DICE_NOT_FIND("40003","类目字典码值未找到"),

        // 重复回答数据
        ASK_PATIENT_ANSWER_REPEAT("50001","患者回答数据重复");

        private String code;
        private String desc;

        ErrorCodeEnum(String code, String desc) {
            this.code = code;
            this.desc = desc;
        }
    }
}