package com.zksy.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

@Slf4j
public class ExcelImportUtil {

    /**
     * 通用 Excel 导入方法
     * @param file 上传的 Excel 文件
     * @param head 表头类型
     * @param <T> 数据类型
     * @return 解析后的对象列表
     */
    public static <T> List<T> importExcel(MultipartFile file, Class<T> head) {
        List<T> dataList = new ArrayList<>();

        try {
            EasyExcel.read(file.getInputStream(), head, new ReadListener<T>() {
                @Override
                public void invoke(T data, AnalysisContext context) {
                    dataList.add(data);
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {
                    log.info("Excel数据解析完成，共解析 {} 条记录", dataList.size());
                }

                @Override
                public void onException(Exception exception, AnalysisContext context) {
                    log.error("解析Excel行 {} 时发生异常: {}",
                            context.readRowHolder().getRowIndex(), exception.getMessage());
                    // 可以选择跳过当前行继续解析
                    throw new RuntimeException("Excel解析异常", exception);
                }
            }).sheet().doRead();
        } catch (IOException e) {
            // 记录异常日志，避免在生产环境打印堆栈信息
            e.printStackTrace();
        }

        return dataList;
    }

    /**
     * 流式处理 Excel 数据的导入方法，适合处理大数据量
     * @param file 上传的 Excel 文件
     * @param head 表头类型
     * @param consumer 数据处理函数
     * @param <T> 数据类型
     */
    public static <T> void importExcelStream(MultipartFile file, Class<T> head, Consumer<T> consumer) {
        try {
            EasyExcel.read(file.getInputStream(), head, new ReadListener<T>() {
                @Override
                public void invoke(T data, AnalysisContext context) {
                    // 每读取一行数据就立即处理，无需等待全部数据加载完成
                    consumer.accept(data);
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {
                    // 所有数据解析完成后的操作
                }
            }).sheet().doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 导入指定 sheet 的 Excel 数据
     * @param file 上传的 Excel 文件
     * @param head 表头类型
     * @param sheetNo sheet 编号，从 0 开始
     * @param <T> 数据类型
     * @return 解析后的对象列表
     */
    public static <T> List<T> importExcelBySheet(MultipartFile file, Class<T> head, int sheetNo) {
        List<T> dataList = new ArrayList<>();

        try {
            EasyExcel.read(file.getInputStream(), head, new ReadListener<T>() {
                @Override
                public void invoke(T data, AnalysisContext context) {
                    dataList.add(data);
                }

                @Override
                public void doAfterAllAnalysed(AnalysisContext context) {
                    // 所有数据解析完成后的操作
                }
            }).sheet(sheetNo).doRead();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return dataList;
    }
}