"""Institutional memory store for Hive agents.

Manages persistent memory in .hive/memory/ directory.
Categories: patterns, incidents, decisions, daily logs.
"""

from __future__ import annotations

import logging
from datetime import datetime, timezone
from pathlib import Path  # noqa: TC003 -- used at runtime
from typing import Any

logger = logging.getLogger("hive.memory")


class MemoryStore:
    """Read/write interface for Hive institutional memory.

    Memory files:
    - patterns.md: Recurring code patterns, conventions
    - incidents.md: Past incidents, root causes, fixes
    - decisions.md: Key decisions, rationale, outcomes
    - YYYY-MM-DD.md: Daily session logs
    """

    def __init__(self, hive_dir: Path) -> None:
        self._memory_dir = hive_dir / "memory"
        self._memory_dir.mkdir(parents=True, exist_ok=True)

    def read(self, filename: str) -> str:
        """Read a memory file."""
        filepath = self._memory_dir / filename
        if filepath.exists():
            return filepath.read_text(encoding="utf-8")
        return ""

    def append(self, filename: str, content: str) -> None:
        """Append to a memory file."""
        filepath = self._memory_dir / filename
        with filepath.open("a", encoding="utf-8") as f:
            f.write(content)

    def write_daily_log(self, content: str) -> None:
        """Write to today's daily session log."""
        today = datetime.now(timezone.utc).strftime("%Y-%m-%d")
        filename = f"{today}.md"
        filepath = self._memory_dir / filename

        if not filepath.exists():
            header = f"# Session Log -- {today}\n\n"
            filepath.write_text(header, encoding="utf-8")

        timestamp = datetime.now(timezone.utc).strftime("%H:%M:%S UTC")
        entry = f"\n## {timestamp}\n{content}\n"
        self.append(filename, entry)

    def record_pattern(self, pattern_id: str, description: str, file_ref: str) -> None:
        """Record a new pattern in patterns.md."""
        entry = f"\n### {pattern_id}: {description}\n- File: `{file_ref}`\n- Recorded: {datetime.now(timezone.utc).isoformat()}\n"
        self.append("patterns.md", entry)
        logger.info("Pattern recorded: %s", pattern_id)

    def record_incident(
        self,
        incident_id: str,
        description: str,
        root_cause: str,
        fix: str,
        level: int,
    ) -> None:
        """Record an incident in incidents.md."""
        entry = f"""
### {incident_id}: {description}
- date: {datetime.now(timezone.utc).isoformat()}
- root-cause: {root_cause}
- fix-applied: {fix}
- resolution-level: {level}
"""
        self.append("incidents.md", entry)
        logger.info("Incident recorded: %s (Level %d)", incident_id, level)

    def record_decision(
        self,
        decision_id: str,
        description: str,
        rationale: str,
        approved_by: str,
    ) -> None:
        """Record a decision in decisions.md."""
        entry = f"""
### {decision_id}: {description}
- Date: {datetime.now(timezone.utc).isoformat()}
- Rationale: {rationale}
- Approved by: {approved_by}
- Outcome: Pending
"""
        self.append("decisions.md", entry)
        logger.info("Decision recorded: %s", decision_id)

    def search(self, query: str) -> list[dict[str, Any]]:
        """Search across all memory files for a query string.

        Returns matching entries with file name and context.
        """
        results: list[dict[str, Any]] = []
        query_lower = query.lower()

        for filepath in self._memory_dir.glob("*.md"):
            content = filepath.read_text(encoding="utf-8")
            if query_lower in content.lower():
                # Find relevant section
                lines = content.split("\n")
                for i, line in enumerate(lines):
                    if query_lower in line.lower():
                        context_start = max(0, i - 2)
                        context_end = min(len(lines), i + 5)
                        results.append(
                            {
                                "file": filepath.name,
                                "line": i + 1,
                                "context": "\n".join(lines[context_start:context_end]),
                            }
                        )
                        break  # One match per file

        return results
