"""Deep focus mode — single-problem context for Timmy.

Persists focus state to a JSON file so Timmy can maintain narrow,
deep attention on one problem across session restarts.

Usage:
    from timmy.focus import focus_manager

    focus_manager.set_topic("three-phase loop")
    topic = focus_manager.get_topic()       # "three-phase loop"
    ctx   = focus_manager.get_focus_context()  # prompt injection string
    focus_manager.clear()
"""

import json
import logging
from pathlib import Path

logger = logging.getLogger(__name__)

_DEFAULT_STATE_DIR = Path.home() / ".timmy"
_STATE_FILE = "focus.json"


class FocusManager:
    """Manages deep-focus state with file-backed persistence."""

    def __init__(self, state_dir: Path | None = None) -> None:
        self._state_dir = state_dir or _DEFAULT_STATE_DIR
        self._state_file = self._state_dir / _STATE_FILE
        self._topic: str | None = None
        self._mode: str = "broad"
        self._load()

    # ── Public API ────────────────────────────────────────────────

    def get_topic(self) -> str | None:
        """Return the current focus topic, or None if unfocused."""
        return self._topic

    def get_mode(self) -> str:
        """Return 'deep' or 'broad'."""
        return self._mode

    def is_focused(self) -> bool:
        """True when deep-focus is active with a topic set."""
        return self._mode == "deep" and self._topic is not None

    def set_topic(self, topic: str) -> None:
        """Activate deep focus on a specific topic."""
        self._topic = topic.strip()
        self._mode = "deep"
        self._save()
        logger.info("Focus: deep-focus set → %r", self._topic)

    def clear(self) -> None:
        """Return to broad (unfocused) mode."""
        old = self._topic
        self._topic = None
        self._mode = "broad"
        self._save()
        logger.info("Focus: cleared (was %r)", old)

    def get_focus_context(self) -> str:
        """Return a prompt-injection string for the current focus state.

        When focused, this tells the model to prioritize the topic.
        When broad, returns an empty string (no injection).
        """
        if not self.is_focused():
            return ""
        return (
            f"[DEEP FOCUS MODE] You are currently in deep-focus mode on: "
            f'"{self._topic}". '
            f"Prioritize this topic in your responses. Surface related memories "
            f"and prior conversation about this topic first. Deprioritize "
            f"unrelated context. Stay focused — depth over breadth."
        )

    # ── Persistence ───────────────────────────────────────────────

    def _load(self) -> None:
        """Load focus state from disk."""
        if not self._state_file.exists():
            return
        try:
            data = json.loads(self._state_file.read_text())
            self._topic = data.get("topic")
            self._mode = data.get("mode", "broad")
        except Exception as exc:
            logger.warning("Focus: failed to load state: %s", exc)

    def _save(self) -> None:
        """Persist focus state to disk."""
        try:
            self._state_dir.mkdir(parents=True, exist_ok=True)
            self._state_file.write_text(
                json.dumps({"topic": self._topic, "mode": self._mode}, indent=2)
            )
        except Exception as exc:
            logger.warning("Focus: failed to save state: %s", exc)


# Module-level singleton
focus_manager = FocusManager()
