from __future__ import annotations

from importlib import resources
from pathlib import Path

_PACKAGE = __package__  # "dods.datagen.templates"


def list_templates() -> list[str]:
    """Return available template names (without .yaml)."""
    files = resources.files(_PACKAGE).iterdir()
    return sorted([p.stem for p in files if p.name.endswith(".yaml")])


def _read_template(name: str) -> str:
    """Read a template YAML content by name (without .yaml)."""
    filename = f"{name}.yaml"
    try:
        return resources.files(_PACKAGE).joinpath(filename).read_text(encoding="utf-8")
    except FileNotFoundError:
        raise ValueError(f"Unknown template '{name}'. Available: {', '.join(list_templates())}")

_YAML_EXTS = (".yaml", ".yml")


def _strip_yaml_ext(name: str) -> str:
    name = name.strip()
    for ext in _YAML_EXTS:
        if name.lower().endswith(ext):
            return name[: -len(ext)]
    return name


def _ensure_yaml_path(p: Path) -> Path:
    # If user passes a directory, write <dir>/<name>.yaml would require name.
    # Here we only ensure suffix if path has no suffix.
    if p.suffix == "":
        return p.with_suffix(".yaml")
    return p


def create_template(
    name: str = "template",
    *,
    path: str | Path | None = None,
    overwrite: bool = False,
) -> Path:
    """
    Write a built-in YAML template to disk and return the output path.

    Parameters
    ----------
    name:
        Template name (e.g. "template", "template_long"). The ".yaml"/".yml"
        suffix is optional and will be ignored.
        See `list_templates()` for all available names.
    path:
        Output file path. If None (default), uses "<name>.yaml".
        If given without extension, ".yaml" is appended automatically.
    overwrite:
        If False (default), raises FileExistsError if the file already exists.
        If True, overwrites the file.

    Returns
    -------
    Path
        The written file path.

    Examples
    --------
    >>> import dods.datagen as dg
    >>> dg.create_template()
    PosixPath('template.yaml')

    >>> dg.create_template("template_long")
    PosixPath('template_long.yaml')

    >>> dg.create_template("template_long.yaml")
    PosixPath('template_long.yaml')

    >>> dg.create_template("template_long", path="configs/template_long", overwrite=True)
    PosixPath('configs/template_long.yaml')
    """
    template_name = _strip_yaml_ext(name)
    content = _read_template(template_name)

    out_path = Path(path) if path is not None else Path(f"{template_name}.yaml")
    out_path = _ensure_yaml_path(out_path)

    if out_path.exists() and not overwrite:
        raise FileExistsError(f"File exists: {out_path} (use overwrite=True)")

    out_path.parent.mkdir(parents=True, exist_ok=True)
    out_path.write_text(content, encoding="utf-8")
    return out_path