package com.qmth.themis.business.templete.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qmth.themis.business.annotation.ExcelNotExport;
import com.qmth.themis.business.annotation.ExcelNote;
import com.qmth.themis.business.constant.SystemConstant;
import com.qmth.themis.business.dto.response.TEExamStudentDto;
import com.qmth.themis.business.service.TEExamStudentService;
import com.qmth.themis.business.templete.TaskExportCommon;
import com.qmth.themis.business.templete.TaskExportTemplete;
import com.qmth.themis.business.templete.service.TempleteLogicService;
import com.qmth.themis.common.util.Result;
import com.qmth.themis.common.util.ResultUtil;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @Description: 考场导出任务
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2020/7/20
 */
@Service
public class TaskExamStudentExportTemplete implements TaskExportTemplete {
    private final static Logger log = LoggerFactory.getLogger(TaskExamStudentExportTemplete.class);

    @Resource
    TEExamStudentService teExamStudentService;

    @Resource
    TempleteLogicService templeteLogicService;

    /**
     * 考生导出模版
     *
     * @param transMap
     * @return
     */
    @Override
    public Result exportTask(Map<String, Object> transMap) throws IOException {
        log.info("开始导出考生数据");
        long start = System.currentTimeMillis();
        TaskExportCommon taskExportCommon = new TaskExportCommon(transMap);
        taskExportCommon.init();
        taskExportCommon.setTxtList(new ArrayList());
        InputStream inputStream = null;
        ByteArrayOutputStream out = null;
        StringJoiner stringJoiner = null;
        String excelFilePath = null;
        int min = 0, line = 0;
        SXSSFWorkbook wb = null;
        try {
            Long examId = (Long) transMap.get(SystemConstant.EXAM_ID);
            Long activityId = (Long) transMap.get(SystemConstant.ACTIVITY_ID);
            String identity = (String) transMap.get("identity");
            String name = (String) transMap.get(SystemConstant.NAME);
            String roomCode = (String) transMap.get(SystemConstant.ROOM_CODE);
            String courseCode = (String) transMap.get(SystemConstant.COURSE_CODE);
            String grade = (String) transMap.get("grade");
            Integer enable = (Integer) transMap.get("enable");
            String classNo = (String) transMap.get("classNo");
            Integer hasPhoto = (Integer) transMap.get("hasPhoto");

            List<TEExamStudentDto> list = null;
            int pageSize = SystemConstant.MAX_QUERY_SIZE, pageNumber = SystemConstant.MIN_QUERY_SIZE;
            IPage<TEExamStudentDto> examStudentDtoIPage = teExamStudentService.examStudentQuery(new Page<>(pageNumber, pageSize), examId, activityId, identity, name, roomCode, courseCode, grade, enable, classNo, hasPhoto);
            while (Objects.nonNull(examStudentDtoIPage) && examStudentDtoIPage.getRecords().size() > 0) {
                list = Objects.isNull(list) ? new ArrayList<>(examStudentDtoIPage.getRecords().size() * 10) : list;
                pageNumber++;
                list.addAll(examStudentDtoIPage.getRecords());
                examStudentDtoIPage = teExamStudentService.examStudentQuery(new Page<>(pageNumber, pageSize), examId, activityId, identity, name, roomCode, courseCode, grade, enable, classNo, hasPhoto);
            }

            boolean oss = (boolean) taskExportCommon.getOssEnv().get(SystemConstant.OSS);
            stringJoiner = new StringJoiner("");
            if (!oss) {
                stringJoiner.add(SystemConstant.FILES_DIR).add(File.separator);
            }
            stringJoiner = SystemConstant.getDirName(stringJoiner, false);
            //创建excel
            wb = new SXSSFWorkbook();
            Sheet sheet = wb.createSheet("考生导出");
            CellStyle style = wb.createCellStyle();
            style.setAlignment(HorizontalAlignment.CENTER); // 水平居中格式
            style.setVerticalAlignment(VerticalAlignment.CENTER); //垂直居中
            Row row = sheet.createRow(0);
            Field[] fields = TEExamStudentDto.class.getDeclaredFields();
            //绘制表头
            for (int i = 0; i < fields.length; i++) {
                Field field = fields[i];
                field.setAccessible(true);
                Annotation annotation = field.getAnnotation(ExcelNotExport.class);
                if (Objects.isNull(annotation)) {
                    Cell cell = row.createCell(i);
                    cell.setCellValue(field.getAnnotation(ExcelNote.class).value());
                    cell.setCellStyle(style);
                    sheet.setColumnWidth(i, 15 * 400);
                }
            }
            int rowIndex = 0, cellIndex = 0, max = SystemConstant.MAX_EXPORT_SIZE, size = list.size();
            if (max >= size) {
                max = size;
            }
            while (max <= size) {
                List subList = list.subList(min, max);
                //绘制数据
                for (int y = 0; y < subList.size(); y++) {
                    line++;
                    TEExamStudentDto teExamStudentDto = (TEExamStudentDto) subList.get(y);
                    rowIndex++;
                    cellIndex = 0;
                    Row sxssfRow = sheet.createRow(rowIndex);
                    for (Field field : fields) {
                        field.setAccessible(true);
                        Annotation annotation = field.getAnnotation(ExcelNotExport.class);
                        if (Objects.isNull(annotation)) {
                            taskExportCommon
                                    .createExcelCell(sxssfRow, cellIndex, field.get(teExamStudentDto), style);
                            cellIndex++;
                        }
                    }
                }
                transMap.put("max", max);
                transMap.put("min", min);
                transMap.put("size", size);
                transMap = templeteLogicService.execExportExamStudentLogic(transMap);
                if (max == size) {
                    break;
                }
                min = max;
                max += SystemConstant.MAX_EXPORT_SIZE;
                if (max >= size) {
                    max = size;
                }
            }
            //临时缓冲区
            out = new ByteArrayOutputStream();
            wb.write(out);
            byte[] bookByteAry = out.toByteArray();
            inputStream = new ByteArrayInputStream(bookByteAry);
            excelFilePath = taskExportCommon.ossUpload(inputStream, stringJoiner.toString());
            long end = System.currentTimeMillis();
            log.info("导出考生数据结束,============耗时============:{}秒", (end - start) / 1000);
        } catch (Exception e) {
            log.error("导出报错", e);
            taskExportCommon.exception(line, e, taskExportCommon.getTxtList());
        } finally {
            //这里写入txt文件
            taskExportCommon.writeExportResultTxt(stringJoiner.toString(), taskExportCommon.getTxtList().toString(), excelFilePath);
            if (Objects.nonNull(wb)) {
                wb.dispose();
            }
            if (Objects.nonNull(inputStream)) {
                inputStream.close();
            }
            if (Objects.nonNull(out)) {
                out.flush();
                out.close();
            }
        }
        return ResultUtil.ok(true);
    }

}
