"""In-memory TUI session-to-persona state management."""

from __future__ import annotations

from dataclasses import dataclass, field

from cleveragents.tui.persona.registry import PersonaRegistry
from cleveragents.tui.persona.schema import Persona


@dataclass(slots=True)
class PersonaState:
    """Tracks active persona per TUI session."""

    registry: PersonaRegistry
    active_by_session: dict[str, str] = field(default_factory=dict)
    preset_by_session: dict[str, str] = field(default_factory=dict)

    def _resolve_default_name(self) -> str:
        default = self.registry.ensure_default()
        return self.registry.get_last_persona() or default.name

    def active_name(self, session_id: str) -> str:
        if session_id not in self.active_by_session:
            self.active_by_session[session_id] = self._resolve_default_name()
        return self.active_by_session[session_id]

    def active_persona(self, session_id: str) -> Persona:
        name = self.active_name(session_id)
        persona = self.registry.get(name)
        if persona is None:
            persona = self.registry.ensure_default()
            self.active_by_session[session_id] = persona.name
        return persona

    def set_active_persona(self, session_id: str, persona_name: str) -> Persona:
        persona = self.registry.get(persona_name)
        if persona is None:
            raise ValueError(f"Unknown persona: {persona_name}")
        self.active_by_session[session_id] = persona.name
        self.registry.set_last_persona(persona.name)
        if session_id not in self.preset_by_session:
            self.preset_by_session[session_id] = "default"
        return persona

    def current_preset(self, session_id: str) -> str:
        if session_id not in self.preset_by_session:
            self.preset_by_session[session_id] = "default"
        return self.preset_by_session[session_id]

    def cycle_preset(self, session_id: str) -> str:
        persona = self.active_persona(session_id)
        if not persona.argument_presets:
            self.preset_by_session[session_id] = "default"
            return "default"
        names = [item.name for item in persona.argument_presets]
        current = self.current_preset(session_id)
        if current not in names:
            self.preset_by_session[session_id] = names[0]
            return names[0]
        idx = names.index(current)
        next_name = names[(idx + 1) % len(names)]
        self.preset_by_session[session_id] = next_name
        return next_name

    def effective_arguments(self, session_id: str) -> dict[str, object]:
        persona = self.active_persona(session_id)
        preset = self.current_preset(session_id)
        return persona.effective_arguments(preset)
