import { extractErrorMsg } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
import { GLOBAL_LOG_A_LOT } from "../../core-constants.mjs";
const logalot = GLOBAL_LOG_A_LOT;
/**
 * @internal Helper to convert a Uint8Array to a Base64 string
 * @param uint8Array @
 * @returns Base64 string
 */
function uint8ArrayToBase64(uint8Array) {
    return new Promise((resolve, reject) => {
        const blob = new Blob([uint8Array], { type: 'application/octet-stream' });
        const reader = new FileReader();
        reader.onload = () => {
            const dataUrl = reader.result;
            // The result is a data URL: "data:application/octet-stream;base64,..."
            // We only want the Base64 part.
            const base64String = dataUrl.split(',')[1];
            resolve(base64String);
        };
        reader.onerror = (error) => reject(error);
        reader.readAsDataURL(blob);
    });
}
/**
 * @internal Helper to convert a Base64 string back to a Uint8Array
 * @param base64String to convert back to Uint8Array
 * @returns Uint8Array
 */
async function base64ToUint8Array(base64String) {
    // Use the fetch API to decode the Base64 string.
    // This is a modern and robust way to handle Base64 in the browser.
    const dataUrl = `data:application/octet-stream;base64,${base64String}`;
    const response = await fetch(dataUrl);
    const blob = await response.blob();
    const buffer = await blob.arrayBuffer();
    return new Uint8Array(buffer);
}
export async function serializeGraphToString({ graph }) {
    const lc = `[${serializeGraphToString.name}]`;
    try {
        if (logalot) {
            console.log(`${lc} starting... (I: 4ddb8803cf68e1d3d35f60680cb69825)`);
        }
        // 1. Serialize: Create a JSON-safe representation of the graph
        // We use a custom replacer to handle Uint8Array
        // const replacer = (key: string, value: any) => {
        //     if (value instanceof Uint8Array) {
        //         // This part is async, so we can't use it directly in JSON.stringify.
        //         // We must pre-process the object first.
        //         throw new Error("Cannot use async replacer. Pre-process the object first.");
        //     }
        //     return value;
        // };
        // Pre-process the graph to handle async Base64 conversion
        const serializableGraph = JSON.parse(JSON.stringify(graph)); // Deep clone to avoid mutation
        for (const key in serializableGraph) {
            if (graph[key].data instanceof Uint8Array) {
                serializableGraph[key].data = {
                    _dataType: 'Uint8Array_Base64',
                    value: await uint8ArrayToBase64(graph[key].data)
                };
            }
        }
        // 2. Stringify: Convert the serializable object to a JSON string
        const jsonString = JSON.stringify(serializableGraph);
        if (logalot) {
            console.log(`${lc} jsonString.length: ${jsonString.length} (I: 56dec8ad0931ab8ba9b5ca3d4e66be25)`);
        }
        return jsonString;
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
    finally {
        if (logalot) {
            console.log(`${lc} complete.`);
        }
    }
}
/**
 * Takes an incoming jsonString created via {@link serializeGraphToString}
 * and returns the original FlatIbGibGraph dto.
 *
 * @param jsonString
 * @returns graph that was originally serialized
 *
 * ## notes
 *
 * This serialize/deserialize is used in the compress/decompress fns:
 *
 * @see {@link compressIbGibToBlob}
 * @see {@link decompressIbGibFromBlob}
 * @see {@link compressIbGibGraphToString}
 * @see {@link decompressIbGibGraphFromString}
 */
export async function deserializeStringToGraph({ jsonString }) {
    const lc = `[${deserializeStringToGraph.name}]`;
    try {
        if (logalot) {
            console.log(`${lc} starting... (I: 52e1a1fb1adcc75168fbc6d819868825)`);
        }
        const reviver = (key, value) => {
            if (value && value._dataType === 'Uint8Array_Base64') {
                // Converting base64 to Uint8Array is async, so we can't use it
                // in JSON.parse. We will post-process the object.
                return value; // Return the placeholder for now
            }
            return value;
        };
        const parsedGraph = JSON.parse(jsonString, reviver);
        // Post-process to convert Base64 back to Uint8Array
        for (const key in parsedGraph) {
            const data = parsedGraph[key].data;
            if (data && data._dataType === 'Uint8Array_Base64') {
                parsedGraph[key].data = await base64ToUint8Array(data.value);
            }
        }
        return parsedGraph;
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
    finally {
        if (logalot) {
            console.log(`${lc} complete.`);
        }
    }
}
/**
 * Compresses an FlatIbGibGraph object into a Blob.
 * @param graph The FlatIbGibGraph object to compress.
 * @returns A Promise that resolves with the compressed Blob.
 */
export async function compressIbGibToBlob(graph) {
    const lc = `[${compressIbGibToBlob.name}]`;
    try {
        if (logalot) {
            console.log(`${lc} starting... (I: 8d306868b718596fe8f562bd5118d825)`);
        }
        // 1. Serialize: Create a JSON-safe representation of the graph and stringify
        const jsonString = await serializeGraphToString({ graph });
        // 2. Encode: Convert the string to a Uint8Array (UTF-8)
        const dataToCompress = new TextEncoder().encode(jsonString);
        // 3. Compress: Use the Compression Streams API
        const stream = new Response(dataToCompress).body;
        const compressedStream = stream.pipeThrough(new CompressionStream('gzip'));
        // Return the compressed data as a Blob
        return await new Response(compressedStream).blob();
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
    finally {
        if (logalot) {
            console.log(`${lc} complete.`);
        }
    }
}
/**
 * Decompresses a Blob back into an FlatIbGibGraph object.
 * @param compressedBlob The Blob containing the compressed graph data.
 * @returns A Promise that resolves with the original FlatIbGibGraph object.
 */
export async function decompressIbGibFromBlob(compressedBlob) {
    // 1. Decompress: Use the Decompression Streams API
    const decompressedStream = compressedBlob.stream().pipeThrough(new DecompressionStream('gzip'));
    // 2. Decode: Convert the decompressed stream back to a string
    const jsonString = await new Response(decompressedStream).text();
    // 3. Deserialize: Parse the JSON with a reviver to restore Uint8Arrays
    const parsedGraph = await deserializeStringToGraph({ jsonString });
    return parsedGraph;
}
/**
 * Compresses an FlatIbGibGraph object and returns a Base64 string representation.
 * @param graph The FlatIbGibGraph object to compress.
 * @returns A Promise that resolves with the compressed data as a Base64 string.
 */
export async function compressIbGibGraphToString({ graph }) {
    const lc = `[${compressIbGibGraphToString.name}]`;
    try {
        if (logalot) {
            console.log(`${lc} starting... (I: 1352f8540c08f0b725952df8f18c4825)`);
        }
        // 1. Get the compressed data as a Blob first.
        const compressedBlob = await compressIbGibToBlob(graph);
        // 2. Convert the Blob's binary data to a Uint8Array.
        const buffer = await compressedBlob.arrayBuffer();
        const uint8Array = new Uint8Array(buffer);
        // 3. Convert that Uint8Array to a Base64 string.
        return await uint8ArrayToBase64(uint8Array);
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
    finally {
        if (logalot) {
            console.log(`${lc} complete.`);
        }
    }
}
/**
 * Decompresses a Base64 string back into an FlatIbGibGraph object.
 * @param compressedBase64 The Base64 string containing the compressed graph data.
 * @returns A Promise that resolves with the original FlatIbGibGraph object.
 */
export async function decompressIbGibGraphFromString({ compressedBase64, }) {
    const lc = `[${decompressIbGibGraphFromString.name}]`;
    try {
        if (logalot) {
            console.log(`${lc} starting... (I: 5f3fa940a2c8f8d7b877978ae7f87825)`);
        }
        // 1. Convert the Base64 string back to a Uint8Array.
        const compressedUint8Array = await base64ToUint8Array(compressedBase64);
        // 2. Create a Blob from the Uint8Array.
        // The MIME type isn't strictly necessary for DecompressionStream but is good practice.
        const compressedBlob = new Blob([compressedUint8Array], { type: 'application/gzip' });
        // 3. Use our existing function to decompress the Blob.
        return await decompressIbGibFromBlob(compressedBlob);
    }
    catch (error) {
        console.error(`${lc} ${extractErrorMsg(error)}`);
        throw error;
    }
    finally {
        if (logalot) {
            console.log(`${lc} complete.`);
        }
    }
}
//# sourceMappingURL=other-helper.web.mjs.map