package cn.com.qmth.examcloud.core.questions.dao.entity;

import java.util.ArrayList;
import java.util.List;

import org.springframework.data.mongodb.core.mapping.DBRef;

import cn.com.qmth.examcloud.core.questions.base.CommonUtils;
import cn.com.qmth.examcloud.core.questions.base.enums.PaperType;
import cn.com.qmth.examcloud.core.questions.base.question.enums.QuesStructType;
import cn.com.qmth.examcloud.core.questions.dao.entity.base.MongoBaseEntity;

public class PaperDetailUnit extends MongoBaseEntity implements Comparable<PaperDetailUnit> {

    /**
	 * 
	 */
	private static final long serialVersionUID = 266448283780973578L;

	@DBRef(lazy = false)
    private Paper paper;// 关联的试卷

    private Integer number;// 小题序号

    private Double score;// 小题分数

    private List<Double> subScoreList;// 对应套题的情况下，各子题的分数分布

    @DBRef(lazy = false)
    private PaperDetail paperDetail;// 关联的大题

    private QuesStructType questionType;// 小题类型

    @DBRef(lazy = false)
    private Question question;// 关联试题

    /**
     * 选择题下option的排序,按照number排序 一般：4,2,3,1 套题下的选择题:1,2,3,4;2,3,4,1;3,2,1,4
     * 题与题之间按分号";"分隔
     */
    private String optionOrder;

    private String creator;// 创建人id

    private String createTime;// 创建时间

    private PaperType paperType;
    //复制数据用
    private Long orgId;
    /**
     * 作答限时 K12
     */
    private Long timeLimit;

    public PaperDetailUnit() {
    }

    public PaperDetailUnit(Paper paper, PaperDetail paperDetail, Question question) {
        this.paper = paper;
        this.questionType = question.getQuestionType();
        this.question = question;
        this.createTime = CommonUtils.getCurDateTime();
        this.paperDetail = paperDetail;
        this.score = 0d;
    }

    public Paper getPaper() {
        return paper;
    }

    public void setPaper(Paper paper) {
        this.paper = paper;
    }

    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer number) {
        this.number = number;
    }

    public Double getScore() {
        return score;
    }

    public void setScore(Double score) {
        this.score = score;
        // 非套题或试题未设置时，不做额外处理
        if (questionType != QuesStructType.NESTED_ANSWER_QUESTION || question == null) {
            return;
        }
        // 当前分数设置为空时，同时设置子题分数为空
        if (score == null) {
            subScoreList = null;
            return;
        }
        // 总分与子题分数之和相同，则不做额外处理
        if (subScoreList != null && subScoreList.size() > 0 && getSubScoreSum() == score) {
            return;
        }
        // 根据试题与总分设置情况重置子题分数
        if (question.getSubQuestions() != null) {
            initSubScoreList(score, question.getSubQuestions());
        }
    }

    public PaperDetail getPaperDetail() {
        return paperDetail;
    }

    public void setPaperDetail(PaperDetail paperDetail) {
        this.paperDetail = paperDetail;
    }

    public QuesStructType getQuestionType() {
        return questionType;
    }

    public void setQuestionType(QuesStructType questionType) {
        this.questionType = questionType;
    }

    public Question getQuestion() {
        return question;
    }

    public void setQuestion(Question question) {
        this.question = question;
        // 非套题或总分未设置时，不做额外处理
        if (questionType != QuesStructType.NESTED_ANSWER_QUESTION || score == null) {
            return;
        }
        // 当前试题或子题列表为空时，同时设置子题分数为空
        if (question == null || question.getSubQuestions() == null) {
            subScoreList = null;
            return;
        }
        // 当前试题子题数量与子题分数数量相同，不做额外处理
        if (subScoreList != null && subScoreList.size() == question.getSubQuestions().size()) {
            return;
        }
        // 根据试题与总分设置情况重置子题分数
        initSubScoreList(score, question.getSubQuestions());
    }

    public String getCreator() {
        return creator;
    }

    public void setCreator(String creator) {
        this.creator = creator;
    }

    public String getCreateTime() {
        return createTime;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }

    public List<Double> getSubScoreList() {
        return subScoreList;
    }

    public String getOptionOrder() {
        return optionOrder;
    }

    public void setOptionOrder(String optionOrder) {
        this.optionOrder = optionOrder;
    }

    public PaperType getPaperType() {
        return paperType;
    }

    public void setPaperType(PaperType paperType) {
        if (paper != null) {
            this.paperType = paper.getPaperType();
        } else {
            this.paperType = paperType;
        }
    }

    public void setSubScoreList(List<Double> subScoreList) {
        this.subScoreList = subScoreList;
        if (subScoreList != null) {
            double totalScore = 0;
            for (Double score : subScoreList) {
                if (score == null) {
                    score = 0d;
                }
                totalScore += score;
            }
            this.score = CommonUtils.formatDouble(totalScore);
        }
    }

    public void setSubScoreListNew(List<Double> subScoreList) {
        this.subScoreList = subScoreList;
    }

    public Long getTimeLimit() {
        return timeLimit;
    }

    public void setTimeLimit(Long timeLimit) {
        this.timeLimit = timeLimit;
    }

    @Override
    public int compareTo(PaperDetailUnit unit) {
        /*if (unit != null) {
            if (this.getQuestionType().getId() > unit.getQuestionType().getId()) {
                return 1;
            } else if (this.getQuestionType().getId() == unit.getQuestionType().getId()) {
                return 0;
            }
        }*/
        if (unit != null) {
            if (this.getNumber() == null) return -1;
            if (unit.getNumber() == null) return 1;
            if (this.getNumber() > unit.getNumber()) {
                return 1;
            } else if (this.getNumber() < unit.getNumber()) {
                return -1;
            } else {
                return 0;
            }
        }
        return -1;
    }

    /**
     * 根据预设总分自动拆解套题子题的分数分布 目前采取均分后累加到最后一题的做法
     *
     * @param totalScore
     * @param questionList
     */
    private void initSubScoreList(double totalScore, List<Question> questionList) {
        List<Double> scoreList = new ArrayList<>();
        int count = questionList.size();
        if (count > 0) {
            int baseScore = (int) (totalScore / count);
            double leftScore = totalScore;
            for (int i = 0; i < count; i++) {
                scoreList.add((double) baseScore);
                leftScore -= baseScore;
            }
            if (leftScore > 0) {
                scoreList.set(count - 1, baseScore + leftScore);
            }
            this.subScoreList = scoreList;
        }
    }

    private double getSubScoreSum() {
        double totalScore = 0;
        if (subScoreList != null) {
            for (Double score : subScoreList) {
                totalScore += score;
            }
        }
        return CommonUtils.formatDouble(totalScore);
    }

    public int getDetailNumber() {
    	if(this.paperDetail==null) {
    		return -1;
    	}
        return this.paperDetail.getNumber();
    }

    public String getDetailId() {
    	if(this.paperDetail==null) {
    		return null;
    	}
        return this.paperDetail.getId();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((question == null) ? 0 : question.getId().hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        PaperDetailUnit other = (PaperDetailUnit) obj;
        if (question == null) {
            if (other.question != null) {
                return false;
            }
        } else if (!question.getId().equals(other.question.getId())) {
            return false;
        }
        return true;
    }

	public Long getOrgId() {
		return orgId;
	}

	public void setOrgId(Long orgId) {
		this.orgId = orgId;
	}

}
