from __future__ import annotations

from pathlib import Path
from typing import Iterable

from ..schemas import SessionState


def load_root_agents_prompt(config: dict) -> str:
    root_value = config.get("source_root") or config.get("project_root", ".")
    root_path = Path(str(root_value)).expanduser().resolve()
    agents_path = root_path / "AGENTS.md"
    if not agents_path.exists() or not agents_path.is_file():
        return ""
    try:
        return agents_path.read_text(encoding="utf-8").strip()
    except OSError:
        return ""


def build_system_prompt(
    config: dict,
    session: SessionState,
    *,
    provider_names: Iterable[str],
    skill_fragments: list[str],
    root_agents_prompt: str = "",
) -> str:
    provider_list = ", ".join(sorted(provider_names)) or "none"
    base_prompt = str(config.get("system_prompt", "")).strip()
    project_root = config.get("project_root", ".")
    workspace_dir = config.get("workspace_dir", "./workspace")
    skills_dir = f"{workspace_dir}/skills"
    safety_help = (
        "Security modes: safe = strict allowlist shell; yolo = owner-only relaxed shell under project roots; "
        "god = owner-only unrestricted shell/file/terminal access on the host. In /safe off the terminal is intentionally unrestricted."
    )
    self_model_help = (
        "You can inspect and modify your own project files, update config, create or update skills, "
        "reload skills without restart, manage Telegram access, and use Telegram action tools when running inside Telegram."
    )
    agent_mode_help = (
        "Agent mode rules: keep working until the task is actually complete. If a tool call fails, analyze the error, "
        "repair the cause, and continue. Do not stop after the first failure if the task can still be completed. "
        "Use session_end only when the task is complete or the user explicitly asks to end the session."
    )
    structure = (
        f"Project root: {project_root}\n"
        f"Workspace: {workspace_dir}\n"
        f"Skills directory: {skills_dir}\n"
        f"Current provider: {session.provider}\n"
        f"Current model: {session.model}\n"
        f"Current security mode: {session.security_mode}\n"
        f"Configured providers: {provider_list}\n"
        f"Session closed flag: {session.closed}"
    )
    effective_root_agents_prompt = root_agents_prompt or load_root_agents_prompt(config)
    instructions = [base_prompt, structure, safety_help, self_model_help, agent_mode_help]
    if effective_root_agents_prompt:
        instructions.append("Root AGENTS.md instructions:\n" + effective_root_agents_prompt)
    if skill_fragments:
        instructions.append(
            "Loaded skill instructions:\n" + "\n\n".join(fragment.strip() for fragment in skill_fragments if fragment.strip())
        )
    return "\n\n".join(section for section in instructions if section)
