"""CLI entry point for mdmin (pip install mdmin → `mdmin` command)."""

from __future__ import annotations

import argparse
import sys
from pathlib import Path

from mdmin.engine import compress, estimate_tokens
from mdmin._extractor import ContextExtractor


def _read_input(path: str) -> str:
    if path == "-":
        return sys.stdin.read()
    p = Path(path)
    if not p.exists():
        print(f"mdmin: file not found: {path}", file=sys.stderr)
        sys.exit(1)
    return p.read_text(encoding="utf-8")


def _cmd_compress(args: argparse.Namespace) -> None:
    text = _read_input(args.file)
    result = compress(text, level=args.level)

    if args.output:
        Path(args.output).write_text(result.output, encoding="utf-8")
        s = result.stats
        print(
            f"Saved {s.saved} tokens ({s.pct:.1f}%)  "
            f"{s.input_tokens} → {s.output_tokens}  [{args.output}]"
        )
    else:
        sys.stdout.write(result.output)


def _cmd_stats(args: argparse.Namespace) -> None:
    text = _read_input(args.file)
    header = f"{'Level':<12} {'Tokens':>8} {'Saved':>7} {'%':>6}"
    print(header)
    print("-" * len(header))
    orig = estimate_tokens(text)
    for lvl in ("light", "medium", "aggressive"):
        r = compress(text, level=lvl)  # type: ignore[arg-type]
        s = r.stats
        print(f"{lvl:<12} {s.output_tokens:>8,} {s.saved:>7,} {s.pct:>5.1f}%")
    print(f"\n{'original':<12} {orig:>8,}")


def _cmd_extract(args: argparse.Namespace) -> None:
    text = _read_input(args.file)

    # Optional: pre-compress before extracting if --level specified explicitly
    if args.level != "none":
        text = compress(text, level=args.level).output

    extractor = ContextExtractor()
    index_stats = extractor.index(text)
    print(
        f"Indexed {index_stats['chunksCreated']} chunks "
        f"({index_stats['totalTokens']} tokens)",
        file=sys.stderr,
    )

    result = extractor.extract(args.query, max_tokens=args.max)
    s = result.stats
    print(
        f"Extracted {s.chunks_extracted}/{s.chunks_total} chunks | "
        f"{s.extracted_tokens}/{s.total_doc_tokens} tokens | "
        f"-{s.reduction}%",
        file=sys.stderr,
    )
    sys.stdout.write(result.text)


def main() -> None:
    parser = argparse.ArgumentParser(
        prog="mdmin",
        description="Markdown compression for LLM consumption.",
    )
    sub = parser.add_subparsers(dest="command", required=True)

    # compress sub-command
    p_compress = sub.add_parser("compress", help="Compress a markdown file")
    p_compress.add_argument("file", help="Path to markdown file (or - for stdin)")
    p_compress.add_argument(
        "--level",
        choices=["light", "medium", "aggressive"],
        default="medium",
        help="Compression level (default: medium)",
    )
    p_compress.add_argument("-o", "--output", metavar="FILE", help="Write output to file")

    # stats sub-command
    p_stats = sub.add_parser("stats", help="Show token stats across all levels")
    p_stats.add_argument("file", help="Path to markdown file (or - for stdin)")

    # extract sub-command
    p_extract = sub.add_parser(
        "extract",
        help="Extract query-relevant chunks from a document",
    )
    p_extract.add_argument("file", help="Path to markdown file (or - for stdin)")
    p_extract.add_argument(
        "-q", "--query",
        required=True,
        help="Query to extract relevant chunks for",
    )
    p_extract.add_argument(
        "--max",
        type=int,
        default=2000,
        metavar="TOKENS",
        help="Max output tokens (default: 2000)",
    )
    p_extract.add_argument(
        "--level",
        choices=["light", "medium", "aggressive", "none"],
        default="none",
        help="Pre-compress level before extracting (default: none)",
    )

    args = parser.parse_args()

    if args.command == "compress":
        _cmd_compress(args)
    elif args.command == "stats":
        _cmd_stats(args)
    elif args.command == "extract":
        _cmd_extract(args)


if __name__ == "__main__":
    main()
