# standard
import pathlib

# third party
import slugify
import frontmatter

# custom
from sunwaee.core.logger import get_logger

_log = get_logger("core.fs")


def make_slug(title: str, fallback_id: str) -> str:
    """Slugify object title."""

    s = slugify.slugify(title)
    return s if s else fallback_id


def write_md(path: pathlib.Path, metadata: dict, body: str) -> None:
    """Write object to markdown with frontmatter."""

    _log.debug("Writing %s", path)
    post = frontmatter.Post(body, **metadata)
    path.parent.mkdir(parents=True, exist_ok=True)
    with open(path, "wb") as f:
        frontmatter.dump(post, f)


def read_md(path: pathlib.Path) -> tuple[dict, str]:
    """Read object from markdown with frontmatter."""

    _log.debug("Reading %s", path)
    post = frontmatter.load(str(path))
    return dict(post.metadata), post.content


def list_md(directory: pathlib.Path) -> list[pathlib.Path]:
    """List all markdown files in a dir."""

    if not directory.exists():
        return []
    return sorted(directory.glob("*.md"), key=lambda p: p.stat().st_mtime, reverse=True)


def find_md(query: str, directory: pathlib.Path) -> pathlib.Path | None:
    """Find a markdown file by id, slug (filename stem), or title (case-insensitive)."""

    _log.debug("Searching for %r in %s", query, directory)
    for path in list_md(directory):
        meta, _ = read_md(path)
        if meta.get("id") == query:
            return path
        if path.stem == query:
            return path
        if meta.get("title", "").lower() == query.lower():
            return path
    _log.debug("No match found for %r in %s", query, directory)
    return None


def search_md(query: str, directory: pathlib.Path) -> list[pathlib.Path]:
    """Return files where query appears in title, tags, or body."""

    q = query.lower()
    results = []
    for path in list_md(directory):
        meta, body = read_md(path)
        if (
            q in meta.get("title", "").lower()
            or q in body.lower()
            or any(q in tag.lower() for tag in meta.get("tags", []))
        ):
            results.append(path)
    return results
