package org.xyzh.common.utils.excel;

import org.xyzh.common.utils.validation.ValidationParam;
import org.xyzh.common.utils.validation.method.ValidateMethodType;

import java.io.File;
import java.util.*;

/**
 * @description Excel工具使用示例
 * @filename ExcelUtilsExample.java
 * @author yslg
 * @copyright yslg
 * @since 2025-11-02
 */
public class ExcelUtilsExample {
    
    /**
     * 示例实体类：用户信息
     */
    public static class UserInfo {
        private String name;
        private Integer age;
        private String phone;
        private String email;
        private String idCard;
        private Date joinDate;
        private Boolean active;
        
        // Getters and Setters
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        
        public Integer getAge() { return age; }
        public void setAge(Integer age) { this.age = age; }
        
        public String getPhone() { return phone; }
        public void setPhone(String phone) { this.phone = phone; }
        
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }
        
        public String getIdCard() { return idCard; }
        public void setIdCard(String idCard) { this.idCard = idCard; }
        
        public Date getJoinDate() { return joinDate; }
        public void setJoinDate(Date joinDate) { this.joinDate = joinDate; }
        
        public Boolean getActive() { return active; }
        public void setActive(Boolean active) { this.active = active; }
        
        @Override
        public String toString() {
            return "UserInfo{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", phone='" + phone + '\'' +
                    ", email='" + email + '\'' +
                    ", idCard='" + idCard + '\'' +
                    ", joinDate=" + joinDate +
                    ", active=" + active +
                    '}';
        }
    }
    
    /**
     * 示例1：基本使用
     */
    public static void example1_BasicUsage() {
        System.out.println("========== 示例1: 基本使用 ==========");
        
        // 1. 定义列映射关系
        List<ExcelColumnMapping> columnMappings = Arrays.asList(
            ExcelColumnMapping.builder()
                .columnName("姓名")
                .fieldName("name")
                .fieldType(String.class)
                .required()
                .build(),
            
            ExcelColumnMapping.builder()
                .columnName("年龄")
                .fieldName("age")
                .fieldType(Integer.class)
                .required()
                .build(),
            
            ExcelColumnMapping.builder()
                .columnName("手机号")
                .fieldName("phone")
                .fieldType(String.class)
                .required()
                .build(),
            
            ExcelColumnMapping.builder()
                .columnName("邮箱")
                .fieldName("email")
                .fieldType(String.class)
                .validations(Arrays.asList(
                    ValidationParam.builder()
                        .fieldName("email")
                        .fieldLabel("邮箱")
                        .required()
                        .validateMethod(ValidateMethodType.EMAIL)
                        .build()
                ))
                .build(),
            
            ExcelColumnMapping.builder()
                .columnName("入职日期")
                .fieldName("joinDate")
                .fieldType(Date.class)
                .dateFormat("yyyy-MM-dd")
                .build(),
            
            ExcelColumnMapping.builder()
                .columnName("是否在职")
                .fieldName("active")
                .fieldType(Boolean.class)
                .defaultValue("true")
                .build()
        );
        
        // 2. 读取Excel
        File file = new File("users.xlsx");
        ExcelReadResult<Object> result = ExcelReaderUtils.readExcel(
            file, 
            UserInfo.class, 
            columnMappings
        );
        
        // 3. 处理结果
        if (result.isSuccess()) {
            System.out.println("读取成功！");
            System.out.println("总行数: " + result.getTotalRows());
            System.out.println("成功行数: " + result.getSuccessRows());
            
            for (Object obj : result.getDataList()) {
                UserInfo user = (UserInfo) obj;
                System.out.println(user);
            }
        } else {
            System.out.println("读取失败: " + result.getErrorMessage());
        }
    }
    
    /**
     * 示例2：带数据校验
     */
    public static void example2_WithValidation() {
        System.out.println("\n========== 示例2: 带数据校验 ==========");
        
        // 定义列映射关系（带校验）
        List<ExcelColumnMapping> columnMappings = Arrays.asList(
            ExcelColumnMapping.builder()
                .columnName("姓名")
                .fieldName("name")
                .fieldType(String.class)
                .required()
                .addValidation(
                    ValidationParam.builder()
                        .fieldName("name")
                        .fieldLabel("姓名")
                        .required()
                        .minLength(2)
                        .maxLength(20)
                        .validateMethod(ValidateMethodType.CHINESE)
                        .build()
                )
                .build(),
            
            ExcelColumnMapping.builder()
                .columnName("年龄")
                .fieldName("age")
                .fieldType(Integer.class)
                .required()
                .addValidation(
                    ValidationParam.builder()
                        .fieldName("age")
                        .fieldLabel("年龄")
                        .required()
                        .customValidator(value -> {
                            Integer age = (Integer) value;
                            return age >= 18 && age <= 65;
                        })
                        .customErrorMessage("年龄必须在18-65岁之间")
                        .build()
                )
                .build(),
            
            ExcelColumnMapping.builder()
                .columnName("手机号")
                .fieldName("phone")
                .fieldType(String.class)
                .required()
                .addValidation(
                    ValidationParam.builder()
                        .fieldName("phone")
                        .fieldLabel("手机号")
                        .required()
                        .validateMethod(ValidateMethodType.PHONE)
                        .build()
                )
                .build(),
            
            ExcelColumnMapping.builder()
                .columnName("邮箱")
                .fieldName("email")
                .fieldType(String.class)
                .addValidation(
                    ValidationParam.builder()
                        .fieldName("email")
                        .fieldLabel("邮箱")
                        .required(false)
                        .validateMethod(ValidateMethodType.EMAIL)
                        .build()
                )
                .build(),
            
            ExcelColumnMapping.builder()
                .columnName("身份证号")
                .fieldName("idCard")
                .fieldType(String.class)
                .addValidation(
                    ValidationParam.builder()
                        .fieldName("idCard")
                        .fieldLabel("身份证号")
                        .required(false)
                        .validateMethod(ValidateMethodType.ID_CARD)
                        .build()
                )
                .build()
        );
        
        // 读取配置
        Map<String, Object> options = new HashMap<>();
        options.put("continueOnError", true);  // 遇到错误继续读取
        
        File file = new File("users.xlsx");
        ExcelReadResult<Object> result = ExcelReaderUtils.readExcel(
            file, 
            UserInfo.class, 
            columnMappings,
            options
        );
        
        // 处理结果
        System.out.println("读取完成！");
        System.out.println("总行数: " + result.getTotalRows());
        System.out.println("成功行数: " + result.getSuccessRows());
        System.out.println("失败行数: " + result.getErrorRowsCount());
        
        // 显示错误信息
        if (result.hasErrors()) {
            System.out.println("\n错误信息:");
            result.getErrorRows().forEach((rowNum, error) -> {
                System.out.println("第" + rowNum + "行: " + error);
            });
        }
    }
    
    /**
     * 示例3：使用列索引
     */
    public static void example3_UseColumnIndex() {
        System.out.println("\n========== 示例3: 使用列索引 ==========");
        
        // 使用列索引而非列名
        List<ExcelColumnMapping> columnMappings = Arrays.asList(
            ExcelColumnMapping.builder()
                .columnIndex(0)  // 第1列
                .fieldName("name")
                .fieldType(String.class)
                .required()
                .build(),
            
            ExcelColumnMapping.builder()
                .columnIndex(1)  // 第2列
                .fieldName("age")
                .fieldType(Integer.class)
                .required()
                .build(),
            
            ExcelColumnMapping.builder()
                .columnIndex(2)  // 第3列
                .fieldName("phone")
                .fieldType(String.class)
                .required()
                .build()
        );
        
        File file = new File("users.xlsx");
        ExcelReadResult<Object> result = ExcelReaderUtils.readExcel(
            file, 
            UserInfo.class, 
            columnMappings
        );
        
        System.out.println("成功读取: " + result.getSuccessRows() + " 行");
    }
    
    /**
     * 示例4：自定义配置
     */
    public static void example4_CustomConfig() {
        System.out.println("\n========== 示例4: 自定义配置 ==========");
        
        List<ExcelColumnMapping> columnMappings = Arrays.asList(
            ExcelColumnMapping.builder()
                .columnName("姓名")
                .fieldName("name")
                .fieldType(String.class)
                .required()
                .build(),
            
            ExcelColumnMapping.builder()
                .columnName("年龄")
                .fieldName("age")
                .fieldType(Integer.class)
                .required()
                .build()
        );
        
        // 自定义配置
        Map<String, Object> options = new HashMap<>();
        options.put("sheetName", "员工信息");      // 指定Sheet名称
        options.put("headerRowIndex", 0);         // 表头在第1行
        options.put("dataStartRowIndex", 1);      // 数据从第2行开始
        options.put("skipEmptyRow", true);        // 跳过空行
        options.put("maxRows", 1000);             // 最多读取1000行
        options.put("continueOnError", true);     // 遇到错误继续
        
        File file = new File("users.xlsx");
        ExcelReadResult<Object> result = ExcelReaderUtils.readExcel(
            file, 
            UserInfo.class, 
            columnMappings,
            options
        );
        
        System.out.println("读取结果: " + result);
    }
    
    /**
     * 示例5：在Controller中使用
     */
    public static void example5_InController() {
        System.out.println("\n========== 示例5: 在Controller中使用（代码示例）==========");
        System.out.println("""
            @PostMapping("/import")
            public ResultDomain<String> importUsers(@RequestParam("file") MultipartFile file) {
                try {
                    // 1. 定义列映射关系
                    List<ExcelColumnMapping> columnMappings = Arrays.asList(
                        ExcelColumnMapping.builder()
                            .columnName("姓名")
                            .fieldName("name")
                            .fieldType(String.class)
                            .required()
                            .addValidation(
                                ValidationParam.builder()
                                    .fieldName("name")
                                    .fieldLabel("姓名")
                                    .required()
                                    .validateMethod(ValidateMethodType.CHINESE)
                                    .build()
                            )
                            .build(),
                        
                        ExcelColumnMapping.builder()
                            .columnName("手机号")
                            .fieldName("phone")
                            .fieldType(String.class)
                            .required()
                            .addValidation(
                                ValidationParam.builder()
                                    .fieldName("phone")
                                    .fieldLabel("手机号")
                                    .required()
                                    .validateMethod(ValidateMethodType.PHONE)
                                    .build()
                            )
                            .build()
                    );
                    
                    // 2. 读取Excel
                    ExcelReadResult<Object> result = ExcelReaderUtils.readExcel(
                        file.getInputStream(),
                        file.getOriginalFilename(),
                        UserInfo.class,
                        columnMappings
                    );
                    
                    // 3. 处理结果
                    if (result.hasErrors()) {
                        StringBuilder errorMsg = new StringBuilder();
                        errorMsg.append("导入失败，共").append(result.getErrorRowsCount()).append("行数据有误：\\n");
                        result.getErrorRows().forEach((rowNum, error) -> {
                            errorMsg.append("第").append(rowNum).append("行: ").append(error).append("\\n");
                        });
                        return ResultDomain.fail(errorMsg.toString());
                    }
                    
                    // 4. 保存数据
                    List<UserInfo> users = new ArrayList<>();
                    for (Object obj : result.getDataList()) {
                        users.add((UserInfo) obj);
                    }
                    userService.batchSave(users);
                    
                    return ResultDomain.success("导入成功，共导入" + result.getSuccessRows() + "条数据");
                    
                } catch (Exception e) {
                    return ResultDomain.fail("导入失败: " + e.getMessage());
                }
            }
            """);
    }
    
    public static void main(String[] args) {
        // 运行示例
        // example1_BasicUsage();
        // example2_WithValidation();
        // example3_UseColumnIndex();
        // example4_CustomConfig();
        example5_InController();
    }
}

