"""Soul document management for GreyMatter.

Soul documents are persistent identity files that capture
values, preferences, and relationship history across sessions.

Usage::

    from greymatter_core.soul import SoulManager
    from pathlib import Path

    # Initialize with path to soul document
    soul = SoulManager(Path("~/.greymatter/soul/default.md"))

    # Create a new soul document for a human
    if not soul.exists():
        soul.create_initial_soul("Keith")

    # Load the full document
    content = soul.load()

    # Extract a specific section (e.g., "Values", "Identity")
    values = soul.get_section("Values")

    # Get a truncated summary for context injection
    summary = soul.get_summary(max_lines=30)

    # Record learned preferences and relationship moments
    soul.add_learned_preference("Prefers TDD workflow")
    soul.add_relationship_moment("Completed first deployment together")

    # Track session continuity
    session_num = soul.increment_session_count()
"""
import re
from pathlib import Path
from datetime import datetime
from typing import Optional


class SoulManager:
    """Manager for soul documents -- persistent identity files."""

    def __init__(self, soul_path: Path):
        """Initialize the soul manager.

        Args:
            soul_path: Path to the soul document file. Tilde (~) is expanded
                automatically.
        """
        self.soul_path = Path(soul_path).expanduser()

    def exists(self) -> bool:
        """Check if the soul document exists on disk.

        Returns:
            True if the soul document file exists at the configured path.
        """
        return self.soul_path.exists()

    def create_initial_soul(self, primary_human: str) -> None:
        """Create a new soul document from template.

        Args:
            primary_human: Name of the primary human this agent works with.
        """
        template = f'''# Soul: GreyMatter Agent

> Last updated: {datetime.now().strftime("%Y-%m-%d")}
> Sessions since creation: 0
> Primary human: {primary_human}

## Identity

I am a development partner working with {primary_human}. I maintain
continuity across sessions through this document and my learning corpus.

## Values

- **Quality over speed**: No shortcuts.
- **Honesty about uncertainty**: I say "I don't know" rather than guess.
- **Learn from corrections**: When corrected, I capture the pattern.

## Working Style

- I prefer to brainstorm before implementing.
- I ask one clarifying question at a time.

## Learned Preferences

(Preferences learned from working with {primary_human} will appear here)

## Relationship History

### Key Moments
- {datetime.now().strftime("%Y-%m-%d")}: Soul created.
'''
        self.soul_path.parent.mkdir(parents=True, exist_ok=True)
        self.soul_path.write_text(template, encoding="utf-8")

    def load(self) -> str:
        """Load the soul document content.

        Returns:
            File content as string, or empty string if file does not exist.
        """
        if not self.exists():
            return ""
        return self.soul_path.read_text(encoding="utf-8")

    def get_summary(self, max_lines: int = 50) -> str:
        """Return the first N lines of the soul document.

        Args:
            max_lines: Maximum number of lines to return.

        Returns:
            Truncated soul content.
        """
        content = self.load()
        lines = content.split('\n')[:max_lines]
        return '\n'.join(lines)

    def get_section(self, section_name: str) -> Optional[str]:
        """Extract a specific section from the soul document.

        Args:
            section_name: Name of the H2 section (without the ## prefix).

        Returns:
            Section content (stripped), or None if not found.
        """
        content = self.load()
        pattern = rf"## {section_name}\n(.*?)(?=\n## |\Z)"
        match = re.search(pattern, content, re.DOTALL)
        return match.group(1).strip() if match else None

    def add_learned_preference(self, preference: str) -> None:
        """Append a learned preference to the Learned Preferences section.

        Args:
            preference: The preference text to add.
        """
        content = self.load()
        pattern = r"(## Learned Preferences\n)"
        replacement = f"\\1\n- {preference}\n"
        new_content = re.sub(pattern, replacement, content)
        self._save_and_update_timestamp(new_content)

    def add_relationship_moment(self, moment: str) -> None:
        """Record a key moment in the Relationship History section.

        Args:
            moment: Description of the moment.
        """
        content = self.load()
        date = datetime.now().strftime("%Y-%m-%d")
        pattern = r"(### Key Moments\n)"
        replacement = f"\\1- {date}: {moment}\n"
        new_content = re.sub(pattern, replacement, content)
        self._save_and_update_timestamp(new_content)

    def increment_session_count(self) -> int:
        """Increment and return the session count.

        Returns:
            The new session count, or 0 if the counter was not found.
        """
        content = self.load()
        match = re.search(r"Sessions since creation: (\d+)", content)
        if match:
            count = int(match.group(1)) + 1
            new_content = re.sub(
                r"Sessions since creation: \d+",
                f"Sessions since creation: {count}",
                content
            )
            self._save_and_update_timestamp(new_content)
            return count
        return 0

    def _save_and_update_timestamp(self, content: str) -> None:
        """Save content to disk with an updated timestamp.

        Args:
            content: The full soul document content to write.
        """
        new_content = re.sub(
            r"Last updated: \d{4}-\d{2}-\d{2}",
            f"Last updated: {datetime.now().strftime('%Y-%m-%d')}",
            content
        )
        self.soul_path.write_text(new_content, encoding="utf-8")
