"""System snapshot and memory context mixin for the thinking engine."""

import logging
from datetime import datetime

from timmy.memory_system import HOT_MEMORY_PATH, SOUL_PATH

logger = logging.getLogger(__name__)


class _SnapshotMixin:
    """Mixin providing system-snapshot and memory-context helpers.

    Expects the host class to provide:
    - self._db_path: Path
    """

    # ── System snapshot helpers ────────────────────────────────────────────

    def _snap_thought_count(self, now: datetime) -> str | None:
        """Return today's thought count, or *None* on failure."""
        from timmy.thinking._db import _get_conn

        try:
            today_start = now.replace(hour=0, minute=0, second=0, microsecond=0)
            with _get_conn(self._db_path) as conn:
                count = conn.execute(
                    "SELECT COUNT(*) as c FROM thoughts WHERE created_at >= ?",
                    (today_start.isoformat(),),
                ).fetchone()["c"]
            return f"Thoughts today: {count}"
        except Exception as exc:
            logger.debug("Thought count query failed: %s", exc)
            return None

    def _snap_chat_activity(self) -> list[str]:
        """Return chat-activity lines (in-memory, no I/O)."""
        try:
            from infrastructure.chat_store import message_log

            messages = message_log.all()
            if messages:
                last = messages[-1]
                return [
                    f"Chat messages this session: {len(messages)}",
                    f'Last chat ({last.role}): "{last.content[:80]}"',
                ]
            return ["No chat messages this session"]
        except Exception as exc:
            logger.debug("Chat activity query failed: %s", exc)
            return []

    def _snap_task_queue(self) -> str | None:
        """Return a one-line task queue summary, or *None*."""
        try:
            from swarm.task_queue.models import get_task_summary_for_briefing

            s = get_task_summary_for_briefing()
            running, pending = s.get("running", 0), s.get("pending_approval", 0)
            done, failed = s.get("completed", 0), s.get("failed", 0)
            if running or pending or done or failed:
                return (
                    f"Tasks: {running} running, {pending} pending, "
                    f"{done} completed, {failed} failed"
                )
        except Exception as exc:
            logger.debug("Task queue query failed: %s", exc)
        return None

    def _snap_workspace(self) -> list[str]:
        """Return workspace-update lines (file-based Hermes comms)."""
        try:
            from timmy.workspace import workspace_monitor

            updates = workspace_monitor.get_pending_updates()
            lines: list[str] = []
            new_corr = updates.get("new_correspondence")
            if new_corr:
                line_count = len([ln for ln in new_corr.splitlines() if ln.strip()])
                lines.append(
                    f"Workspace: {line_count} new correspondence entries (latest from: Hermes)"
                )
            new_inbox = updates.get("new_inbox_files", [])
            if new_inbox:
                files_str = ", ".join(new_inbox[:5])
                if len(new_inbox) > 5:
                    files_str += f", ... (+{len(new_inbox) - 5} more)"
                lines.append(f"Workspace: {len(new_inbox)} new inbox files: {files_str}")
            return lines
        except Exception as exc:
            logger.debug("Workspace check failed: %s", exc)
            return []

    def _gather_system_snapshot(self) -> str:
        """Gather lightweight real system state for grounding thoughts in reality.

        Returns a short multi-line string with current time, thought count,
        recent chat activity, and task queue status. Never crashes — every
        section is independently try/excepted.
        """
        now = datetime.now().astimezone()
        tz = now.strftime("%Z") or "UTC"

        parts: list[str] = [
            f"Local time: {now.strftime('%I:%M %p').lstrip('0')} {tz}, {now.strftime('%A %B %d')}"
        ]

        thought_line = self._snap_thought_count(now)
        if thought_line:
            parts.append(thought_line)

        parts.extend(self._snap_chat_activity())

        task_line = self._snap_task_queue()
        if task_line:
            parts.append(task_line)

        parts.extend(self._snap_workspace())

        return "\n".join(parts) if parts else ""

    def _load_memory_context(self) -> str:
        """Pre-hook: load MEMORY.md + soul.md for the thinking prompt.

        Hot memory first (changes each cycle), soul second (stable identity).
        Returns a combined string truncated to ~1500 chars.
        Graceful on any failure — returns empty string.
        """
        parts: list[str] = []
        try:
            if HOT_MEMORY_PATH.exists():
                hot = HOT_MEMORY_PATH.read_text().strip()
                if hot:
                    parts.append(hot)
        except Exception as exc:
            logger.debug("Failed to read MEMORY.md: %s", exc)

        try:
            if SOUL_PATH.exists():
                soul = SOUL_PATH.read_text().strip()
                if soul:
                    parts.append(soul)
        except Exception as exc:
            logger.debug("Failed to read soul.md: %s", exc)

        if not parts:
            return ""

        combined = "\n\n---\n\n".join(parts)
        if len(combined) > 1500:
            combined = combined[:1500] + "\n... [truncated]"
        return combined

    def _update_memory(self, thought) -> None:
        """Post-hook: update MEMORY.md 'Last Reflection' section with latest thought.

        Never modifies soul.md. Never crashes the heartbeat.
        """
        try:
            from timmy.memory_system import store_last_reflection

            ts = datetime.fromisoformat(thought.created_at)
            local_ts = ts.astimezone()
            tz_name = local_ts.strftime("%Z") or "UTC"
            time_str = f"{local_ts.strftime('%Y-%m-%d %I:%M %p').lstrip('0')} {tz_name}"
            reflection = (
                f"**Time:** {time_str}\n"
                f"**Seed:** {thought.seed_type}\n"
                f"**Thought:** {thought.content[:200]}"
            )
            store_last_reflection(reflection)
        except Exception as exc:
            logger.debug("Failed to update memory after thought: %s", exc)
