/*
 *   This file is a part of the SteamWar software.
 *
 *   Copyright (C) 2025 SteamWar.de-Serverteam
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *   GNU Affero General Public License for more details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package de.steamwar.velocitycore.listeners;

import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.player.ServerPostConnectEvent;
import com.velocitypowered.api.proxy.player.ResourcePackInfo;
import de.steamwar.linkage.Linked;
import de.steamwar.velocitycore.VelocityCore;
import net.kyori.adventure.text.Component;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

// https://jd.papermc.io/velocity/3.4.0/com/velocitypowered/api/proxy/player/ResourcePackInfo.Builder.html#setHash(byte%5B%5D)
@Linked
public class TexturePackSystem extends BasicListener {

    private static final File PACKS_DIR = new File("/var/www/packs");
    private static final String BASE_ULR = "https://packs.steamwar.de/";
    private TreeMap<Integer, Integer> protocolVersionToPackVersion = new TreeMap<>();

    public TexturePackSystem() {
        // https://minecraft.wiki/w/Pack_format#List_of_resource_pack_formats
        // https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol_version_numbers
        protocolVersionToPackVersion.put(759, 9);
        protocolVersionToPackVersion.put(761, 12);
        protocolVersionToPackVersion.put(762, 13);
        protocolVersionToPackVersion.put(763, 15);
        protocolVersionToPackVersion.put(764, 18);
        protocolVersionToPackVersion.put(765, 22);
        protocolVersionToPackVersion.put(766, 32);
        protocolVersionToPackVersion.put(767, 34);
        protocolVersionToPackVersion.put(768, 42);
        protocolVersionToPackVersion.put(769, 46);
        protocolVersionToPackVersion.put(770, 55);
    }

    @Subscribe
    public void onLogin(ServerPostConnectEvent event) {
        if (event.getPreviousServer() != null) {
            return;
        }
        VelocityCore.schedule(() -> {
            TreeMap<Integer, File> fileTreeMap = new TreeMap<>();
            for (File fileEntry : PACKS_DIR.listFiles()) {
                try {
                    int packVersion = Integer.parseInt(fileEntry.getName().split("_")[0]);
                    fileTreeMap.put(packVersion, fileEntry);
                } catch (NumberFormatException e) {
                    // Ignore
                }
            }

            int playerVersion = event.getPlayer().getProtocolVersion().getProtocol();
            Map.Entry<Integer, Integer> packVersionEntry = protocolVersionToPackVersion.floorEntry(playerVersion);
            if (packVersionEntry == null) return;
            Map.Entry<Integer, File> selectedPackEntry = fileTreeMap.floorEntry(packVersionEntry.getValue());
            if (selectedPackEntry == null) return;
            File selectedPack = selectedPackEntry.getValue();

            String fileName = selectedPack.getName();
            fileName = fileName.substring(fileName.indexOf('_') + 1, fileName.lastIndexOf('.'));
            byte[] hash = hexStringToByteArray(fileName);

            ResourcePackInfo resourcePackInfo = VelocityCore.getProxy().createResourcePackBuilder(BASE_ULR + selectedPack.getName())
                    .setId(UUID.nameUUIDFromBytes(fileName.getBytes(StandardCharsets.UTF_8)))
                    .setHash(hash)
                    .setShouldForce(false)
                    .setPrompt(Component.text("The SteamWar TexturePack improves GUIs!"))
                    .build();
            event.getPlayer().sendResourcePacks(resourcePackInfo);
        }).delay(500, TimeUnit.MILLISECONDS).schedule();
    }

    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];

        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i+1), 16));
        }

        return data;
    }
}
