package shop.alien.entity.store.excelVo.util;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

public class ExcelGenerator {

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

    /**
     * 生成 Excel 到本地路径。会在写入前确保父目录存在（含 Linux 生产环境；旧实现仅在 Windows 下 mkdirs，
     * 导致如 /usr/local/alien/file/excel/generate/ 未预先创建时出现 FileNotFoundException）。
     */
    public static <T> String generateExcel(String filePath, List<T> dataList, Class<T> clazz) throws IOException {
        String osName = System.getProperty("os.name").toLowerCase();
        if (osName.contains("win")) {
            filePath = "c:/" + filePath;
        }
        Path outputPath = Paths.get(filePath);
        Path parentDirectory = outputPath.getParent();
        if (parentDirectory != null) {
            try {
                Files.createDirectories(parentDirectory);
            } catch (IOException e) {
                log.error("创建 Excel 输出目录失败, filePath={}, parentDirectory={}", filePath, parentDirectory, e);
                throw e;
            }
        }
        // 创建一个新的工作簿
        XSSFWorkbook workbook = new XSSFWorkbook();
        // 创建一个工作表
        Sheet sheet = workbook.createSheet("Sheet1");

        // 获取类的所有字段
        Field[] fields = clazz.getDeclaredFields();

        // 创建加粗字体
        Font headerFont = workbook.createFont();
        headerFont.setBold(true);

        // 创建表头样式并应用字体
        CellStyle headerCellStyle = workbook.createCellStyle();
        headerCellStyle.setFont(headerFont);

        // 创建表头
        Row headerRow = sheet.createRow(0);
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            ExcelHeader excelHeader = field.getAnnotation(ExcelHeader.class);
            String headerName;
            if (excelHeader != null) {
                headerName = excelHeader.value();
            } else {
                headerName = field.getName();
            }
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headerName);
//            Cell cell = headerRow.createCell(i);
//            cell.setCellValue(fields[i].getName());
            cell.setCellStyle(headerCellStyle);
        }

        // 添加数据
        for (int i = 0; i < dataList.size(); i++) {
            Row row = sheet.createRow(i + 1);

            T obj = dataList.get(i);
            for (int j = 0; j < fields.length; j++) {
                Field field = fields[j];
                field.setAccessible(true);
                if (field.isAnnotationPresent(ExcelImage.class)) {
                    row.setHeightInPoints(80); // 数据行行高
                    try {
                        String imageUrl = (String) field.get(obj);
                        if (imageUrl != null && !imageUrl.isEmpty()) {
                            try (InputStream is = new URL(imageUrl).openStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
                                byte[] buffer = new byte[1024];
                                int length;
                                while ((length = is.read(buffer)) != -1) {
                                    baos.write(buffer, 0, length);
                                }
                                byte[] imageBytes = baos.toByteArray();
                                int pictureIndex = workbook.addPicture(imageBytes, Workbook.PICTURE_TYPE_JPEG);
                                // 去掉泛型参数 <Sheet>
                                Drawing patriarch = sheet.createDrawingPatriarch();
                                ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) j, i + 1, (short) (j + 1), i + 2);
                                patriarch.createPicture(anchor, pictureIndex);
                            } catch (Exception e) {
                                e.printStackTrace();
                                Cell cell = row.createCell(j);
                                cell.setCellValue("图片加载失败");
                            }
                        } else {
                            Cell cell = row.createCell(j);
                            cell.setCellValue("");
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        Cell cell = row.createCell(j);
                        cell.setCellValue("图片加载失败");
                    }
                } else {
                    // 常规字段处理（保持原有）...
                    try {
                        Object value = field.get(obj);
                        Cell cell = row.createCell(j);
                        if (value != null) {
                            cell.setCellValue(value.toString());
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }

            }
        }

        // 自动调整列宽
        for (int i = 0; i < fields.length; i++) {
//            sheet.autoSizeColumn(i);
            sheet.setColumnWidth(i, Math.max(sheet.getColumnWidth(i), 15 * 256));
            // 处理图片列等特殊情况，确保列宽足够
            if (fields[i].isAnnotationPresent(ExcelImage.class)) {
                sheet.setColumnWidth(i, Math.max(sheet.getColumnWidth(i), 12 * 256)); // 图片列适当加宽
            }
        }

        // 将工作簿写入文件
        try (FileOutputStream fileOut = new FileOutputStream(filePath)) {
            workbook.write(fileOut);
        }

        // 关闭工作簿
        workbook.close();
        return filePath;
    }
}    