"""
CLI - Command-line interface for openslides.
"""
import argparse
import importlib.util
import sys
from pathlib import Path


def load_deck_module(file_path: str):
    """Load a deck module from file path."""
    path = Path(file_path).resolve()
    if not path.exists():
        print(f"Error: File not found: {file_path}", file=sys.stderr)
        sys.exit(1)

    if not path.suffix == ".py":
        print(f"Error: File must be a Python file (.py): {file_path}", file=sys.stderr)
        sys.exit(1)

    spec = importlib.util.spec_from_file_location("deck_module", path)
    module = importlib.util.module_from_spec(spec)
    sys.modules["deck_module"] = module
    spec.loader.exec_module(module)
    return module


def find_slide_functions(module) -> list:
    """Find all slide_* functions in a module."""
    slides = []
    for name in dir(module):
        if name.startswith("slide_") and callable(getattr(module, name)):
            func = getattr(module, name)
            slides.append((name, func))
    # Sort by function name to maintain order
    slides.sort(key=lambda x: x[0])
    return slides


def cmd_build(args):
    """Build command - render deck to PNG/PDF."""
    from . import export

    module = load_deck_module(args.file)
    slide_funcs = find_slide_functions(module)

    if not slide_funcs:
        print(f"Error: No slide_* functions found in {args.file}", file=sys.stderr)
        sys.exit(1)

    # Generate slides
    slides = []
    for name, func in slide_funcs:
        try:
            html = func()
            slides.append(html)
            if args.verbose:
                print(f"  {name}()")
        except Exception as e:
            print(f"Error in {name}(): {e}", file=sys.stderr)
            sys.exit(1)

    # Determine output directory
    output_dir = args.output
    if not output_dir:
        output_dir = f"/tmp/{Path(args.file).stem}-deck/"

    # Export
    print(f"Building {len(slides)} slides...")
    paths = export(
        slides,
        output_dir,
        width=args.width,
        height=args.height,
        format=args.format,
    )

    print(f"Exported {len(paths)} slides to {output_dir}")
    for p in paths:
        print(f"  {Path(p).name}")


def cmd_list(args):
    """List command - show slide functions in a deck."""
    module = load_deck_module(args.file)
    slide_funcs = find_slide_functions(module)

    if not slide_funcs:
        print(f"No slide_* functions found in {args.file}")
        return

    print(f"Slides in {args.file}:")
    for i, (name, func) in enumerate(slide_funcs, 1):
        doc = func.__doc__ or ""
        doc_line = doc.strip().split("\n")[0] if doc else ""
        print(f"  {i}. {name}()" + (f" - {doc_line}" if doc_line else ""))


def main():
    """Main CLI entry point."""
    parser = argparse.ArgumentParser(
        prog="openslides",
        description="Brand-first slide deck library",
    )
    parser.add_argument(
        "--version", action="version", version="%(prog)s 1.0.0"
    )

    subparsers = parser.add_subparsers(dest="command", help="Commands")

    # build command
    build_parser = subparsers.add_parser(
        "build", help="Build deck from Python file"
    )
    build_parser.add_argument(
        "file", help="Python file containing slide_* functions"
    )
    build_parser.add_argument(
        "-o", "--output", help="Output directory (default: /tmp/<name>-deck/)"
    )
    build_parser.add_argument(
        "-f", "--format",
        choices=["png", "pdf"],
        default="png",
        help="Output format (default: png)",
    )
    build_parser.add_argument(
        "-W", "--width",
        type=int,
        default=1920,
        help="Slide width in pixels (default: 1920)",
    )
    build_parser.add_argument(
        "-H", "--height",
        type=int,
        default=1080,
        help="Slide height in pixels (default: 1080)",
    )
    build_parser.add_argument(
        "-v", "--verbose",
        action="store_true",
        help="Show slide functions being processed",
    )
    build_parser.set_defaults(func=cmd_build)

    # list command
    list_parser = subparsers.add_parser(
        "list", help="List slides in a deck file"
    )
    list_parser.add_argument(
        "file", help="Python file containing slide_* functions"
    )
    list_parser.set_defaults(func=cmd_list)

    args = parser.parse_args()

    if not args.command:
        parser.print_help()
        sys.exit(0)

    args.func(args)


if __name__ == "__main__":
    main()
