package com.rosetta.messenger.network

import okhttp3.WebSocket
import okio.ByteString
import kotlin.random.Random

/**
 * Chunker for splitting large packets into chunks
 * Matches Desktop implementation exactly
 */
class Chunker(
    private val webSocket: WebSocket,
    private val logger: (String) -> Unit = {}
) {
    companion object {
        private const val MAX_PACKET_SIZE_BEFORE_SLICE = 1024 // bytes
        private const val MAX_CHUNK_SIZE = 1024 // bytes
    }
    
    private fun log(message: String) {
        logger(message)
    }
    
    /**
     * Send stream, chunking if necessary
     */
    fun send(stream: Stream) {
        val data = stream.getStream()
        
        // If packet is small enough, send directly
        if (data.size <= MAX_PACKET_SIZE_BEFORE_SLICE) {
            webSocket.send(ByteString.of(*data))
            return
        }
        
        // Split into chunks
        val totalChunks = (data.size + MAX_CHUNK_SIZE - 1) / MAX_CHUNK_SIZE
        val chunkId = generateChunkId()
        
        log("📦 Chunking packet: ${data.size} bytes -> $totalChunks chunks (id: $chunkId)")
        
        for (i in 0 until totalChunks) {
            val start = i * MAX_CHUNK_SIZE
            val end = minOf((i + 1) * MAX_CHUNK_SIZE, data.size)
            val chunkData = data.sliceArray(start until end)
            
            val chunkPacket = PacketChunk().apply {
                this.chunkId = chunkId
                this.chunkIndex = i
                this.totalChunks = totalChunks
                this.data = chunkData
            }
            
            val chunkStream = chunkPacket.send()
            webSocket.send(ByteString.of(*chunkStream.getStream()))
            
            log("📦 Sent chunk $i/$totalChunks (${chunkData.size} bytes)")
        }
    }
    
    /**
     * Generate random chunk ID (like Desktop version)
     */
    private fun generateChunkId(): String {
        val chars = "abcdefghijklmnopqrstuvwxyz0123456789"
        return (1..26).map { chars[Random.nextInt(chars.length)] }.joinToString("")
    }
}
