package org.dromara.system.controller;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import org.dromara.system.domain.vo.EnrollProjectVo;

import java.io.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;

@Slf4j
public class TestPoi {

    /**
     * @return
     */
    public static void main(String[] args) throws IOException {
        System.out.println(importData());
    }

    private static List<EnrollProjectVo> importData() throws IOException {
        List<EnrollProjectVo> enrolls = new ArrayList<>();
        File file = new File("D:\\poi_demo.xlsx");

        try (FileInputStream fis = new FileInputStream(file);
             Workbook workbook = new XSSFWorkbook(fis)) {

            Sheet sheet = workbook.getSheetAt(0);

            // 获取第一行（表头），用于获取项目名称
            Row headerRow = sheet.getRow(2);
            // 动态确定有效最大列数（去除表头末尾的空列）
            int lastCellIndex = findValidLastColumnIndex(headerRow);
            List<String> projectNames = new ArrayList<>();

            // 从第6列（F列，索引5）开始收集项目名称
            for (int i = 6; i < lastCellIndex; i++) {
                Cell cell = headerRow.getCell(i);
                if (cell != null && cell.getStringCellValue() != null && !cell.getStringCellValue().trim().isEmpty()) {
                    projectNames.add(cell.getStringCellValue().trim());
                } else {
                    projectNames.add("项目_" + i); // 防止空标题
                }
            }

            // 从第3行开始读数据
            for (int i = 3; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row == null) continue;
                if (isRowEmpty(row, 0, lastCellIndex)) {
                    continue;
                }

                EnrollProjectVo enroll = new EnrollProjectVo();
                Map<String, Boolean> selections = new LinkedHashMap<>(); // 保持顺序

                // A列：姓名
                Cell nameCell = row.getCell(0);
                if (nameCell != null) {
                    enroll.setName(getCellValueAsString(nameCell));
                }

                // B列：性别
                Cell sexCell = row.getCell(1);
                if (sexCell != null) {
                    enroll.setSex(getCellValueAsString(sexCell));
                }

                // C列：年龄
                Cell ageCell = row.getCell(2);
                if (ageCell != null) {
                    enroll.setAge(getCellValueAsString(ageCell));
                }

                // D列：队伍名称
                Cell teamCell = row.getCell(3);
                if (teamCell != null) {
                    enroll.setTeamName(getCellValueAsString(teamCell));
                }

                // E列：领队
                Cell leaderCell = row.getCell(4);
                if (leaderCell != null) {
                    enroll.setLeader(getCellValueAsString(leaderCell));
                }

                // F列：联系方式
                Cell phoneCell = row.getCell(5);
                if (phoneCell != null) {
                    enroll.setPhone(getCellValueAsString(phoneCell));
                }

                // 从第6列开始读取项目名称
                for (int j = 6; j < lastCellIndex; j++) {
                    Cell cell = row.getCell(j);
                    String projectName = projectNames.get(j - 6); // 对应项目名
                    boolean selected = isCellSelected(cell);
                    selections.put(projectName, selected);
                }

                enroll.setProjectSelections(selections);
                enrolls.add(enroll);
            }
        }
        return enrolls;
    }

    // 辅助方法：将 Cell 转为字符串
    private static String getCellValueAsString(Cell cell) {
        if (cell == null) return "";

        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_STRING:
                return cell.getStringCellValue().trim();
            case Cell.CELL_TYPE_NUMERIC:
                if (org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue().toString();
                } else {
                    return String.valueOf((int) cell.getNumericCellValue()); // 或者保留小数用 double
                }
            case Cell.CELL_TYPE_BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            default:
                return "";
        }
    }

    /**
     * 判断单元格是否表示“已选择”
     * 支持：是、yes、true、1、✔、✅、√ 等
     */
    private static boolean isCellSelected(Cell cell) {
        if (cell == null) return false;

        // 先检查单元格类型
        if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
            return cell.getBooleanCellValue();
        }
        if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
            return cell.getNumericCellValue() == 1;
        }

        String value = getCellValueAsString(cell).trim().toLowerCase();
        return !value.isEmpty() &&
            (value.equals("是") || value.equals("yes") || value.equals("true") ||
                value.equals("1") || value.contains("✔") || value.contains("✅") ||
                value.contains("√") || value.equals("×"));
    }

    /**
     * 判断某行在指定范围内是否为空（无有效数据）
     *
     * @param row      行对象
     * @param startCol 起始列索引
     * @param endCol   结束列索引（不包含）
     * @return true 表示该行为空
     */
    private static boolean isRowEmpty(Row row, int startCol, int endCol) {
        if (row == null) return true;

        for (int i = startCol; i < endCol; i++) {
            Cell cell = row.getCell(i);
            if (cell != null) {
                // 如果单元格不为null，检查其是否有非空值
                String value = getCellValueAsString(cell);
                if (value != null && !value.trim().isEmpty()) {
                    return false; // 有有效数据
                }
            }
        }
        return true; // 所有列都为空
    }

    /**
     * 找到行中最后一个“有效”单元格的索引（从右往左找第一个非空单元格）
     *
     * @param row 行对象
     * @return 有效最大列索引（不包含），即 getLastCellNum() 的合理值
     */
    private static int findValidLastColumnIndex(Row row) {
        if (row == null) return 0;

        int lastCellNum = row.getLastCellNum(); // 物理最后一列
        if (lastCellNum <= 0) return 0;

        // 从右往左扫描，找到第一个非空单元格
        for (int i = lastCellNum - 1; i >= 0; i--) {
            Cell cell = row.getCell(i);
            String value = getCellValueAsString(cell);
            if (value != null && !value.trim().isEmpty()) {
                return i + 1; // 返回有效列数（索引+1）
            }
        }
        return 0; // 全为空
    }

    private static void export() {
        //1.加载Excel模板文件
        // String template = "template/enroll_template.xlsx";
        String template = "D:\\enroll_template.xlsx";
        System.out.println(template);
        XSSFSheet sheet = null;
        try (
            // InputStream inputStream = TestPoi.class.getClassLoader().getResourceAsStream(template);
            InputStream inputStream = new FileInputStream(template);
            XSSFWorkbook xwb = new XSSFWorkbook(inputStream)) {
            sheet = xwb.getSheetAt(0);
            assert sheet != null;
            //7列3行开始横着渲染 excel表对应6行2列
            // 2. 获取默认赛事动态项目（赛事项目）
            // Map<String, List<String>> projectMap = gameEventProjectService.mapProjectTypeAndProject(eventId);
            Map<String, List<String>> projectMap = new HashMap<>();
            projectMap.put("径赛项目", List.of("4*100米接力", "4*400米接力", "跳高"));
            projectMap.put("田赛项目", List.of("跨栏", "接力", "50米"));

            // 3. 渲染分类
            int currentColumnIndex = 6;
            Row row = sheet.getRow(2);
            if (row == null) {
                row = sheet.createRow(2);
            }

            for (Map.Entry<String, List<String>> entry : projectMap.entrySet()) {
                String categoryName = entry.getKey();
                List<String> projectList = entry.getValue();
                int projectCount = projectList.size();
                // 3.1 创建单元格并设置分类名称
                Cell cell = row.createCell(currentColumnIndex);
                cell.setCellValue(categoryName);

                // 3.2 合并单元格：从 currentColumnIndex 开始，合并 projectCount 个单元格
                int lastColumnIndex = currentColumnIndex + projectCount - 1;
                CellRangeAddress region = new CellRangeAddress(2, 2, currentColumnIndex, lastColumnIndex);
                sheet.addMergedRegion(region);

                // 3.3 创建样式：边框 + 居中 + 加粗
                CellStyle style = xwb.createCellStyle();
                style.setBorderTop(BorderStyle.THIN);
                style.setBorderBottom(BorderStyle.THIN);
                style.setBorderLeft(BorderStyle.THIN);
                style.setBorderRight(BorderStyle.THIN);
                style.setTopBorderColor(IndexedColors.BLACK.getIndex());
                style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
                style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
                style.setRightBorderColor(IndexedColors.BLACK.getIndex());

                style.setAlignment(HorizontalAlignment.CENTER);
                style.setVerticalAlignment(VerticalAlignment.CENTER);

                // 字体加粗
                Font font = xwb.createFont();
                font.setBold(true);
                style.setFont(font);

                // 应用样式
                cell.setCellStyle(style);

                // 3.4  更新起始列：为下一个分类腾出位置
                currentColumnIndex = lastColumnIndex + 1;
            }

            // 4. 渲染项目（在第4行，索引为3）
            currentColumnIndex = 6;
            Row projectRow = sheet.getRow(3);
            if (projectRow == null) {
                projectRow = sheet.createRow(3); // 如果第4行不存在，创建它
            }
            for (Map.Entry<String, List<String>> entry : projectMap.entrySet()) {
                List<String> projectList = entry.getValue();
                // 4.1 遍历当前分类下的每个项目
                for (String projectName : projectList) {
                    Cell cell = projectRow.createCell(currentColumnIndex);
                    cell.setCellValue(projectName);

                    // 3.3 创建样式：边框 + 居中 + 加粗
                    CellStyle style = xwb.createCellStyle();
                    style.setBorderTop(BorderStyle.THIN);
                    style.setBorderBottom(BorderStyle.THIN);
                    style.setBorderLeft(BorderStyle.THIN);
                    style.setBorderRight(BorderStyle.THIN);
                    style.setTopBorderColor(IndexedColors.BLACK.getIndex());
                    style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
                    style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
                    style.setRightBorderColor(IndexedColors.BLACK.getIndex());

                    style.setAlignment(HorizontalAlignment.CENTER);
                    style.setVerticalAlignment(VerticalAlignment.CENTER);

                    // 字体加粗
                    Font font = xwb.createFont();
                    font.setBold(true);
                    style.setFont(font);

                    // 应用样式
                    cell.setCellStyle(style);

                    // 移动到下一列
                    currentColumnIndex++;
                }
            }

            //3.将Excel文件通过Response输出
            // 设置Excel文件路径
            File target = new File("D:\\poi_demo.xlsx");
            try {
                // 创建指向该路径的输出流
                FileOutputStream stream = new FileOutputStream(target);
                // 将数据导出到Excel表格
                xwb.write(stream);
                // 关闭输出流
                stream.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            log.error("下载Excel模板异常，异常信息为：【{}】", e.getMessage(), e);
        }
    }
}

