"""
KIESSCLAW Base Agent
All agents inherit from this class.
"""

from __future__ import annotations
import logging
from pathlib import Path
from typing import Optional

from .llm import LLMRouter, LLMResponse
from .memory import MemoryEngine

logger = logging.getLogger(__name__)


class BaseAgent:
    """
    Base class for all KIESSCLAW agents.

    Provides: LLM access, memory, logging, directive loading.
    """

    codename: str = "BASE"
    name: str = "BaseAgent"
    description: str = ""

    def __init__(self, config: dict, memory: MemoryEngine):
        self.config = config
        self.memory = memory
        self.llm = LLMRouter(config.get("llm", {}))
        self.model = config.get("agents", {}).get(self.codename, {}).get("model")
        self.settings = config.get("agents", {}).get(self.codename, {}).get("settings", {})
        self.directive = self._load_directive()
        logger.info(f"[{self.codename}] Initialized - Model: {self.model}")

    def _load_directive(self) -> str:
        """Load agent directive from AgentMD file."""
        directive_path = Path(f"config/agents/{self.codename.lower()}.md")
        if directive_path.exists():
            return directive_path.read_text(encoding="utf-8")

        # Fallback to multi-agent file
        for fname in Path("config/agents").glob("*.md"):
            content = fname.read_text(encoding="utf-8")
            if f"# {self.codename}" in content:
                lines = content.split("\n")
                start = next((i for i, l in enumerate(lines) if f"# {self.codename}" in l), 0)
                end = next(
                    (i for i, l in enumerate(lines[start+1:], start+1)
                     if l.startswith("# ") and self.codename not in l),
                    len(lines)
                )
                return "\n".join(lines[start:end])

        return f"You are {self.name}, a sales agent in KIESSCLAW."

    def think(
        self,
        user_message: str,
        conversation_history: Optional[list[dict]] = None,
        context: Optional[str] = None,
    ) -> LLMResponse:
        """
        Core reasoning method. Send a message to the LLM with full context.
        """
        system = self.directive
        if context:
            system += f"\n\n## Current Context\n{context}"

        messages = conversation_history or []
        messages.append({"role": "user", "content": user_message})

        response = self.llm.chat(
            messages=messages,
            model=self.model,
            system=system,
        )

        self.memory.log(
            self.codename.lower(),
            f"**Task**: {user_message[:100]}...\n**Response**: {response.content[:200]}..."
        )
        return response

    def run(self, task: str, **kwargs) -> str:
        """Override in each agent with specific task logic."""
        raise NotImplementedError(f"{self.codename}.run() must be implemented")

    def report_status(self) -> dict:
        """Return current agent status."""
        state = self.memory.get_state(self.codename.lower())
        return {
            "codename": self.codename,
            "name": self.name,
            "model": self.model,
            "last_run": state.get("last_run"),
            "last_task": state.get("last_task"),
            "status": state.get("status", "idle"),
        }

    def update_status(self, status: str, task: str = None) -> None:
        """Update agent status in memory."""
        from datetime import datetime
        updates = {"status": status, "last_run": datetime.now().isoformat()}
        if task:
            updates["last_task"] = task
        self.memory.update_state(self.codename.lower(), updates)
