package com.printer.demo.utils;

import android.graphics.*;
import android.text.TextPaint;

import com.printer.demo.bean.AlignedTable;

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

public class Table2Bitmap {
    private static final Table2Bitmap INS = new Table2Bitmap();
    public static Table2Bitmap get() { return INS; }

    private final TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
    private final int textSizePx;
    private final int lineHeightPx;
    private final int paddingPx = 4;

    private Table2Bitmap() {
        textSizePx = 24;
        paint.setTextSize(textSizePx);
        paint.setColor(Color.BLACK);
        paint.setTypeface(Typeface.MONOSPACE);
        Paint.FontMetrics fm = paint.getFontMetrics();
        lineHeightPx = (int) (fm.descent - fm.ascent + 2);
    }

    public Bitmap draw(AlignedTable table) {
        List<String> rows = table.getTableRows();
        if (rows == null || rows.isEmpty()) return null;

        int rowSpacing = table.getRowSpacing() + 1;
        int[] colWidths = table.getTableColWidth();        // 像素 或 汉字数
        boolean pixelMode = table.isWidthIsPixel();
        int colSpcPx = (int) (table.getColSpacing() * paint.measureText(" "));

        /* 1. 换算成像素列宽 */
        int[] colWidthPx = new int[colWidths.length];
        for (int i = 0; i < colWidths.length; i++) {
            colWidthPx[i] = pixelMode ? colWidths[i]                                // 已是像素
                    : (int) (colWidths[i] * paint.measureText("中")); // 汉字→像素
            colWidthPx[i] += colSpcPx;   // 右侧留白
        }
        int bitmapWidth = 0;
        for (int w : colWidthPx) bitmapWidth += w;
        bitmapWidth += paddingPx * 2;

        /* 2. 统计总高度（换行） */
        int totalLines = 0;
        List<int[]> lineCounter = new ArrayList<>();
        for (String row : rows) {
            String[] cells = row.split(table.getTableReg(), -1);
            int[] cols = new int[cells.length];
            int maxLine = 1;
            for (int i = 0; i < cells.length; i++) {
                int col = Math.min(i, colWidthPx.length - 1);
                List<String> lines = TextBreakUtil.breakIntoLines(
                        cells[i], colWidthPx[col] - colSpcPx, paint);
                cols[i] = lines.size();
                maxLine = Math.max(maxLine, cols[i]);
            }
            lineCounter.add(cols);
            totalLines += maxLine;
        }
        int bitmapHeight = totalLines * lineHeightPx * rowSpacing + paddingPx * 2;

        /* 3. 画 */
        Bitmap bmp = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bmp);
        canvas.drawColor(Color.WHITE);

        float y = -paint.ascent() + paddingPx;
        AlignedTable.Align[] aligns = table.getColumnAlignments();
        int rowIdx = 0;
        for (String row : rows) {
            String[] cells = row.split(table.getTableReg(), -1);
            int[] cols = lineCounter.get(rowIdx++);
            int maxLine = 0;
            for (int c : cols) maxLine = Math.max(maxLine, c);

            List<List<String>> cellLines = new ArrayList<>();
            for (int i = 0; i < cells.length; i++) {
                int col = Math.min(i, colWidthPx.length - 1);
                cellLines.add(TextBreakUtil.breakIntoLines(
                        cells[i], colWidthPx[col] - colSpcPx, paint));
            }

            for (int line = 0; line < maxLine; line++) {
                float x = paddingPx;
                for (int i = 0; i < cells.length; i++) {
                    int col = Math.min(i, colWidthPx.length - 1);
                    List<String> lines = cellLines.get(i);
                    String text = line < lines.size() ? lines.get(line) : "";
                    float tw = paint.measureText(text);
                    float drawX = x;
                    AlignedTable.Align align = col < aligns.length ? aligns[col] : AlignedTable.Align.LEFT;
                    if (align == AlignedTable.Align.CENTER)
                        drawX = x + (colWidthPx[col] - colSpcPx - tw) / 2;
                    else if (align == AlignedTable.Align.RIGHT)
                        drawX = x + (colWidthPx[col] - colSpcPx - tw);
                    canvas.drawText(text, drawX, y, paint);
                    x += colWidthPx[col];
                }
                y += lineHeightPx * rowSpacing;
            }
        }
        return bmp;
    }
}