package cn.pluss.platform.util.excel.model;

import cn.pluss.platform.util.ExcelUtil;
import lombok.Data;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCells;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;

/**
 * 合并单元格与普通单元格统一对象
 * @author Djh
 */
@Data
public class Cell {

    /**
     * @param value     内容，这里默认全部转为文本，暂不支持其他
     * @param font      字体
     * @param startCol    开始列
     * @param startRow    开始行
     * @param lengthCol   跨列数
     * @param lengthRow   跨行数
     */
    public Cell(Object value, XSSFFont font, int startCol, int startRow, int lengthCol, int lengthRow) {
        this.font = font;
        this.value = value;
        this.startRow = startRow;
        this.startCol = startCol;
        this.lengthCol = lengthCol;
        this.lengthRow = lengthRow;
    }

    public Cell(Object value, int startCol, int startRow) {
        this(value, startCol, startRow, 1, 1);
    }

    public Cell(Object value, XSSFFont font, int startCol, int startRow) {
        this(value, font,  startCol, startRow, 1, 1);
    }

    public Cell(Object value, int startCol, int startRow, int lengthCol, int lengthRow) {
        this(value, null, startCol, startRow, lengthCol, lengthRow);
    }

    public void addCellRangeAddress(Sheet sheet) {
        addCellRangeAddress(sheet, 0 ,0, null);
    }

    /**
     * @param sheet         Sheet对象
     * @param scaleCol      列偏移量
     * @param scaleRow      行偏移量
     */
    public void addCellRangeAddress(Sheet sheet, int scaleCol, int scaleRow, CellStyle cellStyle) {
        String textValue = ExcelUtil.getTextObject(value, sheet.getDateTimeFormatter());

        XSSFCell cell;
        XSSFRow row = sheet.getSheet().getRow(scaleRow + startRow);
        if (row == null) {
            row = sheet.getSheet().createRow(scaleRow + startRow);
        }

        cell = row.createCell(scaleCol + startCol);
        if (cellStyle != null) {
            cell.setCellStyle(cellStyle);
        } else {
            cell.setCellStyle(sheet.getCellStyle());
        }

        XSSFRichTextString richString = new XSSFRichTextString(textValue);
        if (font != null) {
            richString.applyFont(font);
        }
        cell.setCellValue(richString);

        //
        if (lengthCol > 1 || lengthRow > 1) {
            // 合并单元格
            CellRangeAddress cellAddresses = new CellRangeAddress( scaleRow + startRow, scaleRow + getEndY(), scaleCol + startCol, scaleCol + getEndX());
            mergedRegion(sheet.getSheet(), cellAddresses, sheet.getMergeCount());
            defaultStyle(sheet.getSheet(), cellAddresses);

            sheet.mergeCountIncrement();
        }
    }

    /**
     * 合并单元格默认的样式
     */
    private void defaultStyle(XSSFSheet sheet, CellRangeAddress cellAddresses) {
        RegionUtil.setBorderBottom(BorderStyle.THIN, cellAddresses, sheet);
        RegionUtil.setBorderTop(BorderStyle.THIN, cellAddresses, sheet);
        RegionUtil.setBorderLeft(BorderStyle.THIN, cellAddresses, sheet);
        RegionUtil.setBorderRight(BorderStyle.THIN, cellAddresses, sheet);
    }

    /** cell 内容  */
    private Object value;

    /** 起始列号 */
    private int startCol;

    /** 起始行号 */
    private int startRow;

    /** 跨列数 */
    private int lengthCol;

    /** 跨行数 */
    private int lengthRow;

    private XSSFFont font;

    public int getEndX() {
        return startCol + lengthCol - 1;
    }

    public int getEndY() {
        return startRow + lengthRow - 1;
    }

    private void mergedRegion(XSSFSheet sheet, CellRangeAddress cellAddresses, int mergeCount) {
        CTWorksheet ctWorksheet = sheet.getCTWorksheet();
        CTMergeCells ctMergeCells = mergeCount > 0 ?ctWorksheet.getMergeCells():ctWorksheet.addNewMergeCells();
        CTMergeCell ctMergeCell = ctMergeCells.addNewMergeCell();
        ctMergeCell.setRef(cellAddresses.formatAsString());
    }
}
