package com.codvision.base.config.excel.select;

import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import lombok.Data;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.streaming.SXSSFSheet;

import java.util.Map;

/**
 * @author hxl
 */
@Data
public class CustomSheetWriteHandler implements SheetWriteHandler {

    private final Map<Integer, ExcelSelectedResolve> selectedMap;

    @Override
    public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {

    }

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        //设置空白单元格的格式为文本
        for (int i = 0; i < 100; i++) {
            // 设置为文本格式
            SXSSFSheet sxssfSheet = (SXSSFSheet) writeSheetHolder.getSheet();
            CellStyle cellStyle = writeWorkbookHolder.getCachedWorkbook().createCellStyle();
            // 49为文本格式
            cellStyle.setDataFormat((short) 49);
            // i为列，一整列设置为文本格式
            sxssfSheet.setDefaultColumnStyle(i, cellStyle);
        }

        Sheet sheet = writeSheetHolder.getSheet();
        DataValidationHelper helper = sheet.getDataValidationHelper();
        // 获取工作簿
        // 创建sheet，突破下拉框255的限制
        // 获取一个workbook
        Workbook workbook = writeWorkbookHolder.getWorkbook();

        //2.循环赋值（为了防止下拉框的行数与隐藏域的行数相对应，将隐藏域加到结束行之后）
        selectedMap.forEach((k, v) -> {
            // 定义sheet的名称
            String sheetName = "hidden" + k;
            // 1.创建一个隐藏的sheet 名称为 providerSheet
            Sheet providerSheet = workbook.createSheet(sheetName);

            // 设置下拉列表的行： 首行，末行，首列，末列
            CellRangeAddressList rangeList = new CellRangeAddressList(v.getFirstRow(), v.getLastRow(), k, k);
            for (int i = 0, length = v.getSource().length; i < length; i++) {
                // i:表示你开始的行数  0表示你开始的列数
                Row row = providerSheet.getRow(i);
                if (row == null) {
                    row = providerSheet.createRow(i);
                }
                row.createCell(k).setCellValue(v.getSource()[i]);
            }
            //4 $A$1:$A$N代表 以A列1行开始获取N行下拉数据
            String excelLine = getExcelLine(k);
            String refers = "=" + sheetName + "!$" + excelLine + "$1:$" + excelLine + "$" + (v.getSource().length);
            // 设置下拉列表的值
            DataValidationConstraint constraint = helper.createFormulaListConstraint(refers);
            // 设置约束
            DataValidation validation = helper.createValidation(constraint, rangeList);
            // 阻止输入非下拉选项的值
            validation.setErrorStyle(DataValidation.ErrorStyle.STOP);
            validation.setShowErrorBox(true);
            validation.setSuppressDropDownArrow(true);
            validation.createErrorBox("提示", "请选择下拉选项中的内容");
            sheet.addValidationData(validation);
            //设置列为隐藏
            int hiddenIndex = workbook.getSheetIndex(sheetName);
            if (!workbook.isSheetHidden(hiddenIndex)) {
                workbook.setSheetHidden(hiddenIndex, true);
            }
        });
    }

    /**
     * @param num 列数
     * @return java.lang.String
     * @Description 返回excel列标A-Z-AA-ZZ
     */
    public static String getExcelLine(int num) {
        String line = "";
        int first = num / 26;
        int second = num % 26;
        if (first > 0) {
            line = (char) ('A' + first - 1) + "";
        }
        line += (char) ('A' + second) + "";
        return line;
    }
}
