package com.tiedup.remake.client.renderer.obj;

import com.tiedup.remake.core.TiedUpMod;
import java.util.HashMap;
import java.util.Map;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.jetbrains.annotations.Nullable;

/**
 * Singleton registry/cache for loaded OBJ models.
 * Models are loaded on-demand and cached for reuse.
 * Client-side only.
 */
@OnlyIn(Dist.CLIENT)
public class ObjModelRegistry {

    private static final Map<ResourceLocation, ObjModel> CACHE =
        new HashMap<>();
    private static boolean initialized = false;

    private ObjModelRegistry() {
        // Singleton utility class
    }

    /**
     * Initialize the registry and preload known models.
     * Called during FMLClientSetupEvent.
     */
    public static void init() {
        if (initialized) {
            return;
        }

        TiedUpMod.LOGGER.info("Initializing ObjModelRegistry...");

        // Preload known 3D models
        preloadModel("tiedup:models/obj/ball_gag/model.obj");
        preloadModel("tiedup:models/obj/choke_collar_leather/model.obj");

        initialized = true;
        TiedUpMod.LOGGER.info(
            "ObjModelRegistry initialized with {} models",
            CACHE.size()
        );
    }

    /**
     * Preload a model into the cache.
     *
     * @param path Resource path (e.g., "tiedup:models/obj/ball_gag.obj")
     */
    private static void preloadModel(String path) {
        ResourceLocation location = ResourceLocation.tryParse(path);
        if (location != null) {
            ObjModel model = ObjModelLoader.load(location);
            if (model != null) {
                CACHE.put(location, model);
                TiedUpMod.LOGGER.debug("Preloaded OBJ model: {}", path);
            } else {
                TiedUpMod.LOGGER.warn("Failed to preload OBJ model: {}", path);
            }
        }
    }

    /**
     * Get a model from the cache, loading it if not present.
     *
     * @param location ResourceLocation of the .obj file
     * @return The loaded model, or null if not found/failed to load
     */
    @Nullable
    public static ObjModel get(ResourceLocation location) {
        if (location == null) {
            return null;
        }

        return CACHE.computeIfAbsent(location, ObjModelLoader::load);
    }

    /**
     * Get a model by string path.
     *
     * @param path Resource path (e.g., "tiedup:models/obj/ball_gag.obj")
     * @return The loaded model, or null if not found/failed to load
     */
    @Nullable
    public static ObjModel get(String path) {
        ResourceLocation location = ResourceLocation.tryParse(path);
        return location != null ? get(location) : null;
    }

    /**
     * Check if a model is loaded in the cache.
     */
    public static boolean isLoaded(ResourceLocation location) {
        return CACHE.containsKey(location);
    }

    /**
     * Clear the cache.
     * Useful for resource reload events.
     */
    public static void clearCache() {
        CACHE.clear();
        initialized = false;
        TiedUpMod.LOGGER.info("ObjModelRegistry cache cleared");
    }

    /**
     * Get the number of loaded models.
     */
    public static int getCachedCount() {
        return CACHE.size();
    }
}
