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.Map;
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.PictureConfigItem;
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;

@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 = false)
    private String picList;

    @Column(name = "total_score", nullable = false)
    private Double totalScore;

    /**
     * 试评数量
     */
    @Column(name = "trial_count", nullable = true)
    private Integer trialCount;

    /**
     * 双评比例(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)
    @Enumerated(EnumType.STRING)
    private ScorePolicy scorePolicy;

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

    /**
     * 当前评卷状态
     */
    @Column(name = "status", length = 16, nullable = false)
    @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 = "sheet_view", nullable = false)
    private boolean sheetView;

    @Transient
    private int currentCount;

    @Transient
    private String title;

    @Transient
    private String mainNumber;

    @Transient
    private String scoreList;

    @Transient
    private Map<Integer, List<ExamQuestion>> questionMap;

    @Transient
    private long markerCount;

    @Transient
    private int percent;

    @Transient
    private double markScore;

    @Transient
    private List<ScoreItem> markScoreDetail;

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

    public MarkGroup(Integer examId, String subjectCode, Integer number, List<PictureConfigItem> configList,
            Double totalScore, Double doubleRate, Double arbitrateThreshold, Integer scorePolicy, String markMode,
            Integer trialCount, boolean sheetView) {
        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, PictureConfigItem.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 (markMode != null) {
            this.markMode = MarkMode.findByName(markMode);
        }
        if (trialCount != null && trialCount > 0) {
            this.status = MarkStatus.TRIAL;
            this.trialCount = trialCount;
        } else {
            this.status = MarkStatus.FORMAL;
        }
        this.sheetView = sheetView;
    }

    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<PictureConfigItem> configList) {
        this.picList = configList != null && configList.size() > 0
                ? StringUtils.join(configList, PictureConfigItem.DB_ITEM_JOINER)
                : "";
    }

    public List<PictureConfigItem> getPictureConfigList() {
        return PictureConfigItem.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<>();
        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());
        }
        this.mainNumber = StringUtils.join(mainNumbers, ",");
        this.title = StringUtils.join(mainTitles, ",");
        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 Integer getTrialCount() {
        return trialCount;
    }

    public void setTrialCount(Integer trialCount) {
        this.trialCount = trialCount;
    }

    public boolean isSheetView() {
        return sheetView;
    }

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

    public Map<Integer, List<ExamQuestion>> getQuestionMap() {
        return questionMap;
    }

    public void setQuestionMap(Map<Integer, List<ExamQuestion>> questionMap) {
        this.questionMap = questionMap;
    }

    public String getMainNumber() {
        return mainNumber;
    }

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

}
