package cn.com.qmth.stmms.biz.common.domain.card;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import cn.com.qmth.stmms.biz.mark.model.MarkConfigItem;

/**
 * 卡格式文件内容结构
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class CardFile {

    private String version;

    private boolean adapted;

    private List<CardPageWrapper> pages = Collections.emptyList();

    private List<CardQuestion> paperStruct = Collections.emptyList();

    private List<CardGroup> groupInfos = Collections.emptyList();

    @JsonIgnore
    private SliceConfig sliceConfig;

    @JsonIgnore
    private MarkConfig markConfig;

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public boolean isAdapted() {
        return adapted;
    }

    public void setAdapted(boolean adapted) {
        this.adapted = adapted;
    }

    public List<CardPageWrapper> getPages() {
        return pages;
    }

    public void setPages(List<CardPageWrapper> pages) {
        this.pages = pages;
    }

    public List<CardQuestion> getPaperStruct() {
        return paperStruct;
    }

    public void setPaperStruct(List<CardQuestion> paperStruct) {
        this.paperStruct = paperStruct;
    }

    public List<CardGroup> getGroupInfos() {
        return groupInfos;
    }

    public void setGroupInfos(List<CardGroup> groupInfos) {
        this.groupInfos = groupInfos;
    }

    private void postInit() {
        // 解析卡格式文件中的裁切图坐标，用于阅卷平台同步
        this.sliceConfig = new SliceConfig();
        if (pages != null) {
            int pageNumber = 0;
            for (CardPageWrapper pageWrapper : pages) {
                pageNumber++;
                // 强制使用遮盖模式
                sliceConfig.addConfig(pageNumber, 0, 0, 0, 0);
                // 如果没有infoArea则补一个
                if (pageWrapper.getExchange().getInfoArea().isEmpty()) {
                    pageWrapper.getExchange().getInfoArea().add(new double[] { 0, 0, 0.001, 0.001 });
                }
            }
        }
        // 解析卡格式文件中的大题评卷坐标，用于阅卷平台评卷分组设置
        this.markConfig = new MarkConfig();
        if (pages != null) {
            int pageNumber = 0;
            for (CardPageWrapper pageWrapper : pages) {
                pageNumber++;
                for (AnswerArea area : pageWrapper.getExchange().getAnswerArea()) {
                    if (area.getMainNumber() != null && area.getArea() != null && area.getArea().length >= 4) {
                        markConfig.addConfig(area.getMainNumber(), pageNumber, area.getArea()[0], area.getArea()[1],
                                area.getArea()[2], area.getArea()[3]);
                    }
                }
            }
        }

        if (paperStruct != null && groupInfos != null) {
            for (CardGroup g : groupInfos) {
                BigDecimal totalScore = BigDecimal.ZERO;
                for (CardGroupQuestion q : g.getQuestions()) {
                    for (CardQuestion question : paperStruct) {
                        if (q.getMainNumber() == question.getMainNumber()
                                && q.getSubNumber() == question.getSubNumber()) {
                            question.setGroupNumber(g.getGroupNumber());
                            totalScore = totalScore.add(BigDecimal.valueOf(question.getScore()));
                        }
                    }
                }
                g.setTotalScore(totalScore.doubleValue());
            }
        }
    }

    public SliceConfig getSliceConfig() {
        return sliceConfig;
    }

    public List<MarkConfig.ConfigItem> getMarkConfig(int mainNumber) {
        return markConfig.getConfig(mainNumber);
    }

    public String getMarkConfigAdd(List<MarkConfig.ConfigItem> list, double position) {
        DecimalFormat format = new DecimalFormat("####.###");
        for (MarkConfig.ConfigItem configItem : list) {
            configItem.left = configItem.left < position ? configItem.left : configItem.left - position;
            configItem.top = configItem.top < position ? configItem.top : configItem.top - position;
            configItem.width = configItem.width + position * 2;
            configItem.height = configItem.height + position * 2;

            configItem.left = Double.valueOf(format.format(configItem.left));
            configItem.top = Double.valueOf(format.format(configItem.top));
            configItem.width = Double.valueOf(format.format(configItem.width));
            configItem.height = Double.valueOf(format.format(configItem.height));
        }
        return StringUtils.join(list, MarkConfigItem.DB_ITEM_JOINER);
    }

    /**
     * 输出到文件前，进行必要的字段值转换与处理
     */
    private void format() {
        version = "1.0.0";
        adapted = false;
        for (CardPageWrapper cpw : pages) {
            cpw.getExchange().format();
        }
    }

    /**
     * 输出为字节数组，用于保存到文件或其他输出流
     *
     * @return
     * @throws JsonProcessingException
     */
    public byte[] output() throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        this.format();
        return mapper.writeValueAsBytes(this);
    }

    /**
     * 从输入流解析卡格式文件
     *
     * @param ins
     * @return
     * @throws IOException
     */
    public static CardFile parse(InputStream ins) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        CardFile obj = mapper.readValue(ins, CardFile.class);
        obj.postInit();
        return obj;
    }
}
