import { Buffer } from 'buffer';  // 如果在浏览器环境需要引入buffer包

// PAYLOAD_LENGTHs 统一定义，实际根据你的需求调整
export const PAYLOAD_LENGTHs = 13;
export const MAX_PRESSURE_VALUE = 100; // 假设最大压力值
export const PAYLOAD_LENGTH = 33; // 根据实际计算确定
// 按钮消息对象转 buffer   返回-主页-视图  和  键盘按键的事件 转 buffer
export function toBufferBtn(message) {
    const buffer = new Uint8Array(PAYLOAD_LENGTHs + 1);
    let offset = 0;

    // 写入类型 (1 字节)
    buffer[offset++] = message.type;

    // 写入动作 (1 字节)
    buffer[offset++] = message.action;

    // 写入键码 (4 字节大端序)
    const keycodeBytes = new DataView(new ArrayBuffer(4));
    keycodeBytes.setUint32(0, message.keycode, false);
    buffer.set(new Uint8Array(keycodeBytes.buffer), offset);
    offset += 4;

    // 写入重复次数 (4 字节大端序)
    const repeatBytes = new DataView(new ArrayBuffer(4));
    repeatBytes.setUint32(0, message.repeat, false);
    buffer.set(new Uint8Array(repeatBytes.buffer), offset);
    offset += 4;

    // 写入修饰键状态 (4 字节大端序)
    const metaStateBytes = new DataView(new ArrayBuffer(4));
    metaStateBytes.setUint32(0, message.metaState, false);
    buffer.set(new Uint8Array(metaStateBytes.buffer), offset);

    return buffer;
}

//字符串转buffer
export function stringToUtf8ByteArray(text) {
    return new TextEncoder().encode(text)
}



//发送获取手机粘贴板内容的buffer
export function getClipboard() {
    // 1. 定义消息类型常量（根据实际项目值设置）
    const TYPE_SET_CLIPBOARD = 8 // 假设控制消息类型值为 1

    // 2. 创建消息对象
    const event = {
        buffer: null,
        action: TYPE_SET_CLIPBOARD
    }

    // 4. 计算缓冲区大小并分配空间
    // 结构：1字节类型 + 1字节粘贴标志 + 4字节文本长度 + N字节文本内容
    const buffer = Buffer.alloc(1)

    // 5. 写入缓冲区数据
    let offset = 0

    // 写入消息类型（1字节）
    offset = buffer.writeUInt8(event.action, offset)

    // 6. 将缓冲区挂载到消息对象
    event.buffer = buffer

    return buffer
}


//用于发送文字到手机上，把文字砖换成scrcpy接收的buffer格式
export function setClipboard(text, paste = true) {
    // 1. 定义消息类型常量（根据实际项目值设置）
    const TYPE_SET_CLIPBOARD = 9 // 假设控制消息类型值为 1

    // 2. 创建消息对象
    const event = {
        buffer: null,
        action: TYPE_SET_CLIPBOARD
    }

    // 3. 处理文本内容
    let textBytes = null
    let textLength = 0
    if (text) {
        textBytes = stringToUtf8ByteArray(text)
        textLength = textBytes.length
    }

    // 4. 计算缓冲区大小并分配空间
    // 结构：1字节类型 + 1字节粘贴标志 + 4字节文本长度 + N字节文本内容
    const buffer = Buffer.alloc(1 + 1 + 4 + textLength)

    // 5. 写入缓冲区数据
    let offset = 0

    // 写入消息类型（1字节）
    offset = buffer.writeUInt8(event.action, offset)

    // 写入粘贴标志（1字节：1=true，0=false）
    offset = buffer.writeUInt8(paste ? 1 : 0, offset)

    // 写入文本长度（4字节，大端序）
    offset = buffer.writeUInt32BE(textLength, offset)

    // 写入文本内容（如果有）
    if (textBytes) {
        textBytes.forEach((byte, index) => {
            buffer.writeUInt8(byte, offset + index)
        })
        offset += textBytes.length
    }

    // 6. 将缓冲区挂载到消息对象
    event.buffer = buffer

    return buffer
}


//buffer 转中文
export function bufferToString(buffer) {
    // 创建解码器（默认 UTF-8）
    const decoder = new TextDecoder('utf-8');
    // 直接解码 ArrayBuffer 或 Uint8Array
    return decoder.decode(buffer);
}


//传入两个二进制数组，判断buffer是否包含指定标识头
export function startsWithHeader(header, longArray) {
    // 边界检查：如果任一参数不是 Uint8Array 则抛出错误
    if (!(header instanceof Uint8Array) || !(longArray instanceof Uint8Array)) {
        throw new TypeError('参数必须是 Uint8Array 类型');
    }

    // 快速失败：如果标识比长数组还长，直接返回 false
    if (header.length > longArray.length) {
        return false;
    }

    // 逐个字节比对
    for (let i = 0; i < header.length; i++) {
        if (header[i] !== longArray[i]) {
            return false;
        }
    }

    return true;
}


//长数组 减去 短数组  返回新数组   验证buffer是否包含指定标识头
export function trimLongArray(arr1, arr2) {
    // 1. 确定长短数组
    const [longArray, shortArray] =
        arr1.length > arr2.length ? [arr1, arr2] : [arr2, arr1];

    // 2. 创建新的 ArrayBuffer（长度 = 长数组长度 - 短数组长度）
    const resultBuffer = new ArrayBuffer(longArray.length - shortArray.length);

    // 3. 将长数组后半部分拷贝到新缓冲区
    const resultView = new Uint8Array(resultBuffer);
    const startIndex = shortArray.length;
    resultView.set(longArray.subarray(startIndex));

    // 4. 去除前5个元素
    const trimmedResultView = resultView.slice(5);
    return trimmedResultView;
}


//base64转ArrayBuffer的方法
export function base64ToBinary(base64String) {
    // 以 Base64 字符串创建一个 binary string
    const binaryString = window.atob(base64String);
    // 将 binary string 转换为字节数组
    const bytes = new Uint8Array(binaryString.length);
    for (let i = 0; i < binaryString.length; i++) {
        bytes[i] = binaryString.charCodeAt(i);
    }
    return bytes.buffer; // 返回 ArrayBuffer
}




//鼠标抬起按下 移动的事件处理  对象转buffer
export const toBuffer = (message) => {
    const buffer = new Uint8Array(PAYLOAD_LENGTH + 1);
    let offset = 0;

    // 写入类型 (1 字节)
    buffer[offset++] = message.type;

    // 写入动作 (1 字节)
    buffer[offset++] = message.action;

    // 模拟 Java 的 long 类型 (8 字节)
    // 这里简化为写入 0 和 pointerId (共 8字节)
    const zeroLong = new Uint8Array(4).fill(0); // 前 4字节填 0
    buffer.set(zeroLong, offset);
    offset += 4;
    const pointerIdBytes = new DataView(new ArrayBuffer(4));
    pointerIdBytes.setUint32(0, message.pointerId, false); // 大端序
    buffer.set(new Uint8Array(pointerIdBytes.buffer), offset);
    offset += 4;

    // 写入坐标 (各 4字节)
    const xBytes = new DataView(new ArrayBuffer(4));
    xBytes.setUint32(0, message.position.point.x, false);
    buffer.set(new Uint8Array(xBytes.buffer), offset);
    offset += 4;

    const yBytes = new DataView(new ArrayBuffer(4));
    yBytes.setUint32(0, message.position.point.y, false);
    buffer.set(new Uint8Array(yBytes.buffer), offset);
    offset += 4;

    // 屏幕尺寸 (各 2字节)
    const widthBytes = new DataView(new ArrayBuffer(2));
    widthBytes.setUint16(0, message.position.screenSize.width, false);
    buffer.set(new Uint8Array(widthBytes.buffer), offset);
    offset += 2;

    const heightBytes = new DataView(new ArrayBuffer(2));
    heightBytes.setUint16(0, message.position.screenSize.height, false);
    buffer.set(new Uint8Array(heightBytes.buffer), offset);
    offset += 2;

    // 压力值 (2 字节)
    const pressureValue = Math.floor(message.pressure * MAX_PRESSURE_VALUE);
    const pressureBytes = new DataView(new ArrayBuffer(2));
    pressureBytes.setUint16(0, pressureValue, false);
    buffer.set(new Uint8Array(pressureBytes.buffer), offset);
    offset += 2;

    // 按钮状态 (4 字节)
    const buttonsBytes = new DataView(new ArrayBuffer(4));
    buttonsBytes.setUint32(0, message.buttons, false);
    buffer.set(new Uint8Array(buttonsBytes.buffer), offset);

    return buffer;
};



export function toBuffercomm(params) {
    // 假设 PAYLOAD_LENGTH 是一个预定义的常量值（例如4），根据实际情况调整
    const PAYLOAD_LENGTH = 4;

    // 创建指定长度的 Buffer
    const buffer = Buffer.alloc(PAYLOAD_LENGTH + 1);

    // 从参数对象中获取 type 值并写入 Buffer
    buffer.writeUInt8(params.type, 0);

    console.log("转换comm", buffer);
    return buffer;
}