from __future__ import annotations

import argparse
from importlib import resources
from pathlib import Path


def _iter_md_files():
    for entry in resources.files(__package__).iterdir():
        if entry.is_file() and entry.suffix == ".md":
            yield entry


def list_docs() -> list[str]:
    return sorted(entry.stem for entry in _iter_md_files())


def read_doc(name: str) -> str:
    if not name:
        raise ValueError("Document name is required.")
    filename = name if name.lower().endswith(".md") else f"{name}.md"
    doc_path = resources.files(__package__) / filename
    if not doc_path.is_file():
        available = ", ".join(list_docs()) or "none"
        raise FileNotFoundError(f"Unknown document '{name}'. Available: {available}.")
    return doc_path.read_text(encoding="utf-8")


def write_docs(target_dir: str | Path) -> list[Path]:
    target = Path(target_dir).expanduser().resolve()
    target.mkdir(parents=True, exist_ok=True)
    written: list[Path] = []
    for entry in _iter_md_files():
        content = entry.read_text(encoding="utf-8")
        destination = target / entry.name
        destination.write_text(content, encoding="utf-8")
        written.append(destination)
    return written


def write_site(target_dir: str | Path) -> list[Path]:
    site_root = resources.files(__package__) / "site"
    if not site_root.is_dir():
        raise FileNotFoundError("Bundled site assets are not available.")

    target = Path(target_dir).expanduser().resolve()
    target.mkdir(parents=True, exist_ok=True)
    written: list[Path] = []

    def _copy_tree(src, dst: Path) -> None:
        for entry in src.iterdir():
            out_path = dst / entry.name
            if entry.is_dir():
                out_path.mkdir(parents=True, exist_ok=True)
                _copy_tree(entry, out_path)
            else:
                out_path.write_bytes(entry.read_bytes())
                written.append(out_path)

    _copy_tree(site_root, target)
    return written


def _build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        description="Read excelminer documentation bundled with the package."
    )
    parser.add_argument(
        "--list",
        action="store_true",
        help="List available documentation files.",
    )
    parser.add_argument(
        "--show",
        metavar="NAME",
        help="Print a documentation file to stdout (e.g. USAGE, BACKENDS).",
    )
    parser.add_argument(
        "--write-dir",
        metavar="PATH",
        help="Write all documentation markdown files to a directory.",
    )
    parser.add_argument(
        "--write-site",
        metavar="PATH",
        help="Write the bundled HTML site to a directory.",
    )
    return parser


def main(argv: list[str] | None = None) -> int:
    parser = _build_parser()
    args = parser.parse_args(argv)

    if args.list:
        for name in list_docs():
            print(name)
        return 0

    if args.show:
        print(read_doc(args.show))
        return 0

    if args.write_dir:
        written = write_docs(args.write_dir)
        for path in written:
            print(path)
        return 0

    if args.write_site:
        written = write_site(args.write_site)
        for path in written:
            print(path)
        return 0

    parser.print_help()
    return 0


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