package com.njzscloud.dispose.common.utils;

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.poi.excel.BigExcelWriter;
import cn.hutool.poi.excel.ExcelUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xssf.streaming.SXSSFSheet;

import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * File工具类，扩展
 *
 * @author ljw
 * @date 2505-10-13
 */
@Slf4j
public class FileUtil extends cn.hutool.core.io.FileUtil {

    /**
     * 系统临时目录
     * <br>
     * windows 包含路径分割符，但Linux 不包含,
     * 在windows \\==\ 前提下，
     * 为安全起见 同意拼装 路径分割符，
     * <pre>
     *       java.io.tmpdir
     *       windows : C:\Users/xxx\AppData\Local\Temp\
     *       linux: /temp
     * </pre>
     */
    public static final String SYS_TEM_DIR = System.getProperty("java.io.tmpdir") + File.separator;

    /**
     * 导出excel，支持自定义文件名
     */
    public static void downloadExcel(List<Map<String, Object>> list, HttpServletResponse response, String fileName) throws IOException {
        String tempPath = SYS_TEM_DIR + IdUtil.fastSimpleUUID() + ".xlsx";
        File file = new File(tempPath);
        BigExcelWriter writer = ExcelUtil.getBigWriter(file);
        // 处理数据以防止CSV注入
        List<Map<String, Object>> sanitizedList = list.parallelStream().map(map -> {
            Map<String, Object> sanitizedMap = new LinkedHashMap<>();
            map.forEach((key, value) -> {
                if (value instanceof String) {
                    String strValue = (String) value;
                    // 检查并处理以特殊字符开头的值
                    if (strValue.startsWith("=") || strValue.startsWith("+") || strValue.startsWith("-") || strValue.startsWith("@")) {
                        strValue = "'" + strValue; // 添加单引号前缀
                    }
                    sanitizedMap.put(key, strValue);
                } else {
                    sanitizedMap.put(key, value);
                }
            });
            return sanitizedMap;
        }).collect(Collectors.toList());
        // 一次性写出内容，使用默认样式，强制输出标题
        writer.write(sanitizedList, true);
        SXSSFSheet sheet = (SXSSFSheet) writer.getSheet();

        // 手动设置列宽，确保标题和数据内容都能完整显示
        /*int columnCount = sheet.getRow(0).getLastCellNum();
        for (int i = 0; i < columnCount; i++) {
            String headerText = "";
            int maxContentLength = 0;

            try {
                // 获取标题文本
                if (sheet.getRow(0) != null && sheet.getRow(0).getCell(i) != null) {
                    headerText = sheet.getRow(0).getCell(i).getStringCellValue();
                }

                // 遍历所有数据行，找到最长的内容
                for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
                    if (sheet.getRow(rowIndex) != null && sheet.getRow(rowIndex).getCell(i) != null) {
                        String cellValue = sheet.getRow(rowIndex).getCell(i).getStringCellValue();
                        if (cellValue != null) {
                            maxContentLength = Math.max(maxContentLength, cellValue.length());
                        }
                    }
                }
            } catch (Exception e) {
                // 忽略获取单元格值的异常
            }

            // 根据标题和内容的最大长度计算合适的列宽
            int headerLength = headerText.length();
            int contentLength = maxContentLength;
            int maxLength = Math.max(headerLength, contentLength);

            // 设置列宽：每个字符约2个字符宽度，最小8个字符，最大50个字符
            int calculatedWidth = Math.max(Math.min(maxLength * 2, 50), 8) * 256;
            int currentWidth = sheet.getColumnWidth(i);

            // 设置列宽，确保标题和内容都能完整显示
            sheet.setColumnWidth(i, Math.max(calculatedWidth, currentWidth));
        }*/

        // 尝试自动调整列宽
        try {
            sheet.trackAllColumnsForAutoSizing();
            writer.autoSizeColumnAll();
        } catch (Exception e) {
            log.warn("自动调整列宽失败，使用手动设置的列宽", e);
        }
        //response为HttpServletResponse对象
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        //设置文件名，支持中文文件名
        try {
            String encodedFileName = java.net.URLEncoder.encode(fileName, "UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + encodedFileName);
        } catch (Exception e) {
            // 如果编码失败，使用默认文件名
            response.setHeader("Content-Disposition", "attachment;filename=file.xlsx");
        }
        ServletOutputStream out = response.getOutputStream();
        // 终止后删除临时文件
        file.deleteOnExit();
        writer.flush(out, true);
        //此处记得关闭输出Servlet流
        IoUtil.close(out);
    }

}
