from __future__ import annotations

from nees.behavior.behavior_mapper import BehaviorMapper
from nees.decision.decision_engine import DecisionEngine
from nees.emotion.emotion_modulator import EmotionModulator
from nees.intent.extractor import IntentExtractor
from nees.llm.llm_adapter import LLMAdapter
from nees.memory.memory_selector import MemorySelector
from nees.trace.recorder import TraceRecorder
from nees.types import NEESRequest, ProcessResponse


class Orchestrator:
    def __init__(self, llm: str = "default") -> None:
        self._intent = IntentExtractor()
        self._emotion = EmotionModulator()
        self._memory = MemorySelector()
        self._decision = DecisionEngine()
        self._behavior = BehaviorMapper()
        self._llm = LLMAdapter(llm=llm)

    def run(self, request_data: dict, enable_trace: bool = False) -> ProcessResponse:
        request = NEESRequest.from_dict(request_data)
        recorder = TraceRecorder(mode="local", llm=self._llm.llm, enable_trace=enable_trace)

        intent = self._intent.detect(request)
        recorder.record(
            "intent",
            {"label": intent.label, "confidence": intent.confidence, "cues": intent.cues},
        )

        emotion = self._emotion.modulate(request, intent)
        recorder.record(
            "emotion",
            {
                "state": emotion.state,
                "intensity": emotion.intensity,
                "urgency": emotion.urgency,
                "cues": emotion.cues,
            },
        )

        memories = self._memory.select(request)
        recorder.record(
            "memory",
            {"selected": [item.__dict__ for item in memories], "count": len(memories)},
        )

        decision = self._decision.decide(intent, emotion, memories)
        recorder.record(
            "decision",
            {
                "category": decision.category,
                "framework": decision.framework,
                "goal": decision.goal,
            },
        )

        behavior = self._behavior.map(decision, emotion)
        recorder.record(
            "behavior",
            {
                "style": behavior.style,
                "structure": behavior.structure,
                "guardrails": behavior.guardrails,
            },
        )

        text = self._llm.generate(request, decision, behavior, emotion, memories)
        recorder.record("llm", {"adapter": self._llm.llm, "response_preview": text[:120]})

        summary = {
            "intent": intent.label,
            "emotion": emotion.state,
            "urgency": emotion.urgency,
            "framework": decision.framework,
            "memory_count": len(memories),
        }
        trace = recorder.build(summary=summary)

        return ProcessResponse(
            text=text,
            trace=trace,
            mode="local",
            session_id=request.session_id,
            metadata=summary,
        )
