package com.mingliqiye.minecraft.enchantment.conflict.network;

import com.google.gson.Gson;
import com.mingliqiye.minecraft.enchantment.conflict.Mod;
import com.mingliqiye.minecraft.enchantment.conflict.config.ModConfig;
import com.mojang.logging.LogUtils;
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.codec.PacketCodec;
import net.minecraft.network.packet.CustomPayload;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Identifier;
import org.slf4j.Logger;

import static com.mingliqiye.minecraft.enchantment.conflict.Mod.MOD_ID;

public record ConfigPayload(ModConfig data) implements CustomPayload {

    private static final Logger LOGGER = LogUtils.getLogger();
    public static final CustomPayload.Id<ConfigPayload> TYPE =
            new CustomPayload.Id<>(Identifier.of(Mod.MOD_ID, "config_packet"));

    private static final Gson GSON = new Gson();


    public static final PacketCodec<PacketByteBuf, ConfigPayload> CODEC =
            PacketCodec.of((payload, buf) -> buf.writeString(GSON.toJson(payload.data())),
                    buf -> new ConfigPayload(GSON.fromJson(buf.readString(), ModConfig.class)));

    @Override
    public Id<? extends CustomPayload> getId() {
        return TYPE;
    }

    public static void initializeClient() {
        ClientPlayNetworking.registerGlobalReceiver(TYPE, (payload, ctx) -> {
            ctx.client().execute(() -> {
                ModConfig.setInstance(payload.data());
                LOGGER.info("Load Server {} config {}", MOD_ID, payload.data());
            });
        });
    }

    public static void initializeServer() {
        PayloadTypeRegistry.playS2C().register(TYPE, CODEC);
    }

    public static void sendToPlayer(ServerPlayerEntity player) {
        if (ServerPlayNetworking.canSend(player, TYPE)) {
            ServerPlayNetworking.send(player, new ConfigPayload(ModConfig.getInstance()));
            LOGGER.info("Send {} config to player({}) ok", Mod.MOD_ID, player.getName().getString());
        } else {
            LOGGER.error("Cannot send config to {}: channel not registered", player.getName());
        }
    }
}
