package com.ruoyi.info.collection.handler;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com.ruoyi.common.annotation.TextFormat;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Excel文本列写入处理器
 *
 * @author ruoyi
 */
@Slf4j
public class TextFormatWriteHandler implements SheetWriteHandler {

    private final Class<?> modelClass;

    public TextFormatWriteHandler(Class<?> modelClass) {
        this.modelClass = modelClass;
    }

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        Workbook workbook = writeWorkbookHolder.getWorkbook();
        Sheet sheet = writeSheetHolder.getSheet();
        CellStyle textStyle = createTextStyle(workbook);

        for (Field field : getAllFields(modelClass)) {
            if (field.getAnnotation(TextFormat.class) == null) {
                continue;
            }

            Integer columnIndex = getColumnIndex(field);
            if (columnIndex == null) {
                log.warn("字段[{}]没有指定@ExcelProperty的index，跳过文本格式设置", field.getName());
                continue;
            }

            sheet.setDefaultColumnStyle(columnIndex, textStyle);
            log.info("成功将列[{}]设置为文本格式", columnIndex);
        }
    }

    private CellStyle createTextStyle(Workbook workbook) {
        DataFormat dataFormat = workbook.createDataFormat();
        CellStyle style = workbook.createCellStyle();
        style.setDataFormat(dataFormat.getFormat("@"));
        return style;
    }

    private List<Field> getAllFields(Class<?> clazz) {
        List<Field> fields = new ArrayList<>();
        while (clazz != null && clazz != Object.class) {
            fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
            clazz = clazz.getSuperclass();
        }
        return fields;
    }

    private Integer getColumnIndex(Field field) {
        ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
        if (excelProperty != null && excelProperty.index() >= 0) {
            return excelProperty.index();
        }
        return null;
    }
}
