import { SubscribeInfoType } from '@/services/socket/quota/interface';

/**
 * 将无符号整型数值型转化为二进制数组的方法
 *   value             无符号整型数值
 *   isLittleEndian    是否小端
 *   length            长度
 *  * @returns {Uint8Array}
 */
function uIntToByteArray(value: number, isLittleEndian: boolean, length: number): Uint8Array {
    const dataView = new DataView(new Uint8Array(length).buffer);
    switch (length) {
        case 2:
            dataView.setUint16(0, value, isLittleEndian);

            break;
        case 4:
            dataView.setUint32(0, value, isLittleEndian);

            break;
        case 8:
            dataView.setFloat64(0, value, isLittleEndian);

            break;
        default:
            // 此处暂时返回空的 Uint8Array ， 是否做异常处理，遇到情况再说
            console.warn('将无符号整型数值型转化为二进制数组传入的 【length】 不匹配');
            return new Uint8Array();
    }
    const array = new Uint8Array(dataView.buffer);
    return array;
}

/**
 * 将字符串转化为二进制数组的方法
 *   value             字符串
 *   islittleEndian    是否小端
 * @returns {Uint8Array}
 */
function stringToByteArray(value: string, isLittleEndian: boolean): Uint8Array {
    const buf = [];
    let offset = 0;
    for (let i = 0; i < value.length; i++) {
        if (value.charCodeAt(i) > 255) {
            const tmp = uIntToByteArray(value.charCodeAt(i), isLittleEndian, 2);
            buf[i + offset] = tmp[0];
            buf[i + offset + 1] = tmp[1];

            offset++;
        } else {
            buf[i + offset] = value.charCodeAt(i);
        }
    }
    return new Uint8Array(buf);
}

/**
 * 将某个订阅商品转为二进制
 * @param param SubscribeInfoType
 * @returns {Uint8Array}
 */
function subscribeInfoToByteArrary(param: SubscribeInfoType): Uint8Array {
    const { subState, exchangeCode, goodsCode } = param;
    const dataArray = new Uint8Array(66);

    dataArray[0] = subState;
    dataArray[1] = exchangeCode ? exchangeCode : 250;
    // 不足64byte需要补足
    const a = stringToByteArray(goodsCode, false);
    if (a.length <= 64) {
        const b = new Uint8Array(64);
        b.set(a);
        dataArray.set(b, 2);
    } else {
        // 此处有疑问，超了未做处理，
        console.warn(`goodsCode：${goodsCode} 转化为二进制后长度超过了 64位`);
        return new Uint8Array();
    }

    return dataArray;
}

/**
 * 将订阅商品列表转为二进制数组
 * @param arr 订阅商品列表
 * @param token
 * @param loginId 登录id
 */
export function subscribeInfosToByteArrary(arr: SubscribeInfoType[], token: string, loginId: any): Uint8Array {
    const count = arr.length;
    const dataArray = new Uint8Array(76 + 66 * count);
    // 处理登录账号id
    let postion = 0;
    dataArray.set(loginId.toBytes(false), postion);

    // 处理 token
    postion += 8;
    // Token,不足64byte需要补足
    const a = stringToByteArray(token, false);
    if (a.length <= 64) {
        const b = new Uint8Array(64);
        b.set(a);
        dataArray.set(b, postion);
    } else {
        // 此处有疑问，超了未做处理，
        console.warn('【token】 转化为二进制后长度超过了 64位');
        // return null;
    }

    // 处理 条数
    postion += 64;
    const coutTemp = uIntToByteArray(count, false, 4);
    dataArray.set(coutTemp, postion);
    postion += 4;
    // 处理 订阅的商品
    for (let i = 0; i < count; i++) {
        const item = subscribeInfoToByteArrary(arr[i]);
        dataArray.set(item, postion);
        postion += 66;
    }

    return dataArray;
}

/**
 * 将二进制数组转化为无符号整型数值的方法
 *   array             二进制数组
 *   islittleEndian    是否小端
 * @returns {number}
 */
export function byteArrayToUInt(array: Uint8Array, isLittleEndian: boolean): number {
    const dataView = new DataView(new Uint8Array(array).buffer);
    let value = 0;
    switch (array.length) {
        case 2:
            value = dataView.getUint16(0, isLittleEndian);
            break;
        case 4:
            value = dataView.getUint32(0, isLittleEndian);
            break;
    }
    return value;
}
