package com.bcxin.infrastructure.offices.impls;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.builder.ExcelReaderBuilder;
import com.alibaba.excel.read.builder.ExcelReaderSheetBuilder;
import com.bcxin.Infrastructures.components.ExcelProvider;
import com.bcxin.Infrastructures.components.models.ExcelModelAbstract;
import com.bcxin.Infrastructures.exceptions.BadTenantException;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

@Component
public class ExcelProviderImpl implements ExcelProvider {
    @Override
    public Collection<Map<Integer, String>> read(InputStream reader, Map<String, Object> attributes) {
        ExcelReaderBuilder builder = EasyExcel.read(reader);
        ExcelReaderSheetBuilder sheetBuilder = this.buildSheetName(this.build(builder, attributes), attributes);

        return sheetBuilder.doReadSync();
    }

    @Override
    public <T extends ExcelModelAbstract> Collection<T> read(InputStream reader,
                                                             Class<T> tClass) {
        return EasyExcel.read(reader).sheet().doReadSync();
    }

    @Override
    public <T extends ExcelModelAbstract> Collection<T> read(InputStream reader,
                                                             Class<T> tClass,
                                                             String sheetName) {

        Collection<T> data = EasyExcel.read(reader).sheet(sheetName).<T>doReadSync();

        return data;
    }

    @Override
    public <T extends ExcelModelAbstract> void read(InputStream reader, Class<T> tClass,
                                                    String sheetName, Consumer<List<T>> consumer) {
        EasyExcel.read(reader, tClass,
                        new ExcelDataAnalysisEventListener(consumer, 1000))
                .sheet(sheetName).doRead();
    }

    @Override
    public <T extends ExcelModelAbstract> void read(InputStream reader,
                                                    Class<T> tClass,
                                                    int pageSize,
                                                    Consumer<List<T>> consumer) {
        EasyExcel.read(reader, tClass,
                        new ExcelDataAnalysisEventListener(consumer, pageSize))
                .sheet().doRead();
    }

    /**
     * 动态构建参数信息
     *
     * @param builder
     * @param attributes
     * @return
     */
    private ExcelReaderBuilder build(ExcelReaderBuilder builder, Map<String, Object> attributes) {
        if (attributes != null) {
            for (String key : attributes.keySet()) {
                switch (key) {
                    case ExcelProvider.ATTRIBUTE_HEADER_ROW_COUNT:
                        Object headerRowCount = attributes.get(ExcelProvider.ATTRIBUTE_HEADER_ROW_COUNT);
                        if (headerRowCount instanceof Integer) {
                            builder = builder.headRowNumber((int) headerRowCount);
                        } else {
                            throw new BadTenantException(String.format("Excel头数量(%s)信息设置无效!", headerRowCount));
                        }
                        break;
                }
            }
        }

        return builder;
    }

    /**
     * 设置Sheet页面信息
     *
     * @param builder
     * @param attributes
     * @return
     */
    private ExcelReaderSheetBuilder buildSheetName(ExcelReaderBuilder builder, Map<String, Object> attributes) {
        if (attributes != null) {
            Object sheetName = attributes.get(ExcelProvider.ATTRIBUTE_SHEET_NAME);
            if (sheetName != null) {
                return builder.sheet(String.valueOf(sheetName));
            }
        }
        return builder.sheet();
    }
}
