"""Note persistence: creating, loading, and saving markdown notes with YAML frontmatter."""

from datetime import date
from pathlib import Path

import yaml
from pydantic import BaseModel

from notulist.claude import generate_title
from notulist.config import AppSettings


class NoteMetadata(BaseModel):
    """YAML frontmatter metadata for a note."""

    date_created: date
    title: str


class Note:
    """A markdown note with YAML frontmatter metadata."""

    def __init__(self, metadata: NoteMetadata, content: str):
        """
        Initialize a Note.

        Parameters
        ----------
        metadata : NoteMetadata
            The note's frontmatter metadata.
        content : str
            The markdown body of the note.
        """
        self.metadata = metadata
        self.content = content

    def save(self, filename: Path) -> None:
        """
        Write the note to disk as a markdown file with YAML frontmatter.

        Parameters
        ----------
        filename : Path
            Destination file path. Parent directories are created if needed.
        """
        filename.parent.mkdir(parents=True, exist_ok=True)
        frontmatter = yaml.dump(
            self.metadata.model_dump(mode="json"), default_flow_style=False
        ).strip()
        filename.write_text(f"---\n{frontmatter}\n---\n\n{self.content}\n")

    @staticmethod
    def load(filename: Path) -> "Note":
        """
        Load a note from a markdown file with YAML frontmatter.

        Parameters
        ----------
        filename : Path
            Path to the markdown file.

        Returns
        -------
        Note
            The parsed note.
        """
        text = filename.read_text()
        parts = text.split("---", 2)
        metadata = NoteMetadata.model_validate(yaml.safe_load(parts[1]))
        content = parts[2].strip()
        return Note(metadata=metadata, content=content)


def next_note_path(today_dir: Path, today: date) -> Path:
    """
    Determine the file path for the next note created today.

    Parameters
    ----------
    today_dir : Path
        Directory where today's notes are stored.
    today : date
        The current date, used to build the filename prefix.

    Returns
    -------
    Path
        Path for the new note file, with an auto-incremented sequence number.
    """
    prefix = today.strftime("%Y-%m-%d-")
    existing = sorted(today_dir.glob(f"{prefix}*.md"))
    if existing:
        last = existing[-1].stem
        last_nn = int(last.split("-")[-1])
        nn = last_nn + 1
    else:
        nn = 1
    return today_dir / f"{prefix}{nn:02d}.md"


def record_note(content: str, title: str | None = None) -> Path:
    """
    Create and save a new note.

    Parameters
    ----------
    content : str
        The markdown body of the note.
    title : str or None, optional
        Note title. If ``None``, a title is generated using AI.

    Returns
    -------
    Path
        Path to the saved note file.
    """
    settings = AppSettings()
    today = date.today()
    today_dir = Path(settings.repository) / "today"

    if title is None:
        title = generate_title(content).title
    note_path = next_note_path(today_dir, today)

    note = Note(
        metadata=NoteMetadata(date_created=today, title=title),
        content=content,
    )
    note.save(note_path)

    return note_path
