package com.example.demo.expand.excel;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * 合并单元格策略-联表
 */
public class MergeStrategyJoinTable<T> extends AbstractMergeStrategy {
    private Comparator<T> comparator;
    private int startColumnIndex;
    private int endColumnIndex;

    /**
     * 列表-分组的包含的行数
     * 即每个分组需要合并几行
     */
    private List<Integer> rowCountInGroupList;

    private Integer cellStartRowIndex;

    public MergeStrategyJoinTable(List<T> exportDataList, int startColumnIndex, int endColumnIndex, Comparator<T> comparator) {
        this.comparator = comparator;
        this.startColumnIndex = startColumnIndex;
        this.endColumnIndex = endColumnIndex;
        this.rowCountInGroupList = getRowCountInGroupList(exportDataList);
    }

    /**
     * 这里会遍历全部单元格-从左到右，从上到下
     * 但我不想用它的这个功能，只把它当作一个触发器
     */
    @Override
    protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
        if (cellStartRowIndex == null) {
            cellStartRowIndex = cell.getRowIndex();
            mergeGroupColumn(sheet);
        }
    }

    private void mergeGroupColumn(Sheet sheet) {
        int rowIndex = cellStartRowIndex;
        for (Integer count : rowCountInGroupList) {
            if(count == 1) {
                rowIndex += count;
                continue ;
            }
            for (int i = startColumnIndex; i < endColumnIndex; i++) {
                CellRangeAddress cellRangeAddress = new CellRangeAddress(rowIndex, rowIndex + count - 1, i, i);
                sheet.addMergedRegionUnsafe(cellRangeAddress);
            }
            rowIndex += count;
        }
    }

    private List<Integer> getRowCountInGroupList(List<T> exportDataList) {
        List<Integer> list = new ArrayList<>();
        int count = 1;
        for (int i = 1; i < exportDataList.size(); i++) {
            if (comparator.compare(exportDataList.get(i), exportDataList.get(i - 1)) == 1) {
                count++;
            } else {
                list.add(count);
                count = 1;
            }
        }
        if (exportDataList.size() > 0) list.add(count);
        return list;
    }
}
