package com.tiedup.remake.util;

import com.tiedup.remake.core.TiedUpMod;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.util.RandomSource;

/**
 * Random name generator for NPCs (Damsels, Kidnappers).
 *
 *
 * Loads names from assets/tiedup/names/female_names.txt
 * Contains 5001 female first names from the original mod.
 */
public class NameGenerator {

    private static final RandomSource RANDOM = RandomSource.create();

    /**
     * Female names loaded from file.
     * Used for both Damsels and Kidnappers (all NPCs are female).
     */
    private static List<String> NAMES = null;

    /**
     * Fallback names if file loading fails.
     */
    private static final List<String> FALLBACK_NAMES = List.of(
        "Alice",
        "Emma",
        "Sophia",
        "Olivia",
        "Isabella",
        "Mia",
        "Charlotte",
        "Amelia",
        "Harper",
        "Evelyn"
    );

    /**
     * Load names from the resource file.
     * Called lazily on first name request.
     * Synchronized to prevent race conditions during parallel entity spawning.
     */
    private static synchronized void loadNames() {
        if (NAMES != null) return;

        NAMES = new ArrayList<>();
        String resourcePath = "/assets/tiedup/names/female_names.txt";

        try (
            InputStream is = NameGenerator.class.getResourceAsStream(
                resourcePath
            )
        ) {
            if (is == null) {
                TiedUpMod.LOGGER.error(
                    "[NameGenerator] Could not find resource: {}",
                    resourcePath
                );
                NAMES = new ArrayList<>(FALLBACK_NAMES);
                return;
            }

            try (
                BufferedReader reader = new BufferedReader(
                    new InputStreamReader(is, StandardCharsets.UTF_8)
                )
            ) {
                String line;
                while ((line = reader.readLine()) != null) {
                    line = line.trim();
                    if (!line.isEmpty()) {
                        NAMES.add(line);
                    }
                }
            }

            TiedUpMod.LOGGER.info(
                "[NameGenerator] Loaded {} names from file",
                NAMES.size()
            );
        } catch (IOException e) {
            TiedUpMod.LOGGER.error(
                "[NameGenerator] Failed to load names: {}",
                e.getMessage()
            );
            NAMES = new ArrayList<>(FALLBACK_NAMES);
        }

        if (NAMES.isEmpty()) {
            NAMES = new ArrayList<>(FALLBACK_NAMES);
        }
    }

    /**
     * Get a random name from the loaded list.
     *
     * @return Random name
     */
    public static String getRandomName() {
        loadNames();
        return NAMES.get(RANDOM.nextInt(NAMES.size()));
    }

    /**
     * Get a random damsel name.
     *
     * @return Random damsel name
     */
    public static String getRandomDamselName() {
        return getRandomName();
    }

    /**
     * Get a random kidnapper name.
     * Same as damsel - all NPCs are female.
     *
     * @return Random kidnapper name
     */
    public static String getRandomKidnapperName() {
        return getRandomName();
    }

    /**
     * Get a random maid name.
     * Same as damsel - all NPCs are female.
     *
     * @return Random maid name
     */
    public static String getRandomMaidName() {
        return getRandomName();
    }

    /**
     * Get a random slave trader name.
     * Same as damsel - all NPCs are female.
     *
     * @return Random trader name
     */
    public static String getRandomTraderName() {
        return getRandomName();
    }

    /**
     * Get the total number of available names.
     *
     * @return Number of names loaded
     */
    public static int getNameCount() {
        loadNames();
        return NAMES.size();
    }
}
