/*
 * Original project: RedEnvelope by KaguyaStudio-MC
 * Original project link: https://github.com/KaguyaStudio-MC/RedEnvelope
 * Modified by: LeisureTimeDock
 * This file is part of RedEnvelope
 * Licensed under Camellia License Version 1.0
 */

/*
 * Original project: RedEnvelope by KaguyaStudio-MC
 * Original project link: https://github.com/KaguyaStudio-MC/RedEnvelope
 * Modified by: LeisureTimeDock
 * This file is part of RedEnvelope
 * Licensed under Camellia License Version 1.0
 */

/*
 * Original project: RedEnvelope by KaguyaStudio-MC
 * Original project link: https://github.com/KaguyaStudio-MC/RedEnvelope
 * Modified by: LeisureTimeDock
 * This file is part of RedEnvelope
 * Licensed under Camellia License Version 1.0
 */

/*
 * Original project: RedEnvelope by KaguyaStudio-MC
 * Original project link: https://github.com/KaguyaStudio-MC/RedEnvelope
 * Modified by: LeisureTimeDock
 * This file is part of RedEnvelope
 * Licensed under Camellia License Version 1.0
 */

/*
 * Original project: RedEnvelope by KaguyaStudio-MC
 * Original project link: https://github.com/KaguyaStudio-MC/RedEnvelope
 * Modified by: LeisureTimeDock
 * This file is part of RedEnvelope
 * Licensed under Camellia License Version 1.0
 */

package top.leisuretimedock.redenvelope.core.capability;

import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.common.util.INBTSerializable;
import top.leisuretimedock.redenvelope.core.network.RedEnvelopePacket;
import top.leisuretimedock.redenvelope.core.network.SyncREStoragePacket;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

public class RedEnvelopeStorage implements INBTSerializable<CompoundTag> {
    // 使用两个并行列表来存储UUID和对应的红包数据
    private final List<UUID> uuids = new ArrayList<>();
    private final List<RedEnvelopePacket> packets = new ArrayList<>();

    public RedEnvelopeStorage() {}

    public RedEnvelopeStorage(RedEnvelopeStorage other) {
        this.uuids.addAll(other.uuids);
        this.packets.addAll(other.packets.stream().map(RedEnvelopePacket::copy).toList());
    }


    // ===== 数据操作方法 =====

    public void put(UUID uuid, RedEnvelopePacket packet) {
        int index = uuids.indexOf(uuid);
        if (index == -1) {
            uuids.add(uuid);
            packets.add(packet.copy());
        } else {
            packets.set(index, packet.copy());
        }
    }

    public void remove(UUID uuid) {
        int index = uuids.indexOf(uuid);
        if (index != -1) {
            uuids.remove(index);
            packets.remove(index);
        }
    }

    public RedEnvelopePacket get(UUID uuid) {
        int index = uuids.indexOf(uuid);
        return index != -1 ? packets.get(index) : null;
    }

    public void replace(UUID uuid, RedEnvelopePacket packet) {
        int index = uuids.indexOf(uuid);
        if (index != -1) {
            packets.set(index, packet.copy());
        }
    }

    public List<RedEnvelopePacket> values() {
        return Collections.unmodifiableList(packets);
    }

    public List<UUID> keys() {
        return Collections.unmodifiableList(uuids);
    }

    public boolean isEmpty() {
        return uuids.isEmpty();
    }

    public int size() {
        return uuids.size();
    }

    public void clear() {
        uuids.clear();
        packets.clear();
    }

    // ===== 静态辅助方法（替代原来的 Attachment 操作）=====

    public static void add(Player player, RedEnvelopePacket packet) {
        player.getCapability(RECapability.HONGBAO_STORAGE).ifPresent(storage -> {
            storage.put(packet.uuid(), packet.copy());
        });
    }

    public static RedEnvelopeStorage get(Player player) {
        return player.getCapability(RECapability.HONGBAO_STORAGE).orElse(new RedEnvelopeStorage());
    }

    // ===== NBT 序列化/反序列化 (替代原来的 Codec) =====

    private static final String KEY_UUIDS = "uuids";
    private static final String KEY_PACKETS = "packets";
    private static final String KEY_UUID_MOST = "uuid_most";
    private static final String KEY_UUID_LEAST = "uuid_least";

    @Override
    public CompoundTag serializeNBT() {
        CompoundTag tag = new CompoundTag();

        // 序列化 UUID 列表
        ListTag uuidList = new ListTag();
        for (UUID uuid : uuids) {
            CompoundTag uuidTag = new CompoundTag();
            uuidTag.putLong(KEY_UUID_MOST, uuid.getMostSignificantBits());
            uuidTag.putLong(KEY_UUID_LEAST, uuid.getLeastSignificantBits());
            uuidList.add(uuidTag);
        }
        tag.put(KEY_UUIDS, uuidList);

        // 序列化红包数据列表
        ListTag packetList = new ListTag();
        for (RedEnvelopePacket packet : packets) {
            // 需要 RedEnvelopePacket 实现序列化方法
            packetList.add(RedEnvelopePacket.serialize(packet));
        }
        tag.put(KEY_PACKETS, packetList);

        return tag;
    }

    @Override
    public void deserializeNBT(CompoundTag tag) {
        uuids.clear();
        packets.clear();

        // 反序列化 UUID 列表
        ListTag uuidList = tag.getList(KEY_UUIDS, Tag.TAG_COMPOUND);
        for (int i = 0; i < uuidList.size(); i++) {
            CompoundTag uuidTag = uuidList.getCompound(i);
            long most = uuidTag.getLong(KEY_UUID_MOST);
            long least = uuidTag.getLong(KEY_UUID_LEAST);
            uuids.add(new UUID(most, least));
        }

        // 反序列化红包数据列表
        ListTag packetList = tag.getList(KEY_PACKETS, Tag.TAG_COMPOUND);
        for (int i = 0; i < packetList.size(); i++) {
            RedEnvelopePacket packet = RedEnvelopePacket.deserialize(packetList.getCompound(i));
            packets.add(packet);
        }
    }

    public SyncREStoragePacket packet() {
        return new SyncREStoragePacket(serializeNBT());
    }
}