package cn.com.qmth.stmms.biz.exam.model;

import java.io.Serializable;
import java.text.DecimalFormat;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import org.apache.commons.lang.StringUtils;

import cn.com.qmth.stmms.biz.mark.model.MarkConfigItem;
import cn.com.qmth.stmms.biz.utils.ScoreItem;
import cn.com.qmth.stmms.common.enums.MarkMode;
import cn.com.qmth.stmms.common.enums.MarkStatus;
import cn.com.qmth.stmms.common.enums.ScorePolicy;
import cn.com.qmth.stmms.common.enums.ThirdPolicy;

/**
 * 评卷分组对象
 */
@Entity
@Table(name = "eb_mark_group")
public class MarkGroup implements Serializable {

    private static final long serialVersionUID = 5228601490523811224L;

    @EmbeddedId
    private MarkGroupPK pk;

    /**
     * 评卷图片设置
     */
    @Column(name = "pic_list", length = 255, nullable = true)
    private String picList;

    /**
     * 分组总分
     */
    @Column(name = "total_score", nullable = false)
    private Double totalScore;

    /**
     * 双评比例(0~1)
     */
    @Column(name = "double_rate", nullable = true)
    private Double doubleRate;

    /**
     * 仲裁阀值
     */
    @Column(name = "arbitrate_threshold", nullable = true)
    private Double arbitrateThreshold;

    /**
     * 合分策略(1-平均，2-最高，3-最低)
     */
    @Column(name = "score_policy", nullable = true, length = 16)
    @Enumerated(EnumType.STRING)
    private ScorePolicy scorePolicy;

    /**
     * 三评策略(1-关闭，2-低差值高均分)
     */
    @Column(name = "third_policy", nullable = true, length = 16)
    @Enumerated(EnumType.STRING)
    private ThirdPolicy thirdPolicy;

    /**
     * 强制评卷模式
     */
    @Column(name = "mark_mode", nullable = true, length = 16)
    @Enumerated(EnumType.STRING)
    private MarkMode markMode;

    /**
     * 开启/关闭 原卷显示
     */
    @Column(name = "sheet_view", nullable = false)
    private boolean sheetView;

    /**
     * 开启/关闭 全零分
     */
    @Column(name = "enable_all_zero", nullable = false)
    private boolean enableAllZero;

    /**
     * 当前评卷状态
     */
    @Column(name = "status", nullable = false, length = 16)
    @Enumerated(EnumType.STRING)
    private MarkStatus status;

    /**
     * 正评任务最后构造时间
     */
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "build_time", nullable = true)
    private Date buildTime;

    @Column(name = "library_count")
    private Integer libraryCount;

    @Column(name = "marked_count")
    private Integer markedCount;

    @Column(name = "left_count")
    private Integer leftCount;

    @Column(name = "is_selective", nullable = false)
    private boolean selective;

    @Transient
    private int currentCount;

    @Transient
    private String title;

    @Transient
    private String mainNumber;

    @Transient
    private String scoreList;

    @Transient
    private List<ExamQuestion> importQuestionList;

    @Transient
    private long markerCount;

    @Transient
    private int percent;

    @Transient
    private double markScore;

    @Transient
    private List<ScoreItem> markScoreDetail;

    @Transient
    private boolean deleting;

    @Transient
    private String questionTitle;

    @Transient
    private Integer selectiveIndex;

    public MarkGroup() {
        this.pk = new MarkGroupPK();
    }

    public MarkGroup(Integer examId, String subjectCode, Integer number, List<MarkConfigItem> configList,
            Double totalScore, Double doubleRate, Double arbitrateThreshold, Integer scorePolicy, String markMode,
            Integer trialCount, boolean sheetView, boolean enableAllZero, Integer thirdPolicy, boolean selective) {
        this.pk = new MarkGroupPK();
        this.pk.setExamId(examId);
        this.pk.setNumber(number);
        this.pk.setSubjectCode(subjectCode);
        this.picList = configList != null && configList.size() > 0 ? StringUtils.join(configList,
                MarkConfigItem.DB_ITEM_JOINER) : "";
        this.totalScore = totalScore;
        this.libraryCount = 0;
        this.markedCount = 0;
        this.leftCount = 0;

        if (doubleRate != null && doubleRate >= 0 && doubleRate <= 1) {
            this.doubleRate = doubleRate;
        }
        if (arbitrateThreshold != null && arbitrateThreshold >= 0) {
            this.arbitrateThreshold = arbitrateThreshold;
        }
        if (scorePolicy != null) {
            this.scorePolicy = ScorePolicy.findByValue(scorePolicy);
        } else {
            this.scorePolicy = ScorePolicy.AVG;
        }
        if (StringUtils.isNotBlank(markMode)) {
            this.markMode = MarkMode.findByName(markMode);
        }
        if (trialCount != null && trialCount > 0) {
            this.status = MarkStatus.TRIAL;
        } else {
            this.status = MarkStatus.FORMAL;
        }
        this.sheetView = sheetView;
        this.enableAllZero = enableAllZero;

        if (thirdPolicy != null) {
            this.thirdPolicy = ThirdPolicy.findByValue(thirdPolicy);
        } else {
            this.thirdPolicy = ThirdPolicy.DISABLE;
        }
        this.selective = selective;
    }

    public Integer getExamId() {
        return pk.getExamId();
    }

    public void setExamId(Integer examId) {
        pk.setExamId(examId);
    }

    public String getSubjectCode() {
        return pk.getSubjectCode();
    }

    public void setSubjectCode(String subjectCode) {
        pk.setSubjectCode(subjectCode);
    }

    public Integer getNumber() {
        return pk.getNumber();
    }

    public void setNumber(Integer number) {
        pk.setNumber(number);
    }

    public String getPicList() {
        return picList;
    }

    public void setPicList(String picList) {
        this.picList = picList;
    }

    public void setPicList(List<MarkConfigItem> configList) {
        this.picList = configList != null && configList.size() > 0 ? StringUtils.join(configList,
                MarkConfigItem.DB_ITEM_JOINER) : "";
    }

    public List<MarkConfigItem> getPictureConfigList() {
        return MarkConfigItem.parse(this.picList);
    }

    public Double getTotalScore() {
        return totalScore;
    }

    public void setTotalScore(Double totalScore) {
        this.totalScore = totalScore;
    }

    public Integer getLibraryCount() {
        return libraryCount;
    }

    public void setLibraryCount(Integer libraryCount) {
        this.libraryCount = libraryCount;
    }

    public Integer getMarkedCount() {
        return markedCount;
    }

    public void setMarkedCount(Integer markedCount) {
        this.markedCount = markedCount;
    }

    public Integer getLeftCount() {
        return leftCount;
    }

    public void setLeftCount(Integer leftCount) {
        this.leftCount = leftCount;
    }

    public String getScoreList() {
        return scoreList;
    }

    public void setScoreList(String scoreList) {
        this.scoreList = scoreList;
    }

    public void setQuestionList(List<ExamQuestion> questionList) {
        DecimalFormat format = new DecimalFormat("####.###");
        Set<Integer> mainNumbers = new LinkedHashSet<>();
        Set<String> mainTitles = new LinkedHashSet<>();
        Set<String> questionTitles = new LinkedHashSet<>();
        StringBuilder score = new StringBuilder();
        for (ExamQuestion question : questionList) {
            if (score.length() > 0) {
                score.append(",");
            }
            score.append(format.format(question.getTotalScore()));
            mainNumbers.add(question.getMainNumber());
            mainTitles.add(question.getMainTitle());
            questionTitles.add(question.getMainTitle() + '-' + question.getSubNumber());
        }
        this.mainNumber = StringUtils.join(mainNumbers, ",");
        this.title = StringUtils.join(mainTitles, ",");
        this.questionTitle = StringUtils.join(questionTitles, ",");
        this.scoreList = score.toString();
    }

    public long getMarkerCount() {
        return markerCount;
    }

    public void setMarkerCount(long markerCount) {
        this.markerCount = markerCount;
    }

    public Date getBuildTime() {
        return buildTime;
    }

    public void setBuildTime(Date buildTime) {
        this.buildTime = buildTime;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public int getCurrentCount() {
        return currentCount;
    }

    public void setCurrentCount(int currentCount) {
        this.currentCount = currentCount;
    }

    public int getPercent() {
        return percent;
    }

    public void setPercent(int percent) {
        this.percent = percent;
    }

    public Double getDoubleRate() {
        return doubleRate;
    }

    public void setDoubleRate(Double doubleRate) {
        this.doubleRate = doubleRate;
    }

    public Double getArbitrateThreshold() {
        return arbitrateThreshold;
    }

    public void setArbitrateThreshold(Double arbitrateThreshold) {
        this.arbitrateThreshold = arbitrateThreshold;
    }

    public ScorePolicy getScorePolicy() {
        return scorePolicy;
    }

    public void setScorePolicy(ScorePolicy scorePolicy) {
        this.scorePolicy = scorePolicy;
    }

    public double getMarkScore() {
        return markScore;
    }

    public void setMarkScore(double markScore) {
        this.markScore = markScore;
    }

    public List<ScoreItem> getMarkScoreDetail() {
        return markScoreDetail;
    }

    public void setMarkScoreDetail(List<ScoreItem> markScoreDetail) {
        this.markScoreDetail = markScoreDetail;
    }

    public MarkMode getMarkMode() {
        return markMode;
    }

    public void setMarkMode(MarkMode markMode) {
        this.markMode = markMode;
    }

    public MarkStatus getStatus() {
        return status;
    }

    public void setStatus(MarkStatus status) {
        this.status = status;
    }

    public boolean isSheetView() {
        return sheetView;
    }

    public void setSheetView(boolean sheetView) {
        this.sheetView = sheetView;
    }

    public List<ExamQuestion> getImportQuestionList() {
        return importQuestionList;
    }

    public void setImportQuestionList(List<ExamQuestion> importQuestionList) {
        this.importQuestionList = importQuestionList;
    }

    public String getMainNumber() {
        return mainNumber;
    }

    public void setMainNumber(String mainNumber) {
        this.mainNumber = mainNumber;
    }

    public ThirdPolicy getThirdPolicy() {
        return thirdPolicy;
    }

    public void setThirdPolicy(ThirdPolicy thirdPolicy) {
        this.thirdPolicy = thirdPolicy;
    }

    public boolean isEnableAllZero() {
        return enableAllZero;
    }

    public void setEnableAllZero(boolean enableAllZero) {
        this.enableAllZero = enableAllZero;
    }

    public boolean isDeleting() {
        return deleting;
    }

    public void setDeleting(boolean deleting) {
        this.deleting = deleting;
    }

    public boolean isSelective() {
        return selective;
    }

    public void setSelective(boolean selective) {
        this.selective = selective;
    }

    public String getQuestionTitle() {
        return questionTitle;
    }

    public void setQuestionTitle(String questionTitle) {
        this.questionTitle = questionTitle;
    }

    public Integer getSelectiveIndex() {
        return selectiveIndex;
    }

    public void setSelectiveIndex(Integer selectiveIndex) {
        this.selectiveIndex = selectiveIndex;
    }

}
