"""Read-only summary for You pane noticing synthesis (journal, patterns, proposals)."""

from __future__ import annotations

import logging
import os
from datetime import datetime, timezone
from typing import Any

_log = logging.getLogger(__name__)


def _iso_week_id(dt: datetime) -> str:
    iso = dt.isocalendar()
    return f"{iso[0]:04d}-W{iso[1]:02d}"


def _entry_iso_week_id(ts: str) -> str | None:
    raw = (ts or "").strip()
    if not raw:
        return None
    try:
        return _iso_week_id(datetime.fromisoformat(raw.replace("Z", "+00:00")))
    except Exception:
        return None


def _recent_consolidation_pattern_summary() -> str:
    """Return a one-line pattern summary if consolidation emitted an observation this ISO week."""
    try:
        from persistence import PROACTIVE_QUEUE_PATH
        from utils.proactive_queue import (
            KIND_OBSERVATION,
            pending_entries_from_lines,
        )

        week_id = _iso_week_id(datetime.now(timezone.utc))
        qpath = os.path.expanduser(PROACTIVE_QUEUE_PATH)
        if not os.path.isfile(qpath):
            return ""
        with open(qpath, encoding="utf-8") as f:
            lines = f.readlines()
        for entry in reversed(pending_entries_from_lines(lines, include_notified=True)):
            if str(entry.get("kind") or "") != KIND_OBSERVATION:
                continue
            if str(entry.get("source") or "") != "consolidation":
                continue
            obs = entry.get("observation") if isinstance(entry.get("observation"), dict) else {}
            noticed = str(obs.get("noticed") or entry.get("content") or "").strip()
            if not noticed:
                continue
            entry_week = _entry_iso_week_id(str(entry.get("ts") or ""))
            if entry_week != week_id:
                continue
            from utils.noticing_plaintext import sanitize_noticing_plaintext

            return sanitize_noticing_plaintext(noticed, max_len=300)
    except Exception:
        _log.debug("pattern summary probe failed", exc_info=True)
    return ""


def build_noticing_summary(workspace: str) -> dict[str, Any]:
    """Read-only probe for You pane — must not mutate on GET."""
    from utils.connections_journal import read_connections_journal_tail
    from utils.user_model import filter_proposals_for_you_pane

    journal_tail = ""
    has_journal = False
    try:
        journal_tail = read_connections_journal_tail(workspace, max_chars=1500)
        has_journal = bool(journal_tail.strip())
    except Exception:
        _log.debug("noticing summary journal probe failed", exc_info=True)

    pending_count = 0
    has_connections_proposal = False
    try:
        proposals = filter_proposals_for_you_pane(workspace)
        pending_count = len(proposals)
        has_connections_proposal = any(
            isinstance(p.get("changes"), dict) and bool(p.get("changes", {}).get("connections"))
            for p in proposals
        )
    except Exception:
        _log.debug("noticing summary proposal probe failed", exc_info=True)

    pattern_summary = _recent_consolidation_pattern_summary()
    from utils.noticing_plaintext import extract_journal_bullet_lines, sanitize_noticing_plaintext

    journal_lines = extract_journal_bullet_lines(journal_tail) if has_journal else []
    pattern_clean = sanitize_noticing_plaintext(pattern_summary, max_len=280)
    journal_display = (
        sanitize_noticing_plaintext(journal_tail, max_len=1500) if has_journal else ""
    )

    return {
        "connections_journal_tail": journal_display,
        "connections_journal_preview_lines": journal_lines,
        "has_connections_journal": has_journal,
        "recent_pattern_summary": pattern_clean,
        "has_pattern_observation_this_week": bool(pattern_clean.strip()),
        "pending_proposal_count": pending_count,
        "has_connections_proposal": has_connections_proposal,
    }
