package com.qmth.paper.library.business.templete.execute;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.qmth.boot.tools.excel.ExcelWriter;
import com.qmth.boot.tools.excel.enums.ExcelType;
import com.qmth.paper.library.business.bean.dto.CodeNameEnableDisabledValue;
import com.qmth.paper.library.business.bean.dto.ExamStudentImport;
import com.qmth.paper.library.business.bean.vo.FilePathVo;
import com.qmth.paper.library.business.service.ExamStudentService;
import com.qmth.paper.library.business.service.FileUploadService;
import com.qmth.paper.library.business.service.PaperScanTaskService;
import com.qmth.paper.library.business.templete.importData.AsyncImportTaskTemplate;
import com.qmth.paper.library.business.templete.service.TaskLogicService;
import com.qmth.paper.library.common.contant.SpringContextHolder;
import com.qmth.paper.library.common.contant.SystemConstant;
import com.qmth.paper.library.common.entity.ExamStudent;
import com.qmth.paper.library.common.entity.TBTask;
import com.qmth.paper.library.common.enums.*;
import com.qmth.paper.library.common.service.TBTaskService;
import com.qmth.paper.library.common.util.Result;
import com.qmth.paper.library.common.util.ResultUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileOutputStream;
import java.text.MessageFormat;
import java.util.*;

/**
 * @Description: 考生字典导入同步任务
 * @Author: CaoZixuan
 * @Date: 2024-02-26
 */
@Service
public class AsyncExamStudentImportService extends AsyncImportTaskTemplate {

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

    public static final String BEGIN_TITLE = "->开始处理导入文件";
    public static final String EXCEPTION_TITLE = "->数据处理发生异常!";
    public static final String EXCEPTION_DATA = "错误信息:";
    public static final String FINISH_TITLE = "->数据处理结束，共处理了";
    public static final String FINISH_TOTAL_SIZE = "条数据，成功";
    public static final String FINISH_SUCCESS_SIZE = "条数据，失败";
    public static final String FINISH_ERROR_SIZE = "条数据";

    @Resource
    private PaperScanTaskService paperScanTaskService;
    @Resource
    private ExamStudentService examStudentService;
    @Resource
    private FileUploadService fileUploadService;

    @Override
    public Result importTask(Map<String, Object> map) {
        TBTask tbTask = (TBTask) map.get(SystemConstant.TASK);

        StringJoiner stringJoinerSummary = new StringJoiner("\n");
        SystemConstant.addSummary(stringJoinerSummary, BEGIN_TITLE);
        tbTask.setStatus(TaskStatusEnum.RUNNING);
        TBTaskService tbTaskService = SpringContextHolder.getBean(TBTaskService.class);
        tbTaskService.updateById(tbTask);
        int dataCount;
        int successCount;
        int errorCount;
        boolean hasError;
        List<ExamStudentImport> errorDataList;

        try {
            TaskLogicService taskLogicService = SpringContextHolder.getBean(TaskLogicService.class);

            // 执行导入考务数据
            Map<String, Object> result = taskLogicService.executeImportExamStudentLogic(map, stringJoinerSummary);
            dataCount = Integer.parseInt(String.valueOf(result.get(SystemConstant.DATA_COUNT)));
            successCount = Integer.parseInt(String.valueOf(result.get(SystemConstant.SUCCESS_DATA_COUNT)));
            errorCount = Integer.parseInt(String.valueOf(result.get(SystemConstant.ERROR_DATA_COUNT)));
            hasError = Boolean.parseBoolean(String.valueOf(result.get(SystemConstant.HAS_ERROR_DATA)));

            if (hasError) {
                SystemConstant.addSummary(stringJoinerSummary, "有异常数据，开始生成错误文件");
                tbTask.setResult(TaskResultEnum.ERROR);
                // 有异常数据
                errorDataList = JSON.parseArray(JSON.toJSONString(result.get(SystemConstant.ERROR_DATA_LIST)), ExamStudentImport.class);
                try {
                    String[] columnNames = (String[]) result.get(SystemConstant.COLUMN_NAMES);
                    File excelFileTemp = SystemConstant.getFileTempVar(SystemConstant.EXCEL_PREFIX);
                    this.createErrorExcelFile(columnNames, errorDataList, excelFileTemp);
                    String fileName = SystemConstant.getNanoId() + SystemConstant.EXCEL_PREFIX;

                    FilePathVo filePathVo = fileUploadService.uploadFile(excelFileTemp, UploadFileEnum.FILE, fileName);
                    tbTask.setErrorFilePath(JSON.toJSONString(filePathVo));
                    SystemConstant.addSummary(stringJoinerSummary, "错误文件生成生成，请到\"导入结果查询\"中，下载错误文件");
                } catch (Exception e) {
                    SystemConstant.addSummary(stringJoinerSummary, "错误文件生成失败，" + e.getMessage());
                }
            } else {
                SystemConstant.addSummary(stringJoinerSummary, "数据校验通过，开始写入考生管理数据");
                List<ExamStudent> examStudentList = JSON.parseArray(JSON.toJSONString(result.get(SystemConstant.DATASOURCE)), ExamStudent.class);
                examStudentService.saveOrUpdateBatch(examStudentList);
                SystemConstant.addSummary(stringJoinerSummary, "写入考生管理数据完成，开始更新扫描任务数据");

                RecognitionTypeEnum recognitionType = (RecognitionTypeEnum) map.get("recognitionType");
                StoreTypeEnum storeType = (StoreTypeEnum) map.get("storeType");
                // 更新扫描任务数据
                paperScanTaskService.updatePaperScanTask(tbTask.getExamId(), recognitionType, storeType, examStudentList, tbTask);
                SystemConstant.addSummary(stringJoinerSummary, "更新扫描任务数据完成，导入结束");
                tbTask.setResult(TaskResultEnum.SUCCESS);

                stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}{4}{5}{6}{7}",
                        DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), FINISH_TITLE, dataCount,
                        FINISH_TOTAL_SIZE, successCount, FINISH_SUCCESS_SIZE, errorCount, FINISH_ERROR_SIZE));
            }
        } catch (Exception e) {
            tbTask.setResult(TaskResultEnum.ERROR);
            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), EXCEPTION_TITLE, EXCEPTION_DATA, e.getMessage()));
        } finally {//生成文件
            tbTask.setStatus(TaskStatusEnum.FINISH);
            tbTask.setSummary(stringJoinerSummary.toString());
            tbTaskService.updateById(tbTask);
        }
        return ResultUtil.ok();
    }

    private void createErrorExcelFile(String[] columnName, List<ExamStudentImport> examStudentDtoList, File excelFileTemp) {
        try {
            List<String> columnNameList = new ArrayList<>(Arrays.asList(columnName));
            columnNameList.add("错误信息");
            String[] columnNames = columnNameList.toArray(new String[0]);
            List<String[]> columnValues = new ArrayList<>();
            for (ExamStudentImport examStudentImport : examStudentDtoList) {
                List<String> valueList = new ArrayList<>();
                for (String title : columnNameList) {
                    if (title.equals("错误信息")) {
                        valueList.add(examStudentImport.getErrorMsg());
                        continue;
                    }
                    String value = "";
                    for (CodeNameEnableDisabledValue codeNameEnableValue : examStudentImport.getRequiredFieldList()) {
                        if (codeNameEnableValue.getName().equals(title)) {
                            value = codeNameEnableValue.getValue();
                        }
                    }
                    if (StringUtils.isBlank(value)) {
                        for (CodeNameEnableDisabledValue codeNameEnableValue : examStudentImport.getExtendFieldList()) {
                            if (codeNameEnableValue.getName().equals(title)) {
                                value = codeNameEnableValue.getValue();
                            }
                        }
                    }
                    valueList.add(value);
                }
                // 错误信息
                String[] columnValue = valueList.toArray(new String[valueList.size()]);
                columnValues.add(columnValue);
            }

            FileOutputStream outputStream = new FileOutputStream(excelFileTemp);
            ExcelWriter writer = ExcelWriter.create(ExcelType.XLSX);
            writer.writeDataArrays("考生数据", null, columnNames, columnValues.listIterator());
            writer.output(outputStream);
            outputStream.flush();
            outputStream.close();
        } catch (Exception e) {

        }
    }

}
