"""Conversation state tracking for player-NPC dialogues."""

from dataclasses import dataclass

from mudlib.dialogue import DialogueNode, DialogueTree
from mudlib.entity import Mob
from mudlib.npc_behavior import transition_state
from mudlib.player import Player


@dataclass
class ConversationState:
    """Tracks an active conversation between a player and NPC."""

    tree: DialogueTree
    current_node: str
    npc: Mob
    previous_state: str = "idle"


# Global registry of active conversations (keyed by player name)
active_conversations: dict[str, ConversationState] = {}


def start_conversation(player: Player, mob: Mob, tree: DialogueTree) -> DialogueNode:
    """Start a conversation between player and NPC.

    Args:
        player: The player starting the conversation
        mob: The NPC mob to talk to
        tree: The dialogue tree to use

    Returns:
        The root DialogueNode
    """
    # Store mob's previous state for restoration
    previous_state = mob.behavior_state

    # Transition mob to converse state
    transition_state(mob, "converse")

    # Create conversation state
    state = ConversationState(
        tree=tree,
        current_node=tree.root_node,
        npc=mob,
        previous_state=previous_state,
    )
    active_conversations[player.name] = state

    return tree.nodes[tree.root_node]


def advance_conversation(player: Player, choice_index: int) -> DialogueNode | None:
    """Advance conversation based on player's choice.

    Args:
        player: The player making the choice
        choice_index: 1-indexed choice number

    Returns:
        Next DialogueNode (conversation state updated but not ended yet),
        or None if invalid choice
    """
    conv = active_conversations.get(player.name)
    if conv is None:
        return None

    current = conv.tree.nodes[conv.current_node]

    # Validate choice index
    if choice_index < 1 or choice_index > len(current.choices):
        return None

    # Get the next node
    choice = current.choices[choice_index - 1]
    next_node = conv.tree.nodes[choice.next_node]

    # Update conversation state to new node
    conv.current_node = next_node.id

    return next_node


def end_conversation(player: Player) -> None:
    """End the active conversation and clean up state.

    Args:
        player: The player whose conversation to end
    """
    conv = active_conversations.get(player.name)
    if conv is None:
        return

    # Transition mob back to previous state
    transition_state(conv.npc, conv.previous_state)

    # Remove conversation state
    del active_conversations[player.name]


def get_conversation(player: Player) -> ConversationState | None:
    """Get the active conversation for a player.

    Args:
        player: The player to look up

    Returns:
        ConversationState if active, None otherwise
    """
    return active_conversations.get(player.name)
