package com.tiedup.remake.dialogue.conversation;

import com.tiedup.remake.dialogue.DialogueContext;
import com.tiedup.remake.dialogue.SpeakerType;
import java.util.EnumSet;
import java.util.Set;

/**
 * Simplified conversation topics for interactive dialogue.
 * 8 core topics with significant effects, organized in 2 categories.
 *
 */
public enum ConversationTopic {
    // === ACTIONS (Always visible) ===
    COMPLIMENT(
        "conversation.compliment",
        "Compliment",
        Category.ACTION,
        null,
        null,
        "You look nice today.",
        "Give a compliment"
    ),

    COMFORT(
        "conversation.comfort",
        "Comfort",
        Category.ACTION,
        null,
        50,
        "It's going to be okay.",
        "Comfort them"
    ),

    PRAISE(
        "conversation.praise",
        "Praise",
        Category.ACTION,
        null,
        null,
        "You did well.",
        "Praise their behavior"
    ),

    SCOLD(
        "conversation.scold",
        "Scold",
        Category.ACTION,
        null,
        null,
        "That was wrong.",
        "Scold them"
    ),

    THREATEN(
        "conversation.threaten",
        "Threaten",
        Category.ACTION,
        null,
        null,
        "Don't make me...",
        "Make a threat"
    ),

    TEASE(
        "conversation.tease",
        "Tease",
        Category.ACTION,
        null,
        null,
        "Having fun?",
        "Tease them playfully"
    ),

    // === QUESTIONS (Basic inquiries) ===
    HOW_ARE_YOU(
        "conversation.how_are_you",
        "How are you?",
        Category.QUESTION,
        null,
        null,
        "How are you feeling?",
        "Ask about their state"
    ),

    WHATS_WRONG(
        "conversation.whats_wrong",
        "What's wrong?",
        Category.QUESTION,
        null,
        40,
        "Something seems off...",
        "Ask what's bothering them"
    );

    /**
     * Topic categories for UI organization.
     */
    public enum Category {
        ACTION("Actions"),
        QUESTION("Questions");

        private final String displayName;

        Category(String displayName) {
            this.displayName = displayName;
        }

        public String getDisplayName() {
            return displayName;
        }
    }

    private final String dialogueId;
    private final String displayText;
    private final Category category;
    private final Integer minMood;
    private final Integer maxMood;
    private final String playerText;
    private final String description;

    ConversationTopic(
        String dialogueId,
        String displayText,
        Category category,
        Integer minMood,
        Integer maxMood,
        String playerText,
        String description
    ) {
        this.dialogueId = dialogueId;
        this.displayText = displayText;
        this.category = category;
        this.minMood = minMood;
        this.maxMood = maxMood;
        this.playerText = playerText;
        this.description = description;
    }

    /**
     * Get the dialogue ID for this topic (used to fetch NPC response).
     */
    public String getDialogueId() {
        return dialogueId;
    }

    /**
     * Get the display text shown in the UI button.
     */
    public String getDisplayText() {
        return displayText;
    }

    /**
     * Get the topic category.
     */
    public Category getCategory() {
        return category;
    }

    /**
     * Get the text the player says when selecting this topic.
     */
    public String getPlayerText() {
        return playerText;
    }

    /**
     * Get a description of what this topic does.
     */
    public String getDescription() {
        return description;
    }

    /**
     * Check if this topic is available for the given context.
     *
     * @param context The dialogue context
     * @return true if the topic can be used
     */
    public boolean isAvailableFor(DialogueContext context) {
        // Check speaker type
        if (!isValidForSpeaker(context.getSpeakerType())) {
            return false;
        }

        // Check mood bounds
        int mood = context.getMood();
        if (minMood != null && mood < minMood) {
            return false;
        }
        if (maxMood != null && mood > maxMood) {
            return false;
        }

        return true;
    }

    /**
     * Check if this topic is valid for a speaker type.
     *
     * @param speakerType The speaker type
     * @return true if valid
     */
    public boolean isValidForSpeaker(SpeakerType speakerType) {
        // All 8 topics work with DAMSEL
        return speakerType == SpeakerType.DAMSEL;
    }

    /**
     * Check if this is an action topic (as opposed to a question).
     *
     * @return true if this is an action
     */
    public boolean isAction() {
        return category == Category.ACTION;
    }

    /**
     * Check if this is a positive action (compliment, comfort, praise).
     *
     * @return true if positive
     */
    public boolean isPositive() {
        return this == COMPLIMENT || this == COMFORT || this == PRAISE;
    }

    /**
     * Check if this is a negative action (scold, threaten).
     *
     * @return true if negative
     */
    public boolean isNegative() {
        return this == SCOLD || this == THREATEN;
    }

    /**
     * Get all topics available for a given context.
     *
     * @param context The dialogue context
     * @return Set of available topics
     */
    public static Set<ConversationTopic> getAvailableTopics(
        DialogueContext context
    ) {
        Set<ConversationTopic> available = EnumSet.noneOf(
            ConversationTopic.class
        );

        for (ConversationTopic topic : values()) {
            if (topic.isAvailableFor(context)) {
                available.add(topic);
            }
        }

        return available;
    }

    /**
     * Get topics by category that are available for a context.
     *
     * @param context The dialogue context
     * @param category The category to filter by
     * @return Set of available topics in that category
     */
    public static Set<ConversationTopic> getAvailableByCategory(
        DialogueContext context,
        Category category
    ) {
        Set<ConversationTopic> available = EnumSet.noneOf(
            ConversationTopic.class
        );

        for (ConversationTopic topic : values()) {
            if (topic.category == category && topic.isAvailableFor(context)) {
                available.add(topic);
            }
        }

        return available;
    }

    /**
     * Get the translation key for this topic's display text.
     *
     * @return Translation key
     */
    public String getTranslationKey() {
        return "conversation.topic." + this.name().toLowerCase();
    }
}
