/*
 * *************************************************
 * Copyright (c) 2019 QMTH. All Rights Reserved.
 * Created by Deason on 2019-05-23 11:39:26.
 * *************************************************
 */

package cn.com.qmth.examcloud.core.questions.service.bean.paper;

import cn.com.qmth.examcloud.commons.exception.StatusException;
import cn.com.qmth.examcloud.commons.util.JsonUtil;
import cn.com.qmth.examcloud.core.questions.base.question.enums.QuesStructType;
import cn.com.qmth.examcloud.core.questions.dao.entity.QuesOption;
import cn.com.qmth.examcloud.core.questions.dao.entity.Question;
import cn.com.qmth.examcloud.core.questions.service.bean.dto.PaperDetailExp;
import cn.com.qmth.examcloud.core.questions.service.bean.dto.PaperDetailUnitExp;
import cn.com.qmth.examcloud.core.questions.service.bean.dto.PaperExp;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * 试卷预览内容处理
 *
 * @author: QMTH
 * @since: 2019/5/23
 */
public class PreviewPaperHandler {
    private static final Logger log = LoggerFactory.getLogger(PreviewPaperHandler.class);
    private final static String DETAIL_STYLE = "class=\"e_detail\"";//试卷大题样式
    private final static String QUESTION_STYLE = "class=\"e_question\"";//试题标题样式
    private final static String OPTION_STYLE = "class=\"e_option\"";//试题答案项样式
    private final static String OPTION_END_STYLE = "class=\"e_option e_option_end\"";//试题答案结束项样式

    private final static String FORMAT_DETAIL = "<p %s><b>%s、%s</b></p>";//大题标题格式
    private final static String FORMAT_QUESTION = "<p %s>%s、%s</p>";//试题标题格式
    private final static String FORMAT_OPTION = "<p %s>%s、%s</p>";//选项内容格式

    private final static String[] REGEX_FILL_1 = {"[#][#]", "____"};//正则关键字
    private final static String[] REGEX_FILL_2 = {"[_][#]", "_"};//正则关键字

    /**
     * 转换试卷的HTML内容
     */
    public static String convertPaperHtml(PaperExp data) {
        if (data == null) {
            log.warn("Paper data is not exist.");
            throw new StatusException("500", "试卷信息不存在！");
        }

        List<PaperDetailExp> details = data.getPaperDetails();
        if (CollectionUtils.isEmpty(details)) {
            return "[]";
        }

        List<String> htmlTags = new ArrayList<>();
        for (int x = 0; x < details.size(); x++) {
            PaperDetailExp detail = details.get(x);
            if (StringUtils.isNotBlank(detail.getTitle())) {
                htmlTags.add(String.format(FORMAT_DETAIL, DETAIL_STYLE, detail.getCnNum(), replaceTagP(detail.getName() + detail.getTitle())));
            } else {
                htmlTags.add(String.format(FORMAT_DETAIL, DETAIL_STYLE, detail.getCnNum(), replaceTagP(detail.getName())));
            }

            if (StringUtils.isNotBlank(detail.getTitleDetail())) {
                htmlTags.add(String.format("<p><b>%s</b></p>", replaceTagP(detail.getTitleDetail())));
            }

            //封装大题的试题列表
            List<PaperDetailUnitExp> units = detail.getPaperDetailUnits();
            if (CollectionUtils.isEmpty(units)) {
                continue;
            }

            for (int y = 0; y < units.size(); y++) {
                PaperDetailUnitExp unit = units.get(y);
                Question question = unit.getQuestion();
                if (question == null) {
                    continue;
                }

                String qBody = question.getQuesBody();
                if (StringUtils.isEmpty(qBody)) {
                    log.warn("Question body is empty.");
                    qBody = " ";
                }

                //题干 替换特殊关键字
                qBody = replaceFill(question, qBody);
                if (question.getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION) {
                    htmlTags.add(String.format("<p %s>%s</p>", QUESTION_STYLE, qBody));
                } else {
                    htmlTags.add(String.format(FORMAT_QUESTION, QUESTION_STYLE, unit.getNumber(), qBody));
                }

                //客观题 选项列表
                handleOptionStyle(htmlTags, question);

                if (question.getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION) {
                    //套题的子题
                    List<Question> subQuestions = question.getSubQuestions();
                    if (CollectionUtils.isNotEmpty(subQuestions)) {
                        for (int m = 0; m < subQuestions.size(); m++) {
                            Question subQues = subQuestions.get(m);

                            String subBody = subQues.getQuesBody();
                            if (StringUtils.isEmpty(subBody)) {
                                log.warn("SubQuestion body is empty.");
                                subBody = " ";
                            }

                            //题干 替换特殊关键字
                            subBody = replaceFill(subQues, subBody);
                            String subQuesNumber = subQues.getQuesParams().get("number");
                            htmlTags.add(String.format(FORMAT_QUESTION, QUESTION_STYLE, subQuesNumber, subBody));

                            //客观题 选项列表
                            handleOptionStyle(htmlTags, subQues);
                        }
                    }
                }
            }
        }
        return JsonUtil.toJson(htmlTags);
    }

    /**
     * 转换试卷答案HTML内容
     */
    public static String convertPaperAnswerHtml(PaperExp data) {
        if (data == null) {
            throw new StatusException("500", "试卷信息不存在！");
        }

        List<PaperDetailExp> details = data.getPaperDetails();
        if (CollectionUtils.isEmpty(details)) {
            return "[]";
        }

        //封装试卷答案的HTML内容
        List<String> htmlTags = new ArrayList<>();
        for (PaperDetailExp detail : details) {
            if (StringUtils.isNotBlank(detail.getTitle())) {
                htmlTags.add(String.format(FORMAT_DETAIL, DETAIL_STYLE, detail.getCnNum(), replaceTagP(detail.getName() + detail.getTitle())));
            } else {
                htmlTags.add(String.format(FORMAT_DETAIL, DETAIL_STYLE, detail.getCnNum(), replaceTagP(detail.getName())));
            }

            List<PaperDetailUnitExp> units = detail.getPaperDetailUnits();
            if (CollectionUtils.isEmpty(units)) {
                continue;
            }

            for (PaperDetailUnitExp unit : units) {
                Question question = unit.getQuestion();
                if (question == null) {
                    continue;
                }

                if (question.getQuestionType() == QuesStructType.NESTED_ANSWER_QUESTION) {
                    //htmlTags.add(String.format(FORMAT_QUESTION, QUESTION_STYLE, unit.getNumber(), "题"));
                    List<Question> subQuestions = question.getSubQuestions();
                    if (CollectionUtils.isNotEmpty(subQuestions)) {
                        for (Question subQues : subQuestions) {
                            String subQuesNumber = subQues.getQuesParams().get("number");
                            htmlTags.add(String.format(FORMAT_QUESTION, QUESTION_STYLE, subQuesNumber, replaceFill(subQues, subQues.getQuesAnswer())));
                        }
                    }
                } else {
                    htmlTags.add(String.format(FORMAT_QUESTION, QUESTION_STYLE, unit.getNumber(), replaceFill(question, question.getQuesAnswer())));
                }
            }
        }
        return JsonUtil.toJson(htmlTags);
    }

    private static void handleOptionStyle(List<String> htmlTags, Question question) {
        List<QuesOption> options = question.getQuesOptions();
        if (CollectionUtils.isNotEmpty(options)) {
            for (int i = 0; i < options.size(); i++) {
                QuesOption option = options.get(i);
                if (i == (options.size() - 1)) {
                    htmlTags.add(String.format(FORMAT_OPTION, OPTION_END_STYLE, formatNum(option.getNumber()), replaceTagP(option.getOptionBody())));
                } else {
                    htmlTags.add(String.format(FORMAT_OPTION, OPTION_STYLE, formatNum(option.getNumber()), replaceTagP(option.getOptionBody())));
                }
            }
        }
    }

    public static String formatValue(Double score) {
        if (score == null) {
            return "";
        }
        DecimalFormat decimalFormat = new DecimalFormat("#.#");
        return decimalFormat.format(score);
    }

    public static String formatNum(String numStr) {
        int number = Integer.parseInt(numStr);
        char c = (char) (64 + number);
        return String.valueOf(c);
    }

    private static String replaceFill(Question question, String body) {
        if (StringUtils.isEmpty(body)) {
            return "";
        }

        body = replaceTagP(body);
        body = body.replaceAll(REGEX_FILL_1[0], REGEX_FILL_1[1]);

        //填空题情况
        if (question.getQuestionType() == QuesStructType.FILL_BLANK_QUESTION) {
            body = body.replaceAll(REGEX_FILL_2[0], REGEX_FILL_2[1]);
        }
        return body;
    }

    /**
     * 去掉"p"标签
     */
    public static String replaceTagP(String str) {
        if (StringUtils.isEmpty(str)) {
            return "";
        }
        return str.replace("<p>", "")
                .replace("</p>", "")
                .replace("<span>", "")
                .replace("</span>", "");
    }

}