package org.example.Utils;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * ESC打印指令工具类（对应原C# EscPrintHelper）
 * 功能：生成各类ESC打印控制指令字节数组，提供打印指令组装工具方法
 */
public final class EscPrintHelper {

    // ------------------- 常量定义（对应原C#静态常量） -------------------
    // 字体宽度常量（保留小数位精度）
    public static final double FONT_A_WIDTH = Math.round(2.0 * 10) / 10.0; // 等价Math.Round(2.0, 1)
    public static final double FONT_B_WIDTH = Math.round(1.0 * 10) / 10.0; // 等价Math.Round(1.0, 1)

    // 控制字符常量（全大写，符合Java命名规范）
    public static final byte ESC = 27;    // Esc
    public static final byte FS = 28;     // FS
    public static final byte GS = 29;     // GS
    public static final byte DLE = 16;    // DLE
    public static final byte EOT = 4;     // EOT
    public static final byte ENQ = 5;     // ENQ
    public static final byte SP = 32;     // SP
    public static final byte HT = 9;      // HT
    public static final byte LF = 10;     // LF
    public static final byte CR = 13;     // CR
    public static final byte FF = 12;     // FF
    public static final byte CAN = 24;    // CAN

    // 分隔符常量
    public static final String SEPARATOR = "-------------------------";

    // Windows默认编码（对应C# Encoding.Default）
    private static final Charset DEFAULT_CHARSET = StandardCharsets.ISO_8859_1;

    // 私有化构造方法，禁止实例化（静态工具类）
    private EscPrintHelper() {
    }

    // ------------------- 核心打印指令方法 -------------------

    /**
     * 初始化打印机（对应原InitPrinter）
     */
    public static byte[] initPrinter() {
        return new byte[]{ESC, 64};
    }

    /**
     * 收据模式下开启/关闭标签模式（对应原OpenOrCloseLableModelInReceip）
     */
    public static byte[] openOrCloseLableModelInReceip(boolean open) {
        byte[] array = new byte[]{31, 27, 31, 0, 1, 1, (byte) 128, 0};
        array[7] = (byte) (open ? 1 : 0);
        return array;
    }

    /**
     * 标签结束指令（对应原EndOfLable）
     */
    public static byte[] endOfLable() {
        return new byte[]{31, 27, 31, 0, 1, 1, (byte) 129};
    }

    /**
     * 设置标签宽度（对应原SetTheLableWidth）
     */
    public static byte[] setTheLableWidth(int width) {
        return new byte[]{
                31,
                27,
                31,
                0,
                1,
                1,
                (byte) 131,
                (byte) width
        };
    }

    /**
     * 设置绝对打印位置（对应原SetAbsolutePrintPosition）
     */
    public static byte[] setAbsolutePrintPosition(int m, int n) {
        return new byte[]{
                ESC,
                36,
                (byte) m,
                (byte) n
        };
    }

    /**
     * 选择字符大小（对应原SelectCharacterSize）
     */
    public static byte[] selectCharacterSize(int n) {
        return new byte[]{
                GS,
                33,
                (byte) n
        };
    }

    /**
     * 添加打印文本（对应原AddValueStr）
     */
    public static byte[] addValueStr(String value) {
        if (value == null || value.trim().isEmpty()) {
            return null;
        }
        return value.getBytes(DEFAULT_CHARSET);
    }

    /**
     * 打印并换行（默认1行，对应原PrintAndFeedLine()）
     */
    public static byte[] printAndFeedLine() {
        return printAndFeedLine(1);
    }

    /**
     * 打印并换行（指定行数，对应原PrintAndFeedLine(int lineNum)）
     */
    public static byte[] printAndFeedLine(int lineNum) {
        byte[] array = new byte[lineNum];
        for (int i = 0; i < lineNum; i++) {
            array[i] = LF;
        }
        return array;
    }

    /**
     * 加粗开启（对应原BoldOn）
     */
    public static byte[] boldOn() {
        return new byte[]{ESC, 69, 1};
    }

    /**
     * 加粗关闭（对应原BoldOff）
     */
    public static byte[] boldOff() {
        return new byte[]{ESC, 69, 0};
    }

    /**
     * 左对齐（对应原AlignLeft）
     */
    public static byte[] alignLeft() {
        return new byte[]{ESC, 97, 0};
    }

    /**
     * 右对齐（对应原AlignRight）
     */
    public static byte[] alignRight() {
        return new byte[]{ESC, 97, 2};
    }

    /**
     * 居中对齐（对应原AlignCenter）
     */
    public static byte[] alignCenter() {
        return new byte[]{ESC, 97, 1};
    }

    /**
     * 设置水平位置（对应原SetHorizontalPosition）
     * 注：原代码中array[2]被重复赋值为0，已保留该逻辑
     */
    public static byte[] setHorizontalPosition(byte col) {
        byte[] array = new byte[4];
        array[0] = ESC;
        array[1] = 68;
        array[2] = col;
        array[2] = 0; // 原代码逻辑：覆盖为0
        return array;
    }

    /**
     * 设置加粗模式（对应原SetBold）
     */
    public static byte[] setBold(int boldMode) {
        switch (boldMode) {
            case 0:
                return boldOff();
            case 1:
                return boldOn();
            default:
                return null;
        }
    }

    /**
     * 设置字体模式（对应原SetFontMode）
     */
    public static byte[] setFontMode(int fontMode) {
        byte[] array = new byte[]{ESC, 77, 0};
        switch (fontMode) {
            case 0:
                array[2] = 0;
                break;
            case 1:
                array[2] = 1;
                break;
        }
        return array;
    }

    /**
     * 设置字体大小模式（对应原SetFontSizeMode）
     */
    public static byte[] setFontSizeMode(int fontSizeMode) {
        byte[] array = new byte[]{ESC, 33, 0};
        switch (fontSizeMode) {
            case 0:
                array[2] = 0;
                break;
            case 1:
                array[2] = 16;
                break;
            case 2:
                array[2] = 32;
                break;
        }
        return array;
    }

    /**
     * 设置对齐模式（对应原SetAlign）
     */
    public static byte[] setAlign(int alignMode) {
        switch (alignMode) {
            case 0:
                return alignLeft();
            case 1:
                return alignCenter();
            case 2:
                return alignRight();
            default:
                return null;
        }
    }

    /**
     * 部分切纸（对应原feedPaperCutPartial）
     */
    public static byte[] feedPaperCutPartial() {
        return new byte[]{GS, 86, 66, 0};
    }

    /**
     * 获取文本打印示例指令（对应原GetTextPrintCommand）
     */
    public static List<byte[]> getTextPrintCommand() {
        List<byte[]> list = new ArrayList<>();
        list.add(openOrCloseLableModelInReceip(true));
        list.add(setTheLableWidth(40));
        list.add(initPrinter());
        list.add(setAbsolutePrintPosition(50, 0));
        list.add(selectCharacterSize(17));
        list.add(addValueStr("商品"));
        list.add(setAbsolutePrintPosition(250, 0));
        list.add(addValueStr("价格"));
        list.add(printAndFeedLine());
        list.add(printAndFeedLine());
        list.add(initPrinter());
        list.add(setAbsolutePrintPosition(30, 0));
        list.add(addValueStr("黄焖鸡"));
        list.add(setAbsolutePrintPosition(220, 0));
        list.add(addValueStr("5元"));
        list.add(printAndFeedLine());
        list.add(initPrinter());
        list.add(setAbsolutePrintPosition(30, 0));
        list.add(addValueStr("黄焖鸡呀"));
        list.add(setAbsolutePrintPosition(220, 0));
        list.add(addValueStr("6元"));
        list.add(printAndFeedLine());
        list.add(endOfLable());
        return list;
    }

    /**
     * 合并字节数组（对应原byteMerger）
     */
    public static byte[] byteMerger(byte[][] byteList) {
        if (byteList == null || byteList.length == 0) {
            return new byte[0];
        }

        // 计算总长度
        int totalLength = 0;
        for (byte[] bytes : byteList) {
            if (bytes != null) {
                totalLength += bytes.length;
            }
        }

        // 合并数组
        byte[] mergedArray = new byte[totalLength];
        int currentIndex = 0;
        for (byte[] bytes : byteList) {
            if (bytes != null) {
                for (byte b : bytes) {
                    mergedArray[currentIndex++] = b;
                }
            }
        }

        return mergedArray;
    }
}