package com.qmth.exam.reserve.service.impl;

import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.AreaBreak;
import com.itextpdf.layout.element.Cell;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.element.Table;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.VerticalAlignment;
import com.qmth.boot.core.exception.StatusException;
import com.qmth.boot.tools.uuid.FastUUID;
import com.qmth.exam.reserve.bean.stdapply.ItextDocumentInfo;
import com.qmth.exam.reserve.bean.stdapply.MaterialTitleInfo;
import com.qmth.exam.reserve.bean.stdapply.StudentApplyVO;
import com.qmth.exam.reserve.service.MaterialGenerateService;
import com.qmth.exam.reserve.util.ItextPdfUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

@Service
public class MaterialGenerateServiceImpl implements MaterialGenerateService {

    private static final Logger log = LoggerFactory.getLogger(MaterialGenerateServiceImpl.class);

    private static final int FIRST_PAGE_STUDENT_ROW_COUNT = 30;// 首页最多显示多少行学生

    private static final int NOT_FIRST_PAGE_STUDENT_ROW_COUNT = 35;// 非首页最多显示多少行学生

    private static final int STUDENT_GROUP_COUNT = 2;// 每行显示几组学生信息

    private static final int FONT_SIZE = 12;

    private static final int LINE_HEIGHT = 20;

    @Override
    public File generateSignInForm(MaterialTitleInfo title, List<StudentApplyVO> studentList) {
        Document doc = null;
        ItextDocumentInfo pageModel = new ItextDocumentInfo();

        try {
            File file = File.createTempFile("Material" + FastUUID.get(), ".tmp");
            doc = pageModel.prepareDocument(file);
            doc.setMargins(2, 20, 2, 20);
            doc.add(new Paragraph("签到表").setFontSize(18).setBold().setTextAlignment(TextAlignment.CENTER));

            int totalSize = studentList.size();
            doc.add(subHead(title, FONT_SIZE));
            doc.add(overviewTable(FONT_SIZE, totalSize));

            int rowCount = FIRST_PAGE_STUDENT_ROW_COUNT;
            List<StudentApplyVO> tempList = new ArrayList<>();
            for (int index = 0; index < totalSize; index++) {
                tempList.add(studentList.get(index));

                if (index >= FIRST_PAGE_STUDENT_ROW_COUNT * STUDENT_GROUP_COUNT) {
                    // 非首页
                    rowCount = NOT_FIRST_PAGE_STUDENT_ROW_COUNT;
                }

                if (tempList.size() == rowCount * STUDENT_GROUP_COUNT) {
                    createSignInTable(tempList, doc, rowCount);
                    if (index != totalSize - 1) {
                        // 非末页
                        doc.add(new AreaBreak());
                    }
                    tempList.clear();
                }
            }

            if (!tempList.isEmpty()) {
                createSignInTable(tempList, doc, rowCount);
                tempList.clear();
            }

            return file;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            ItextPdfUtil.closePdf(doc);
            throw new StatusException("无法生成pdf");
        } finally {
            ItextPdfUtil.closePdf(doc);
        }
    }

    private void createSignInTable(List<StudentApplyVO> tempList, Document doc, int rowCount) {
        Table tableTitle = tableTitle(FONT_SIZE);
        int number = Math.min(tempList.size(), rowCount);
        int nameFontSize = 10;
        for (int i = 0; i < number; i++) {
            StudentApplyVO result = null;
            if (tempList.size() >= i + 1) {
                result = tempList.get(i);
                tableTitle.addCell(new Cell(1, 1).add(result != null ? result.getName() : " ").setTextAlignment(TextAlignment.CENTER)
                        .setVerticalAlignment(VerticalAlignment.MIDDLE).setFontSize(nameFontSize).setHeight(LINE_HEIGHT));
                tableTitle.addCell(new Cell(1, 1).add(result != null ? result.getStudentCode() : " ").setTextAlignment(TextAlignment.CENTER)
                        .setVerticalAlignment(VerticalAlignment.MIDDLE).setFontSize(FONT_SIZE).setHeight(LINE_HEIGHT));
                tableTitle.addCell(new Cell(1, 1).add(result != null ? result.getSeatNumber() : " ").setTextAlignment(TextAlignment.CENTER)
                        .setVerticalAlignment(VerticalAlignment.MIDDLE).setFontSize(FONT_SIZE).setHeight(LINE_HEIGHT));
                tableTitle.addCell(
                        new Cell(1, 1).add(" ").setTextAlignment(TextAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE)
                                .setFontSize(FONT_SIZE).setHeight(LINE_HEIGHT));
            } else {
                tableTitle.addCell(
                        new Cell(1, 1).add(" ").setTextAlignment(TextAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE)
                                .setFontSize(10).setHeight(LINE_HEIGHT));
                tableTitle.addCell(
                        new Cell(1, 1).add(" ").setTextAlignment(TextAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE)
                                .setFontSize(10).setHeight(LINE_HEIGHT));
                tableTitle.addCell(
                        new Cell(1, 1).add(" ").setTextAlignment(TextAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE)
                                .setFontSize(10).setHeight(LINE_HEIGHT));
                tableTitle.addCell(
                        new Cell(1, 1).add(" ").setTextAlignment(TextAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE)
                                .setFontSize(10).setHeight(LINE_HEIGHT));
            }
            if (tempList.size() >= i + number + 1) {
                result = tempList.get(i + rowCount);
                tableTitle.addCell(new Cell(1, 1).add(result != null ? result.getName() : " ").setTextAlignment(TextAlignment.CENTER)
                        .setVerticalAlignment(VerticalAlignment.MIDDLE).setFontSize(nameFontSize).setHeight(LINE_HEIGHT));
                tableTitle.addCell(new Cell(1, 1).add(result != null ? result.getStudentCode() : " ").setTextAlignment(TextAlignment.CENTER)
                        .setVerticalAlignment(VerticalAlignment.MIDDLE).setFontSize(FONT_SIZE).setHeight(LINE_HEIGHT));
                tableTitle.addCell(new Cell(1, 1).add(result != null ? result.getSeatNumber() : " ").setTextAlignment(TextAlignment.CENTER)
                        .setVerticalAlignment(VerticalAlignment.MIDDLE).setFontSize(FONT_SIZE).setHeight(LINE_HEIGHT));
                tableTitle.addCell(
                        new Cell(1, 1).add(" ").setTextAlignment(TextAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE)
                                .setFontSize(FONT_SIZE).setHeight(LINE_HEIGHT));
            } else {
                tableTitle.addCell(
                        new Cell(1, 1).add(" ").setTextAlignment(TextAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE)
                                .setFontSize(10).setHeight(LINE_HEIGHT));
                tableTitle.addCell(
                        new Cell(1, 1).add(" ").setTextAlignment(TextAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE)
                                .setFontSize(10).setHeight(LINE_HEIGHT));
                tableTitle.addCell(
                        new Cell(1, 1).add(" ").setTextAlignment(TextAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE)
                                .setFontSize(10).setHeight(LINE_HEIGHT));
                tableTitle.addCell(
                        new Cell(1, 1).add(" ").setTextAlignment(TextAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE)
                                .setFontSize(10).setHeight(LINE_HEIGHT));
            }
        }
        doc.add(tableTitle);
    }

    private Table subHead(MaterialTitleInfo title, int fontSize) {
        Table table = new Table(new float[]{1.2f, 1f}).setWidthPercent(100);
        String address = title.getRoomName();
        if (address != null && address.length() > 18) {
            fontSize = 10;
        }
        table.addCell(new Cell(1, 1).add("考点名称：" + title.getSiteName()).setTextAlignment(TextAlignment.LEFT)
                .setVerticalAlignment(VerticalAlignment.MIDDLE).setBorder(null).setFontSize(fontSize).setMarginLeft(20f));
        table.addCell(new Cell(1, 1).add("考场编号：" + title.getRoomCode()).setTextAlignment(TextAlignment.LEFT)
                .setVerticalAlignment(VerticalAlignment.MIDDLE).setBorder(null).setFontSize(fontSize).setMarginLeft(40f));

        table.addCell(new Cell(1, 1).add("考场名称：" + address).setTextAlignment(TextAlignment.LEFT)
                .setVerticalAlignment(VerticalAlignment.MIDDLE).setBorder(null).setFontSize(fontSize).setMarginLeft(20f));
        table.addCell(new Cell(1, 1).add("考试时间：" + title.getTimePeriod()).setTextAlignment(TextAlignment.LEFT)
                .setVerticalAlignment(VerticalAlignment.MIDDLE).setBorder(null).setFontSize(fontSize).setMarginLeft(40f));
        return table;
    }

    private Table overviewTable(int fontSize, int totalSize) {
        Table table = new Table(new float[]{1f, 1f, 1f, 1f, 1f, 1f}).setWidthPercent(100);
        table.addCell(new Cell(1, 1).add("应考人数").setTextAlignment(TextAlignment.LEFT)
                .setVerticalAlignment(VerticalAlignment.MIDDLE).setFontSize(fontSize).setMarginLeft(20f));
        table.addCell(new Cell(1, 1).add(String.valueOf(totalSize)).setTextAlignment(TextAlignment.LEFT)
                .setVerticalAlignment(VerticalAlignment.MIDDLE).setFontSize(fontSize).setMarginLeft(20f));
        table.addCell(new Cell(1, 1).add("实考人数").setTextAlignment(TextAlignment.LEFT)
                .setVerticalAlignment(VerticalAlignment.MIDDLE).setFontSize(fontSize).setMarginLeft(20f));
        table.addCell(new Cell(1, 1).add(" ").setTextAlignment(TextAlignment.LEFT)
                .setVerticalAlignment(VerticalAlignment.MIDDLE).setFontSize(fontSize).setMarginLeft(20f));
        table.addCell(new Cell(1, 1).add("缺考人数").setTextAlignment(TextAlignment.LEFT)
                .setVerticalAlignment(VerticalAlignment.MIDDLE).setFontSize(fontSize).setMarginLeft(20f));
        table.addCell(new Cell(1, 1).add(" ").setTextAlignment(TextAlignment.LEFT)
                .setVerticalAlignment(VerticalAlignment.MIDDLE).setFontSize(fontSize).setMarginLeft(20f));

        table.addCell(new Cell(1, 1).add("监考员1签名").setTextAlignment(TextAlignment.LEFT)
                .setVerticalAlignment(VerticalAlignment.MIDDLE).setFontSize(fontSize).setMarginLeft(10f));
        table.addCell(new Cell(1, 2).add(" ").setTextAlignment(TextAlignment.LEFT)
                .setVerticalAlignment(VerticalAlignment.MIDDLE).setFontSize(fontSize).setMarginLeft(20f));
        table.addCell(new Cell(1, 1).add("监考员2签名").setTextAlignment(TextAlignment.LEFT)
                .setVerticalAlignment(VerticalAlignment.MIDDLE).setFontSize(fontSize).setMarginLeft(10f));
        table.addCell(new Cell(1, 2).add(" ").setTextAlignment(TextAlignment.LEFT)
                .setVerticalAlignment(VerticalAlignment.MIDDLE).setFontSize(fontSize).setMarginLeft(20f));

        table.setMarginTop(2);
        table.setMarginBottom(2);
        return table;
    }

    private Table tableTitle(int fontSize) {
        Table signTable = new Table(new float[]{1f, 1.3f, 0.5f, 1f, 1f, 1.3f, 0.5f, 1f}).setWidthPercent(100);
        for (int i = 0; i < STUDENT_GROUP_COUNT; i++) {
            signTable.addCell(
                    new Cell(1, 1).add("姓名").setTextAlignment(TextAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE)
                            .setFontSize(fontSize).setBold());
            signTable.addCell(
                    new Cell(1, 1).add("学号").setTextAlignment(TextAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE)
                            .setFontSize(fontSize).setBold());
            signTable.addCell(
                    new Cell(1, 1).add("座号").setTextAlignment(TextAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE)
                            .setFontSize(fontSize).setBold());
            signTable.addCell(
                    new Cell(1, 1).add("签字").setTextAlignment(TextAlignment.CENTER).setVerticalAlignment(VerticalAlignment.MIDDLE)
                            .setFontSize(fontSize).setBold());
        }
        return signTable;
    }

}
