package com.mvc.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mvc.constant.BaseConstant;
import com.mvc.dao.TAicbqCfgMapper;
import com.mvc.dao.TAireadDownloadRecordMapper;
import com.mvc.dao.TaskReviewMapper;
import com.mvc.entity.*;
import com.mvc.model.*;
import com.mvc.netty.dealconstant.ResourceTag;
import com.mvc.service.copy.TAireadService;
import com.mvc.service.taizhang.TAicbqCfgService;
import com.mvc.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.xssf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.print.DocFlavor;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

@Service
@Transactional
public class TAireadDownloadRecordService {
    private static Logger log = LoggerFactory.getLogger(TAireadDownloadRecordService.class);

    @Resource
    private TAireadDownloadRecordMapper tAireadDownloadRecordMapper;

    @Resource
    private TaskReviewMapper taskReviewMapper;

    @Resource
    private TAicbqCfgMapper tAicbqCfgMapper;

    @Resource
    private Environment env;

    private final String downloadDir = "airead_download/";

    //图像的根目录(这么写是为了适配识别工具要求是绝对路径)
    private final String ImageRootPath = "D:/WM_Images/";
    private final String ImageDirName = "images";

    public ResPageModel findAllTAireadDownloadRecord(TAireadDownloadRecordModel queryModel) {
        TAireadDownloadRecordExample example = new TAireadDownloadRecordExample();
        TAireadDownloadRecordExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotEmpty(queryModel.getQueryType())) {
            criteria.andQueryTypeEqualTo(queryModel.getQueryType());
        }
        if (StringUtils.isNotEmpty(queryModel.getCreateMan())) {
            criteria.andCreateManLike(StringUtil.getLikeFormat(queryModel.getCreateMan()));
        }
        if (StringUtils.isNotEmpty(queryModel.getFileName())) {
            criteria.andFileNameLike(StringUtil.getLikeFormat(queryModel.getFileName()));
        }
        if (StringUtils.isNotEmpty(queryModel.getStatus())) {
            criteria.andStatusEqualTo(queryModel.getStatus());
        }

        example.setOrderByClause("CREATE_TIME DESC");
        Page<Object> pageObject = PageHelper.startPage(queryModel.getPageNum(), queryModel.getPageSize());
        List<TAireadDownloadRecordModel> resList = selectByExample(example);
        ResPageModel pageModel = new ResPageModel(resList, pageObject);
        return pageModel;
    }

    public TAireadDownloadRecordModel saveTAireadDownloadRecord(TAireadDownloadRecordModel model) {
        model.setCreateTime(new Date());
        model.setStatus("0");
        model.setFileSize(0);
        model.setQueryType(StringUtils.isEmpty(model.getQueryType()) ? "0" : model.getQueryType());
        TAireadDownloadRecord TAireadDownloadRecord = new TAireadDownloadRecord();
        BeanUtils.copyProperties(model, TAireadDownloadRecord);
        //保存记录后,开始生成文件
        if (tAireadDownloadRecordMapper.insert(TAireadDownloadRecord) > 0) {
            model.setId(TAireadDownloadRecord.getId());
            startFileGeneration(model);
        }
        return model;
    }

    //删除记录,并同步删除文件
    public int deleteTAireadDownloadRecord(int id) {
        TAireadDownloadRecord record = tAireadDownloadRecordMapper.selectByPrimaryKey(id);
        if (record != null) {
            String fileName = record.getFileName();
            int i = tAireadDownloadRecordMapper.deleteByPrimaryKey(id);
            if (i > 0) {
                String fullName = env.getProperty(ResourceTag.DownloadPathTag.getTag()) + downloadDir + fileName;
                File file = new File(fullName);
                if (file.exists()) {
                    file.delete();
                }
            }
            return i;
        }
        return 0;
    }

    // 开始生成文件
    private void startFileGeneration(TAireadDownloadRecordModel model) {
        log.info("开始生成识别数据...");
        //使用异步处理下载任务
        CompletableFuture.runAsync(() -> {
            // 调用生成文件的方法
            generateFile(model);
        });
    }

    //生成文件
    private void generateFile(TAireadDownloadRecordModel record) {
        // 1.先处理文件名、目录
        String dateStr = DateUtil.formateDate(record.getCreateTime(), DateUtil.PATTERN_DATA_UNSIGNED);
        String path = env.getProperty(ResourceTag.DownloadPathTag.getTag()) + downloadDir + dateStr;

        String excelFileName = dateStr + ".xlsx";
        String excelFullName = path + File.separator + excelFileName;

        //图片目录images_开始时间_结束时间_类型
        String imageDirFullName = path + File.separator + ImageDirName + "-" + getFileStringBuilder(record);

        File dir = new File(path);
        if (dir.exists() && !dir.isDirectory()) {
            File[] files = dir.listFiles();
            for (File file : files) {
                file.delete();
            }
        } else {
            dir.mkdirs();
        }
        //创建图片文件夹
        File imageDir = new File(imageDirFullName);
        imageDir.mkdirs();

        // 2.创建表格
        XSSFWorkbook workbook = createWorkbook();
        XSSFSheet sheet = workbook.getSheetAt(0);

        // 3.处理审核数据
        handleReviewData(record, sheet, imageDirFullName);

        // 4.保存表格
        saveWorkbook(workbook, excelFullName);

        // 5.压缩文件并更新记录
        zipFileAndUpdateRecord(record, path);
        log.info("生成识别数据结束" + record.getFileName());
    }

    //压缩文件并更新记录
    private void zipFileAndUpdateRecord(TAireadDownloadRecordModel model, String path) {
        File sourceDir = new File(path);
        String extensions = ".zip";
        //格式:开始时间-结束时间-查询类型.zip
        StringBuilder sbZipFileName = getFileStringBuilder(model);
        sbZipFileName.append(extensions);
        String zipFileName = sbZipFileName.toString();
        String zipFullName = sourceDir.getParent() + File.separator + zipFileName;
        File zipFile = new File(zipFullName);
        try {
            //重名了,在扩展名前加 (1)
            if (zipFile.exists()) {
                zipFileName = zipFileName.replace(extensions, "(1)" + extensions);
                zipFullName = zipFullName.replace(extensions, "(1)" + extensions);
            }

            //压缩目录
            ZipUtil.zipDirectory(path, zipFullName);

            //删除目录
            Path directory = Paths.get(path);
            Files.walk(directory)
                    .sorted((p1, p2) -> -p1.compareTo(p2)) // 逆序排序以先删除文件再删除目录
                    .map(Path::toFile)
                    .forEach(File::delete);
        } catch (Exception e) {
            log.error("zipFileAndUpdateRecord:", e);
            e.printStackTrace();
        }

        // 更新记录
        model.setFileName(zipFileName);
        model.setFileSize((int) zipFile.length());
        model.setStatus(BaseConstant.VALID_FLAG);
        TAireadDownloadRecord record = new TAireadDownloadRecord();
        BeanUtils.copyProperties(model, record);
        tAireadDownloadRecordMapper.updateByPrimaryKeySelective(record);
    }

    //获取文件名(开始时间-结束时间-类型)
    private StringBuilder getFileStringBuilder(TAireadDownloadRecordModel model) {
        StringBuilder sbZipFileName = new StringBuilder();
        sbZipFileName.append(DateUtil.formateDate(model.getStartTime(), DateUtil.PATTERN_DATA_UNSIGNED));
        sbZipFileName.append("-");
        sbZipFileName.append(DateUtil.formateDate(model.getEndTime(), DateUtil.PATTERN_DATA_UNSIGNED));
        sbZipFileName.append("-");
        sbZipFileName.append(model.getQueryType());
        return sbZipFileName;
    }

    //创建工作簿
    private XSSFWorkbook createWorkbook() {
        // 创建一个新的工作簿
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 在工作簿中创建一个表单
        XSSFSheet sheet = workbook.createSheet("sheet1");
        createHeader(workbook, sheet);
        // 参数分别代表列分隔和行分隔，0表示不冻结任何列，1表示冻结第一行之后的行
        sheet.createFreezePane(0, 1);
        return workbook;
    }

    //保存工作簿
    private void saveWorkbook(XSSFWorkbook workbook, String excelFullName) {
        // 将工作簿写入文件
        try (FileOutputStream fileOut = new FileOutputStream(excelFullName)) {
            workbook.write(fileOut);
        } catch (IOException e) {
            log.error("saveWorkbook:", e);
            e.printStackTrace();
        } finally {
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //处理审核数据
    private void handleReviewData(TAireadDownloadRecordModel record, XSSFSheet sheet, String imageDirFullName) {
        TaskReviewExample example = new TaskReviewExample();
        TaskReviewExample.Criteria criteria = example.createCriteria();
        criteria.andSampleTimeGreaterThan(record.getStartTime());
        criteria.andSampleTimeLessThanOrEqualTo(record.getEndTime());

        String queryType = record.getQueryType();
        if (StringUtils.isNotEmpty(queryType)) {
            if (queryType.equals("4")) {//识别正确+审核修正
                criteria.andFinishedFlagGreaterThan("0");
                criteria.andFinishedFlagLessThan("3");
            } else if (!queryType.equals("0")) {
                criteria.andFinishedFlagEqualTo(record.getQueryType());
            }
        }

        int splitIndex = 0;

        int pages = 1;
        int pageNum = 1;
        int pageSize = 1000;

        int rowIndex = 1;
        // 用于存储已经处理过的图像地址,用来去重(审核中有非当日数据,使用历史数据作为当日审核数据的规则)
        Set<String> processedImageUrl = new HashSet<>();
        while (pageNum <= pages) {
            Page<Object> pageObject = PageHelper.startPage(pageNum, pageSize);
            List<TaskReview> resList = taskReviewMapper.selectByExample(example);
            for (TaskReview taskReview : resList) {
                String imageUrl = taskReview.getMcuImageUrl();
                if (processedImageUrl.contains(imageUrl)) {
                    continue;
                }
                if (handleReviewRecord(taskReview, sheet, imageDirFullName, rowIndex)) {
                    rowIndex++;
                    splitIndex++;
                }

                processedImageUrl.add(imageUrl);
            }
            pageNum++;
            pages = pageObject.getPages();
        }
    }

    private List<TAireadDownloadRecordModel> selectByExample(TAireadDownloadRecordExample example) {
        List<TAireadDownloadRecord> TAireadDownloadRecords = tAireadDownloadRecordMapper.selectByExample(example);
        List<TAireadDownloadRecordModel> resList = new ArrayList<>();
        for (TAireadDownloadRecord TAireadDownloadRecord : TAireadDownloadRecords) {
            TAireadDownloadRecordModel model = new TAireadDownloadRecordModel();
            BeanUtils.copyProperties(TAireadDownloadRecord, model);
            if (model.getFileSize() != null) {
                model.setFormattedFileSize(FileUtil.convertFileSize(model.getFileSize()));
            }
            //转换本地路径为网络路径
            String url = env.getProperty(ResourceTag.ResourceUrlTag.getTag()) + "/download/" + downloadDir + model.getFileName();
            model.setZipDownloadUrl(url);
            resList.add(model);
        }

        return resList;
    }

    //下载压缩文件
    public void downloadZipFile(HttpServletResponse response, String fileName) {
        String fullName = env.getProperty(ResourceTag.DownloadPathTag.getTag()) + downloadDir + fileName;
        File file = new File(fullName);
        if (!file.exists()) {
            //压缩文件已不存在
            try {
                //response.sendError(5404);
                return;
            } catch (Exception ex) {
                log.error("downloadZipFile", ex);
            }
        }

        try {
            response.setContentType("application/octet-stream");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName);

            // 将ZIP文件内容写入响应输出流
            try (FileInputStream fis = new FileInputStream(fullName);
                 ServletOutputStream outputStream = response.getOutputStream()) {

                byte[] buffer = new byte[1024];
                int length;
                while ((length = fis.read(buffer)) >= 0) {
                    outputStream.write(buffer, 0, length);
                }
                outputStream.flush(); // 确保所有数据都被写入
            }
        } catch (Exception ex) {
            log.error("downloadZipFile", ex);
            ex.printStackTrace();
        }
    }

    //创建表头
    private void createHeader(XSSFWorkbook workbook, XSSFSheet sheet) {
        XSSFRow row = sheet.createRow(0);
        XSSFCell cell;
        // 创建单元格样式并设置居中
        XSSFCellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        //标题加粗
        XSSFFont font = workbook.createFont();
        font.setBold(true);
        cellStyle.setFont(font);
        for (ExcelFormat column : ExcelFormat.values()) {
            cell = row.createCell(column.getIndex());//序号
            cell.setCellValue(column.getName());
            cell.setCellStyle(cellStyle);
            sheet.setColumnWidth(column.getIndex(), column.getWidth() * 256);
        }
    }

    //处理审核记录
    private boolean handleReviewRecord(TaskReview taskReview, XSSFSheet sheet, String imageDirFullName, int rowIndex) {
        String rawName = taskReview.getMcuImageUrl().replace("BSY", "B");//将水印图片换为无水印的
        String rawImage = ImageUtil.convertImageUrlToLocalPath(rawName, env.getProperty(ResourceTag.UploadPathTag.getTag()));
        File file = new File(rawImage);

        String bigImage = "";
        //原始图片不存在的不处理
        if (!file.exists()) {
            //审核图片不是大图,从读数表中匹配
            bigImage = getBigImageByAireadId(taskReview.getAireadId());
            if (StringUtils.isEmpty(bigImage)) {
                System.out.println("原始图片不存在,且读数表无大图:" + bigImage);
                return false;
            } else {
                rawImage = ImageUtil.convertImageUrlToLocalPath(bigImage, env.getProperty(ResourceTag.UploadPathTag.getTag()));
                file = new File(rawImage);
                if (!file.exists()) {
                    System.out.println("读数表中原始图片也不存在:" + rawImage);
                    return false;
                }
            }

        }
        try {
            BufferedImage bufferedImage = ImageIO.read(file);
            if (bufferedImage.getWidth() != 320 || bufferedImage.getHeight() != 240) {
                if (StringUtils.isEmpty(bigImage)) {//现在判断的是审核表的图片,匹配一下读数表
                    bigImage = getBigImageByAireadId(taskReview.getAireadId());
                    if (StringUtils.isEmpty(bigImage)) {
                        System.out.println("审核表图尺寸不对,读数表无大图:" + rawImage);
                        return false;
                    } else {
                        rawImage = ImageUtil.convertImageUrlToLocalPath(bigImage, env.getProperty(ResourceTag.UploadPathTag.getTag()));
                        file = new File(rawImage);
                        if (!file.exists()) {
                            System.out.println("审核表图尺寸不对,读数表大图不存在:" + rawImage);
                            return false;
                        } else {
                            bufferedImage = ImageIO.read(file);
                            if (bufferedImage.getWidth() != 320 || bufferedImage.getHeight() != 240) {
                                System.out.println("读数表大图尺寸不对:" + rawImage);
                                return false;
                            }
                        }
                    }
                } else {
                    System.out.println("图片大小错误:" + rawImage);
                    return false;
                }
            }

            String destImageName = imageDirFullName + File.separator + file.getName();
            Files.copy(Paths.get(rawImage), Paths.get(destImageName), StandardCopyOption.REPLACE_EXISTING);
        } catch (Exception ex) {
            System.out.println("复制图片失败");
        }

        XSSFRow row = sheet.createRow(rowIndex);

        //序号
        /*XSSFCell cell = row.createCell(ExcelFormat.SERIAL_NUMBER.getIndex());
        cell.setCellValue(rowIndex);*/

        //图片名称
        XSSFCell cell = row.createCell(ExcelFormat.IMAGE_NAME.getIndex());
        //绝对路径
        String imagePath = ImageRootPath + new File(imageDirFullName).getName() + File.separator + file.getName();
        imagePath = imagePath.replace("/", File.separator);
        cell.setCellValue(imagePath);
        //cell.setCellValue(file.getName());

        //标准答案
        cell = row.createCell(ExcelFormat.STANDARD_ANSWER.getIndex());
        cell.setCellValue(toDoubleWithTwoDecimalPlaces(taskReview.getReviewValue()));

        //设备编码
        cell = row.createCell(ExcelFormat.DEVICE_SN.getIndex());
        if (taskReview.getDeviceSn() != null) {
            cell.setCellValue(taskReview.getDeviceSn());
        }

        //站点编码
        cell = row.createCell(ExcelFormat.STATION_CODE.getIndex());
        cell.setCellValue(taskReview.getStationCode());

        //采样时间
        cell = row.createCell(ExcelFormat.SAMPLE_TIME.getIndex());
        cell.setCellValue(DateUtil.formateDate(taskReview.getSampleTime(), DateUtil.PATTERN_DATA_NORMAL));

        //数字个数
        cell = row.createCell(ExcelFormat.DIGIT_NUM.getIndex());
        if (taskReview.getDigitNum() != null) {
            cell.setCellValue(taskReview.getDigitNum());
        }

        //尾数单位
        cell = row.createCell(ExcelFormat.UINT_TYPE.getIndex());
        if (taskReview.getUnitType() != null) {
            cell.setCellValue(taskReview.getUnitType());
        }

        /*if (taskReview.getUintType() != null) {
            //将单位从字典值转为0.001...
            Double unitValue = UnitType.getElement(taskReview.getUintType()).getValue();
            if (unitValue != null) {
                cell.setCellValue(unitValue);
            }
        }*/

        //MCU版本
        cell = row.createCell(ExcelFormat.SOFT_VER.getIndex());
        if (taskReview.getSoftVer() != null) {
            cell.setCellValue(taskReview.getSoftVer());
        }

        //AI版本
        cell = row.createCell(ExcelFormat.AI_VERSION.getIndex());
        if (taskReview.getAiVersion() != null) {
            cell.setCellValue(taskReview.getAiVersion());
        }

        return true;
    }

    @Resource
    private TAireadService aireadService;

    /**
     * 根据AireadId获取大图地址
     *
     * @param aireadId
     * @return
     */
    private String getBigImageByAireadId(String aireadId) {
        if (StringUtils.isEmpty(aireadId)) return "";
        TAireadModel model = aireadService.getTaireadByAireadId(aireadId);
        return model == null || StringUtils.isEmpty(model.getBigJpgUrl()) ? "" : model.getBigJpgUrl().replaceAll("BSY", "B");
    }

    /**
     * 格式化为Double
     *
     * @param value
     * @return
     */
    private double toDoubleWithTwoDecimalPlaces(BigDecimal value) {
        return value.doubleValue();
    }

    /**
     * --------------------------------------分段生成全部数据---开始----------------------------------------
     */
    private static final int BATCH_ITEM_COUNT = 10000;//分包条数

    // 开始生成文件
    public void startFileGeneration2(String startTime) {
        log.info("开始生成所有识别数据文件...");
        TAireadDownloadRecordModel model = new TAireadDownloadRecordModel();
        //model.setStartTime(DateUtil.getOtherDateByYear(new Date(), -3));
        model.setStartTime(DateUtil.parseTimeStr(startTime, DateUtil.PATTERN_DATA_UNSIGNED));
        model.setEndTime(DateUtil.getZeroTimeOfDay(new Date()));
        model.setQueryType("4");
        //使用异步处理下载任务
        CompletableFuture.runAsync(() -> {
            // 调用生成文件的方法
            generateFile2(model);
        });
    }

    private String mIgonreStationCodes = "0582001142,2404240028,2404240026,2404240025,2404240023,2404240024,2404240027";
    private String mIgonreDeviceSns = "00000001159,00000001714,00000001287,00000001926,00000002672,00000002796,00000002968,00000001926";

    //生成文件
    private void generateFile2(TAireadDownloadRecordModel record) {
        try {
            Map<String, TAicbqCfg> doubleLightStationMap = getDoubleLightStationMap();
            TaskReviewExample example = new TaskReviewExample();
            TaskReviewExample.Criteria criteria = example.createCriteria();
            criteria.andSampleTimeGreaterThan(record.getStartTime());
            criteria.andSampleTimeLessThanOrEqualTo(record.getEndTime());

            String queryType = record.getQueryType();
            if (StringUtils.isNotEmpty(queryType)) {
                if (queryType.equals("4")) {//识别正确+审核修正
                    criteria.andFinishedFlagGreaterThan("0");
                    criteria.andFinishedFlagLessThan("3");
                } else if (!queryType.equals("0")) {
                    criteria.andFinishedFlagEqualTo(record.getQueryType());
                }
            }
            example.setOrderByClause("ID desc");

            int splitIndex = 1;

            int pages = 1;
            int pageNum = 1;
            int pageSize = 1000;

            int packIndex = 1;
            int invalidCount = 0;
            int validCount = 0;

            ItemData itemData = null;
            Set<String> processedImageUrl = new HashSet<>();
            while (pageNum <= pages) {
                Page<Object> pageObject = PageHelper.startPage(pageNum, pageSize);
                List<TaskReview> resList = taskReviewMapper.selectByExample(example);
                for (TaskReview taskReview : resList) {
                    if (itemData == null) {
                        itemData = getItemData(taskReview, packIndex);
                    }

                    if(StringUtils.isEmpty(taskReview.getDeviceSn()))
                    {
                        continue;
                    }

                    //过滤非水表
                    if (mIgonreStationCodes.contains(taskReview.getStationCode())) {
                        continue;
                    }

                    if(mIgonreDeviceSns.contains(taskReview.getDeviceSn())){
                        continue;
                    }

                    if (!doubleLightStationMap.containsKey(taskReview.getDeviceSn())) {
                        log.info("配置信息非双灯:" + taskReview.getDeviceSn());
                        continue;
                    }

                    String sampleDate = DateUtil.formateDate(taskReview.getSampleTime(), "yyyyMMdd");
                    if (!sampleDate.equals(taskReview.getTaskDate())) {//审核与数据不是同一天的不要
                        continue;
                    }

                    //只要双灯的 2025-03-22
                    if (StringUtils.isEmpty(taskReview.getSoftVer()) || StringUtils.isEmpty(taskReview.getHardVersion())) {
                        continue;
                    }
                    String mcuVer = taskReview.getSoftVer().toLowerCase();
                    if (!StringUtil.isInteger(taskReview.getHardVersion())) {
                        continue;
                    }
                    int cpuVer = Integer.valueOf(taskReview.getHardVersion().trim());

                    if (mcuVer.startsWith("ec")) {//ESP32的一定是双灯
                        if (taskReview.getStationCode().startsWith("351")) {//ESP32的要跳过燃气表
                            continue;
                        }
                    } else if (mcuVer.startsWith("aa") && cpuVer >= 546) {

                    } else {//非双灯设备
                        continue;
                    }

                    String imageUrl = taskReview.getMcuImageUrl();
                    if (processedImageUrl.contains(imageUrl)) {
                        System.out.println("已处理过图片:" + imageUrl);
                        continue;
                    }

                    if (handleReviewRecord(taskReview, itemData.getSheet(), itemData.getImageDirName(), splitIndex)) {
                        splitIndex++;
                        validCount++;
                    } else {
                        invalidCount++;
                        continue;
                    }

                    processedImageUrl.add(imageUrl);
                    if (splitIndex > BATCH_ITEM_COUNT) {
                        saveItemData(itemData);
                        splitIndex = 1;
                        itemData = null;
                        packIndex++;
                    }
                }
                pageNum++;
                pages = pageObject.getPages();
            }

            if (itemData != null) {
                saveItemData(itemData);
            }
            log.info("完成生成所有识别数据文件,有效数量:" + validCount + ",无效数量:" + invalidCount);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("生成文件失败", e);
        }
    }

    private ItemData getItemData(TaskReview taskReview, int splitNum) {
        ItemData itemData = new ItemData();
        // 1.先处理文件名、目录
        String markName = StringUtils.leftPad(splitNum + "", 3, '0') + "_" + taskReview.getTaskDate().substring(0, 6);
        String path = env.getProperty(ResourceTag.DownloadPathTag.getTag()) + downloadDir + markName;
        itemData.setRootDirectory(path);
        itemData.setRootDirName(markName);

        String excelFileName = markName + ".xlsx";
        String excelFullName = path + File.separator + excelFileName;
        itemData.setExcelFileName(excelFileName);
        itemData.setExcelFullName(excelFullName);

        //图片目录images_开始时间_结束时间_类型
        String imageDirFullName = path + File.separator + ImageDirName + "_" + markName;
        itemData.setImageDirName(imageDirFullName);
        File dir = new File(path);
        if (dir.exists() && !dir.isDirectory()) {
            File[] files = dir.listFiles();
            for (File file : files) {
                file.delete();
            }
        } else {
            dir.mkdirs();
        }
        //创建图片文件夹
        File imageDir = new File(imageDirFullName);
        imageDir.mkdirs();

        // 2.创建表格
        XSSFWorkbook workbook = createWorkbook();
        XSSFSheet sheet = workbook.getSheetAt(0);
        itemData.setWorkbook(workbook);
        itemData.setSheet(sheet);
        return itemData;
    }

    private void saveItemData(ItemData itemData) {
        saveWorkbook(itemData.getWorkbook(), itemData.getExcelFullName());

        File sourceDir = new File(itemData.getRootDirectory());
        String extensions = ".zip";

        String zipFileName = sourceDir.getName() + extensions;
        String zipFullName = sourceDir.getParent() + File.separator + zipFileName;
        File zipFile = new File(zipFullName);
        try {
            //重名了,在扩展名前加 (1)
            if (zipFile.exists()) {
                zipFileName = zipFileName.replace(extensions, "(1)" + extensions);
                zipFullName = zipFullName.replace(extensions, "(1)" + extensions);
            }

            //压缩目录
            ZipUtil.zipDirectory(itemData.rootDirectory, zipFullName);

            //删除目录
            Path directory = Paths.get(itemData.rootDirectory);
            Files.walk(directory)
                    .sorted((p1, p2) -> -p1.compareTo(p2)) // 逆序排序以先删除文件再删除目录
                    .map(Path::toFile)
                    .forEach(File::delete);
        } catch (Exception e) {
            log.error("zipFileAndUpdateRecord:", e);
            e.printStackTrace();
        }
    }

    private Map<String, TAicbqCfg> getDoubleLightStationMap() {
        TAicbqCfgExample example = new TAicbqCfgExample();
        TAicbqCfgExample.Criteria criteria = example.createCriteria();
        criteria.andUseFlagEqualTo("1");
        criteria.andImageSynthesisTypeGreaterThan(1);
        List<TAicbqCfg> list = tAicbqCfgMapper.selectByExample(example);
        return list.stream()
                .collect(Collectors.toMap(
                        TAicbqCfg::getDeviceSn, // 键提取器
                        cfg -> cfg, // 值提取器
                        (existing, replacement) -> replacement // 合并函数，保留最后一个出现的项
                ));

    }

    /**
     * --------------------------------------分段下载全部数据---结束----------------------------------------
     */

    class ItemData {
        private String rootDirectory;
        private String RootDirName;
        private String ImageDirName;
        private String ExcelFileName;
        private String ExcelFullName;
        private XSSFWorkbook workbook;
        private XSSFSheet sheet;

        public String getRootDirectory() {
            return rootDirectory;
        }

        public void setRootDirectory(String rootDirectory) {
            this.rootDirectory = rootDirectory;
        }

        public String getRootDirName() {
            return RootDirName;
        }

        public void setRootDirName(String rootDirName) {
            RootDirName = rootDirName;
        }

        public String getImageDirName() {
            return ImageDirName;
        }

        public void setImageDirName(String imageDirName) {
            ImageDirName = imageDirName;
        }

        public String getExcelFileName() {
            return ExcelFileName;
        }

        public void setExcelFileName(String excelFileName) {
            ExcelFileName = excelFileName;
        }

        public String getExcelFullName() {
            return ExcelFullName;
        }

        public void setExcelFullName(String excelFullName) {
            ExcelFullName = excelFullName;
        }

        public XSSFWorkbook getWorkbook() {
            return workbook;
        }

        public void setWorkbook(XSSFWorkbook workbook) {
            this.workbook = workbook;
        }

        public XSSFSheet getSheet() {
            return sheet;
        }

        public void setSheet(XSSFSheet sheet) {
            this.sheet = sheet;
        }
    }

    enum ExcelFormat {
        //SERIAL_NUMBER("序号", 0, 7, 0),//去年序号,与算法识别工具的模板匹配
        IMAGE_NAME("水表图像路径", 0, 47, 0),
        STANDARD_ANSWER("标准答案", 1, 15, 0),
        DEVICE_SN("设备编码", 2, 14, 0),
        STATION_CODE("站点编码", 3, 13, 0),
        SAMPLE_TIME("采样时间", 4, 20, 0),
        DIGIT_NUM("数字个数", 5, 10, 0),
        UINT_TYPE("尾数单位", 6, 10, 0),
        SOFT_VER("MCU版本", 7, 15, 0),
        AI_VERSION("AI版本", 8, 15, 0);

        ExcelFormat(String name, Integer index, Integer width, Integer type) {
            this.name = name;
            this.index = index;
            this.width = width;
            this.type = type;
        }

        private String name;
        private int index;
        private int width;
        private int type;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getIndex() {
            return index;
        }

        public void setIndex(int index) {
            this.index = index;
        }

        public int getWidth() {
            return width;
        }

        public void setWidth(int width) {
            this.width = width;
        }

        public int getType() {
            return type;
        }

        public void setType(int type) {
            this.type = type;
        }
    }
}
