package com.tiedup.remake.entities;

import com.tiedup.remake.items.base.BindVariant;
import com.tiedup.remake.items.base.BlindfoldVariant;
import com.tiedup.remake.items.base.GagVariant;
import java.util.Random;

/**
 * Defines themed item sets for kidnappers.
 * Each theme groups compatible binds, gags, and blindfolds.
 *
 * Themes are selected randomly with weighted probabilities.
 * Higher weight = more common theme.
 *
 * Note: Natural themes (SLIME, VINE, WEB) are reserved for monsters.
 */
public enum KidnapperTheme {
    // === ROPE THEMES (most common) ===

    ROPE(
        BindVariant.ROPES,
        new GagVariant[] {
            GagVariant.ROPES_GAG,
            GagVariant.CLOTH_GAG,
            GagVariant.CLEAVE_GAG,
        },
        new BlindfoldVariant[] { BlindfoldVariant.CLASSIC },
        true, // supportsColor
        30 // weight (spawn probability)
    ),

    SHIBARI(
        BindVariant.SHIBARI,
        new GagVariant[] {
            GagVariant.ROPES_GAG,
            GagVariant.CLOTH_GAG,
            GagVariant.RIBBON_GAG,
        },
        new BlindfoldVariant[] { BlindfoldVariant.CLASSIC },
        true,
        15
    ),

    // === TAPE THEME ===

    TAPE(
        BindVariant.DUCT_TAPE,
        new GagVariant[] { GagVariant.TAPE_GAG, GagVariant.WRAP_GAG },
        new BlindfoldVariant[] { BlindfoldVariant.MASK },
        true,
        20
    ),

    // === LEATHER/BDSM THEME ===

    LEATHER(
        BindVariant.LEATHER_STRAPS,
        new GagVariant[] {
            GagVariant.BALL_GAG,
            GagVariant.BALL_GAG_STRAP,
            GagVariant.PANEL_GAG,
        },
        new BlindfoldVariant[] { BlindfoldVariant.MASK },
        false,
        15
    ),

    // === CHAIN THEME ===

    CHAIN(
        BindVariant.CHAIN,
        new GagVariant[] {
            GagVariant.CHAIN_PANEL_GAG,
            GagVariant.BALL_GAG_STRAP,
        },
        new BlindfoldVariant[] { BlindfoldVariant.MASK },
        false,
        10
    ),

    // === MEDICAL THEME ===

    MEDICAL(
        BindVariant.MEDICAL_STRAPS,
        new GagVariant[] {
            GagVariant.TUBE_GAG,
            GagVariant.SPONGE_GAG,
            GagVariant.BALL_GAG,
        },
        new BlindfoldVariant[] { BlindfoldVariant.MASK },
        false,
        8
    ),

    // === SCI-FI/BEAM THEME ===

    BEAM(
        BindVariant.BEAM_CUFFS,
        new GagVariant[] { GagVariant.BEAM_PANEL_GAG, GagVariant.LATEX_GAG },
        new BlindfoldVariant[] { BlindfoldVariant.MASK },
        false,
        5
    ),

    // === LATEX THEME (rare) ===

    LATEX(
        BindVariant.LATEX_SACK,
        new GagVariant[] { GagVariant.LATEX_GAG, GagVariant.TUBE_GAG },
        new BlindfoldVariant[] { BlindfoldVariant.MASK },
        false,
        3
    ),

    // === ASYLUM THEME (rare) ===

    ASYLUM(
        BindVariant.STRAITJACKET,
        new GagVariant[] {
            GagVariant.BITE_GAG,
            GagVariant.SPONGE_GAG,
            GagVariant.BALL_GAG,
        },
        new BlindfoldVariant[] { BlindfoldVariant.MASK },
        false,
        5
    ),

    // === RIBBON THEME (cute/playful) ===

    RIBBON(
        BindVariant.RIBBON,
        new GagVariant[] { GagVariant.RIBBON_GAG, GagVariant.CLOTH_GAG },
        new BlindfoldVariant[] { BlindfoldVariant.CLASSIC },
        false,
        8
    ),

    // === WRAP THEME ===

    WRAP(
        BindVariant.WRAP,
        new GagVariant[] { GagVariant.WRAP_GAG, GagVariant.TAPE_GAG },
        new BlindfoldVariant[] { BlindfoldVariant.MASK },
        false,
        5
    );

    private static final Random RANDOM = new Random();

    private final BindVariant bind;
    private final GagVariant[] gags;
    private final BlindfoldVariant[] blindfolds;
    private final boolean supportsColor;
    private final int weight;

    KidnapperTheme(
        BindVariant bind,
        GagVariant[] gags,
        BlindfoldVariant[] blindfolds,
        boolean supportsColor,
        int weight
    ) {
        this.bind = bind;
        this.gags = gags;
        this.blindfolds = blindfolds;
        this.supportsColor = supportsColor;
        this.weight = weight;
    }

    /**
     * Get the primary bind for this theme.
     */
    public BindVariant getBind() {
        return bind;
    }

    /**
     * Get compatible gags for this theme (ordered by preference).
     */
    public GagVariant[] getGags() {
        return gags;
    }

    /**
     * Get compatible blindfolds for this theme.
     */
    public BlindfoldVariant[] getBlindfolds() {
        return blindfolds;
    }

    /**
     * Check if this theme supports color variations.
     * Only themes with colorable items (rope, shibari, tape) support colors.
     */
    public boolean supportsColor() {
        return supportsColor;
    }

    /**
     * Get the spawn weight for this theme.
     * Higher weight = more common.
     */
    public int getWeight() {
        return weight;
    }

    /**
     * Get primary gag (first in list).
     * Used when only one gag is selected.
     */
    public GagVariant getPrimaryGag() {
        return gags.length > 0 ? gags[0] : GagVariant.BALL_GAG;
    }

    /**
     * Get a random gag from this theme's compatible list.
     */
    public GagVariant getRandomGag() {
        if (gags.length == 0) return GagVariant.BALL_GAG;
        return gags[RANDOM.nextInt(gags.length)];
    }

    /**
     * Get primary blindfold (first in list).
     */
    public BlindfoldVariant getPrimaryBlindfold() {
        return blindfolds.length > 0 ? blindfolds[0] : BlindfoldVariant.CLASSIC;
    }

    /**
     * Get a random blindfold from this theme's compatible list.
     */
    public BlindfoldVariant getRandomBlindfold() {
        if (blindfolds.length == 0) return BlindfoldVariant.CLASSIC;
        return blindfolds[RANDOM.nextInt(blindfolds.length)];
    }

    /**
     * Check if this theme has any blindfolds.
     */
    public boolean hasBlindfolds() {
        return blindfolds.length > 0;
    }

    /**
     * Get a random theme using weighted probability.
     * Higher weight themes are more likely to be selected.
     */
    public static KidnapperTheme getRandomWeighted() {
        int totalWeight = 0;
        for (KidnapperTheme theme : values()) {
            totalWeight += theme.weight;
        }

        int roll = RANDOM.nextInt(totalWeight);
        int cumulative = 0;

        for (KidnapperTheme theme : values()) {
            cumulative += theme.weight;
            if (roll < cumulative) {
                return theme;
            }
        }

        return ROPE; // Fallback
    }

    /**
     * Get a random theme using a specific Random instance.
     */
    public static KidnapperTheme getRandomWeighted(Random random) {
        int totalWeight = 0;
        for (KidnapperTheme theme : values()) {
            totalWeight += theme.weight;
        }

        int roll = random.nextInt(totalWeight);
        int cumulative = 0;

        for (KidnapperTheme theme : values()) {
            cumulative += theme.weight;
            if (roll < cumulative) {
                return theme;
            }
        }

        return ROPE; // Fallback
    }
}
