from __future__ import annotations

import argparse
import sys

from .extract import extract_text
from .generate import generate_shadow_dossier
from .lint import lint_markdown, lint_markdown_with_source


def _build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(prog="revoice")
    sub = parser.add_subparsers(dest="cmd", required=True)

    extract_p = sub.add_parser("extract", help="Extract text from a document")
    extract_p.add_argument("--input", required=True, help="Path to input document")
    extract_p.add_argument("--output", required=False, help="Write extracted text to file")

    gen_p = sub.add_parser("generate", help="Generate a shadow dossier")
    gen_p.add_argument("--style", required=True, help="Style id (e.g. if.dave.v1)")
    gen_p.add_argument("--input", required=True, help="Path to input document")
    gen_p.add_argument("--output", required=False, help="Write dossier markdown to file")

    lint_p = sub.add_parser("lint", help="Lint a generated dossier against a style bible")
    lint_p.add_argument("--style", required=True, help="Style id (e.g. if.dave.v1)")
    lint_p.add_argument("--input", required=True, help="Path to markdown file")
    lint_p.add_argument("--source", required=False, help="Optional source document to allow source emojis")

    return parser


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

    if args.cmd == "extract":
        text = extract_text(args.input)
        if args.output:
            with open(args.output, "w", encoding="utf-8") as f:
                f.write(text)
        else:
            sys.stdout.write(text)
        return 0

    if args.cmd == "generate":
        source_text = extract_text(args.input)
        md = generate_shadow_dossier(style_id=args.style, source_text=source_text, source_path=args.input)
        if args.output:
            with open(args.output, "w", encoding="utf-8") as f:
                f.write(md)
        else:
            sys.stdout.write(md)
        return 0

    if args.cmd == "lint":
        with open(args.input, "r", encoding="utf-8") as f:
            md = f.read()
        if args.source:
            source_text = extract_text(args.source)
            issues = lint_markdown_with_source(style_id=args.style, markdown=md, source_text=source_text)
        else:
            issues = lint_markdown(style_id=args.style, markdown=md)
        if issues:
            for issue in issues:
                print(f"- {issue}", file=sys.stderr)
            return 2
        return 0

    raise RuntimeError(f"Unhandled cmd: {args.cmd}")


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