"""Enrich missing-path tool errors with sibling listings and managed-root hints."""

from __future__ import annotations

import os

from utils.managed_path_roots import find_managed_root_for_path
from utils.path_normalize import fuzzy_slug_normalize
from utils.path_safety import is_dangerous_path

_MISSING_PREFIX = "Path does not exist:"
_SUFFIX_CAP = 800


def _list_siblings(parent: str, *, max_entries: int = 10) -> list[str]:
    if is_dangerous_path(parent):
        return []
    if not os.path.isdir(parent):
        return []
    try:
        names = sorted(os.listdir(parent))
    except (OSError, PermissionError):
        return []
    out: list[str] = []
    for name in names[:max_entries]:
        full = os.path.join(parent, name)
        if os.path.isdir(full):
            out.append(f"{name}/")
        else:
            out.append(name)
    return out


def _unique_fuzzy_match(requested_basename: str, siblings: list[str]) -> str | None:
    target = fuzzy_slug_normalize(requested_basename)
    if not target:
        return None
    matches: list[str] = []
    for entry in siblings:
        clean = entry.rstrip("/")
        if fuzzy_slug_normalize(clean) == target:
            matches.append(clean)
    if len(matches) == 1:
        return matches[0]
    return None


def _managed_slug_listing(abs_path: str) -> str | None:
    root = find_managed_root_for_path(abs_path)
    if root is None:
        return None
    try:
        root_path = os.path.realpath(os.path.expanduser(root.abs_path))
    except OSError:
        return None
    if not os.path.isdir(root_path):
        return None
    slugs = _list_siblings(root_path, max_entries=15)
    if not slugs:
        return None
    slug_names = [s.rstrip("/") for s in slugs if s.endswith("/")]
    if not slug_names:
        return None
    return f"{root.label}: {', '.join(slug_names)}"


def enrich_missing_path_error(abs_path: str, *, workspace: str = "") -> str:
    """Return suffix to append after ``Path does not exist: {abs_path}`` (prefix unchanged)."""
    if not abs_path:
        return ""

    parts: list[str] = []
    parent = os.path.dirname(abs_path)
    requested_base = os.path.basename(abs_path)

    if parent and os.path.isdir(parent) and not is_dangerous_path(parent):
        siblings = _list_siblings(parent)
        if siblings:
            listing = ", ".join(siblings)
            parts.append(f"Parent directory exists. Entries: {listing}")
            suggestion = _unique_fuzzy_match(requested_base, siblings)
            if suggestion:
                suggested = os.path.join(parent, suggestion)
                parts.append(f"Did you mean: {suggested}")

    managed = _managed_slug_listing(abs_path)
    if managed:
        parts.append(managed)

    if not parts:
        return ""

    suffix = "\n\n" + "\n".join(parts)
    if len(suffix) > _SUFFIX_CAP:
        suffix = suffix[: _SUFFIX_CAP - 40].rstrip() + "\n(more entries omitted)"
    return suffix


def maybe_enrich_tool_missing_path_result(result: str, *, workspace: str = "") -> str:
    """If *result* is a missing-path error, append enrichment suffix."""
    if not isinstance(result, str) or not result.startswith(_MISSING_PREFIX):
        return result
    # Extract abs path from "Path does not exist: /path"
    rest = result[len(_MISSING_PREFIX):].strip()
    first_line = rest.split("\n", 1)[0].strip()
    if not first_line:
        return result
    suffix = enrich_missing_path_error(first_line, workspace=workspace)
    if not suffix:
        return result
    return result + suffix
