#!/usr/bin/env python3
"""Create a new Obsidian note from a source Markdown file.

The vault is discovered via scripts/find-vault (OBSIDIAN_VAULT override, else a
single .obsidian/ directory under $HOME/Documents). Pass --notes-dir to bypass.
"""

from __future__ import annotations

import argparse
import re
import sys
from datetime import datetime
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent))
from _vault import find_vault  # noqa: E402

ILLEGAL_FILENAME_CHARS = re.compile(r'[<>:"/\\|?*\x00-\x1f]')


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--source", type=Path, required=True, help="Source Markdown file.")
    parser.add_argument("--title", required=True, help="Title for the new note (used as filename verbatim, sanitized only).")
    parser.add_argument("--tags", nargs="+", required=True, help="Tag names to wiki-link in the body.")
    parser.add_argument("--notes-dir", type=Path, default=None, help="Target directory (default: <vault>/all_notes).")
    parser.add_argument(
        "--render-title",
        action="store_true",
        help="Render the title as a ## heading inside the note body. Use only when you generated the title yourself.",
    )
    return parser.parse_args()


def sanitize_filename(title: str) -> str:
    cleaned = ILLEGAL_FILENAME_CHARS.sub("", title).strip().rstrip(".")
    if not cleaned:
        raise ValueError(f"Title {title!r} sanitizes to an empty filename")
    return f"{cleaned}.md"


def dedupe_preserve_order(items: list[str]) -> list[str]:
    seen: set[str] = set()
    result: list[str] = []
    for item in items:
        if item in seen:
            continue
        seen.add(item)
        result.append(item)
    return result


def render_note(tags: list[str], content: str, title: str | None = None) -> str:
    now = datetime.now()
    date = now.strftime("%Y-%m-%d")
    timestamp = now.strftime("%Y-%m-%d %H:%M")
    tags_line = " ".join(f"[[{tag}]]" for tag in tags)
    frontmatter = f"---\ncreated: {date}\nmodified: {date}\ntags:\n---\n"
    body_header = f"{timestamp}\nStatus:\nTags: {tags_line}\n\n"
    title_heading = f"## {title}\n\n" if title else ""
    return f"{frontmatter}{body_header}{title_heading}{content.rstrip()}\n"


def main() -> int:
    args = parse_args()
    notes_dir = args.notes_dir if args.notes_dir is not None else find_vault() / "all_notes"
    content = args.source.read_text()
    tags = dedupe_preserve_order(args.tags)
    rendered = render_note(
        tags=tags,
        content=content,
        title=args.title if args.render_title else None,
    )
    notes_dir.mkdir(parents=True, exist_ok=True)
    note_path = notes_dir / sanitize_filename(args.title)
    try:
        with note_path.open("x") as note_file:
            note_file.write(rendered)
    except FileExistsError:
        print(f"Refusing to overwrite existing note: {note_path}", file=sys.stderr)
        return 1
    print(note_path)
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
