package net.moonleay.gimble.networking

import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.cbor.Cbor
import kotlinx.serialization.decodeFromByteArray
import kotlinx.serialization.encodeToByteArray
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking
import net.fabricmc.fabric.api.networking.v1.PacketByteBufs
import net.minecraft.network.PacketByteBuf
import net.moonleay.gimble.client.editor.ClientEditor
import net.moonleay.gimble.editor.state.EditorState
import net.moonleay.gimble.editor.util.GimblePolicy

object GimbleClient {

    fun registerPacketHandlers() {
        ClientPlayNetworking.registerGlobalReceiver(PacketIDs.TRANSFER_GIMBLE_POLICY_ID) { _, _, buf, _ ->
            onAllowedCheck(buf)
        }
    }

    private fun onAllowedCheck(buf: PacketByteBuf) {
        val policy = Cbor.decodeFromByteArray<GimblePolicy>(buf.readByteArray())
        ClientEditor.onAllowedCheck(policy) // Update the client's policy
    }

    /**
     * Sends the given [EditorState] to the server.
     */
    @OptIn(ExperimentalSerializationApi::class)
    fun sendEditorState(state: EditorState) {
        val buf = PacketByteBufs.create()
        buf.writeByteArray(Cbor.encodeToByteArray(state))
        ClientPlayNetworking.send(PacketIDs.UPDATE_EDITOR_STATE_ID, buf)
    }

    fun checkIfServerHasGimble(state: EditorState) {
        val buf = PacketByteBufs.create()
        buf.writeByteArray(Cbor.encodeToByteArray(state))
        ClientPlayNetworking.send(PacketIDs.GIMBLE_PRERENCE_CHECK_ID, buf)
    }
}
