from __future__ import annotations

from typing import Any

from Mama.models import (
    ConversationState,
    ExecutionContext,
    LlmConfig,
    RetrievalConfig,
    StorageConfig,
)


def build_execution_context(data: dict[str, Any]) -> ExecutionContext:
    required = ["tenant_id", "user_id", "session_id", "kb_id"]
    missing = [name for name in required if not data.get(name)]
    if missing:
        raise ValueError(f"missing required execution context fields: {', '.join(missing)}")

    llm_data = data.get("llm", {})
    retrieval_data = data.get("retrieval", {})
    storage_data = data.get("storage", {})
    conv_data = data.get("conversation", {})

    return ExecutionContext(
        tenant_id=str(data["tenant_id"]),
        user_id=str(data["user_id"]),
        session_id=str(data["session_id"]),
        kb_id=str(data["kb_id"]),
        llm=LlmConfig(
            provider=str(llm_data.get("provider", "dummy")),
            model=str(llm_data.get("model", "dummy")),
            parameters=dict(llm_data.get("parameters", {})),
        ),
        retrieval=RetrievalConfig(
            search_type=str(retrieval_data.get("search_type", "similarity")),
            k=int(retrieval_data.get("k", 4)),
            filters=dict(retrieval_data.get("filters", {})),
        ),
        storage=StorageConfig(
            backend=str(storage_data.get("backend", "faiss_local")),
            params=dict(storage_data.get("params", {})),
        ),
        conversation=ConversationState(
            messages=list(conv_data.get("messages", [])),
            max_messages=int(conv_data.get("max_messages", 20)),
        ),
        metadata=dict(data.get("metadata", {})),
    )
