"""Loads LLM task instructions from skill config/format.yaml files (Rule #12).

Services call ``build_task_instruction()`` with a skill name and optional
preamble/suffix to produce the exact markdown-format prompt the LLM sees.
The section definitions, rules, and empty-fallback text all come from the
skill's ``config/format.yaml`` — users edit YAML, not Python, to change
what the LLM produces.

Hardcoded fallback strings are kept so the system never crashes when a
skill config file is missing.
"""

from __future__ import annotations

import logging
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from agntspace.skills.loader import SkillLoader

log = logging.getLogger(__name__)


def _load_format(skill_loader: SkillLoader | None, skill_name: str) -> dict | None:
    """Load format.yaml from a skill's config directory."""
    if not skill_loader:
        return None
    try:
        return skill_loader.load_skill_config_file(skill_name, "format.yaml")
    except Exception:
        return None


def build_task_instruction(
    skill_loader: SkillLoader | None,
    skill_name: str,
    *,
    preamble: str = "",
    suffix: str = "",
    fallback: str = "",
) -> str:
    """Build a task instruction from a skill's config/format.yaml.

    Returns a string like::

        {preamble}

        ## Good Morning
        A brief personalized greeting (1-2 sentences).

        ## Today's Focus
        Honor the user's focus if set, otherwise suggest top priorities.
        Write *Nothing scheduled.* if empty.

        ---
        {suffix}
        RULES: Output ONLY valid markdown. ...

    If the format.yaml doesn't exist, returns ``fallback``.
    """
    fmt = _load_format(skill_loader, skill_name)
    if not fmt or not isinstance(fmt.get("sections"), list):
        if fallback:
            log.debug("Using fallback task instruction for %s", skill_name)
            return fallback
        return ""

    parts: list[str] = []
    if preamble:
        parts.append(preamble)
        parts.append("")

    for section in fmt["sections"]:
        header = section.get("header", "")
        desc = section.get("description", "").strip()
        empty_fb = section.get("empty_fallback", "")

        parts.append(f"## {header}")
        if desc:
            parts.append(desc)
        if empty_fb:
            parts.append(f"Write *{empty_fb}* if empty.")
        parts.append("")

    parts.append("---")

    if suffix:
        parts.append(suffix)

    rules = fmt.get("rules", [])
    if rules and isinstance(rules, list):
        parts.append("RULES: " + " ".join(rules))

    return "\n".join(parts)


def get_memory_updates_section(
    skill_loader: SkillLoader | None,
    skill_name: str = "daily-reflection",
) -> str:
    """Return the section header that contains memory update suggestions.

    Loaded from format.yaml ``memory_updates_section`` key.
    Falls back to "Suggested Memory Updates" / "Memory Updates".
    """
    fmt = _load_format(skill_loader, skill_name)
    if fmt and isinstance(fmt.get("memory_updates_section"), str):
        return fmt["memory_updates_section"]
    return "Memory Updates"
