"""Memory manager — filesystem CRUD for .fliiq/memory/."""

import os
import re
from pathlib import Path

_DATE_PATTERN = re.compile(r"^\d{4}-\d{2}-\d{2}$")
_DAILY_SEPARATOR = "\n\n---\n\n"


class MemoryManager:
    """Pure filesystem CRUD for the .fliiq/memory/ directory."""

    def __init__(self, memory_dir: Path | str):
        self.memory_dir = Path(memory_dir)

    @classmethod
    def from_project_root(cls, project_root: Path | str) -> "MemoryManager":
        return cls(Path(project_root) / ".fliiq" / "memory")

    def ensure_dirs(self) -> None:
        """Create memory/ and memory/skills/ and memory/jobs/ directories."""
        self.memory_dir.mkdir(parents=True, exist_ok=True)
        (self.memory_dir / "skills").mkdir(exist_ok=True)
        (self.memory_dir / "jobs").mkdir(exist_ok=True)

    def job_memory_path(self, job_name: str) -> Path:
        """Return the path to a job's memory file."""
        return self.memory_dir / "jobs" / f"{job_name}.md"

    def _resolve_path(self, name: str) -> Path:
        """Resolve a memory name to a file path.

        - Contains '/' → relative path (e.g., 'skills/fitness')
        - Matches YYYY-MM-DD → daily log
        - 'MEMORY' → root MEMORY.md
        - Otherwise → root-level file
        """
        # Strip .md extension if provided
        if name.endswith(".md"):
            name = name[:-3]

        if "/" in name:
            return self.memory_dir / f"{name}.md"
        if _DATE_PATTERN.match(name):
            return self.memory_dir / f"{name}.md"
        if name == "MEMORY":
            return self.memory_dir / "MEMORY.md"
        return self.memory_dir / f"{name}.md"

    def load_memory(self, name: str) -> str | None:
        """Load a memory file by name. Returns None if not found."""
        path = self._resolve_path(name)
        if not path.is_file():
            return None
        return path.read_text(encoding="utf-8")

    def save_memory(self, name: str, content: str) -> Path:
        """Create or overwrite a memory file."""
        path = self._resolve_path(name)
        path.parent.mkdir(parents=True, exist_ok=True)
        path.write_text(content, encoding="utf-8")
        return path

    def append_daily(self, date_str: str, content: str) -> Path:
        """Append to a daily log with separator."""
        path = self._resolve_path(date_str)
        path.parent.mkdir(parents=True, exist_ok=True)
        if path.is_file():
            existing = path.read_text(encoding="utf-8")
            path.write_text(existing + _DAILY_SEPARATOR + content, encoding="utf-8")
        else:
            path.write_text(content, encoding="utf-8")
        return path

    def list_skill_memories(self) -> list[str]:
        """List skill file stems (e.g., ['cantonese', 'fitness'])."""
        skills_dir = self.memory_dir / "skills"
        if not skills_dir.is_dir():
            return []
        return sorted(p.stem for p in skills_dir.glob("*.md"))

    def load_curated(self) -> str | None:
        """Shortcut to load MEMORY.md."""
        return self.load_memory("MEMORY")

    def save_curated(self, content: str) -> Path:
        """Shortcut to save MEMORY.md."""
        return self.save_memory("MEMORY", content)
