"""CLI interface for auto-build tool."""

from pathlib import Path
from typing import Sequence, TypedDict


class BuildResult(TypedDict):
    """Result of a build operation."""
    success: bool
    return_code: int
    stdout: str
    stderr: str
    output_path: Path | None
    duration_seconds: float


def run_cli(args: Sequence[str]) -> None:
    """Run the CLI with the given arguments.
    
    Args:
        args: Command line arguments (excluding program name)
    """
    import argparse
    import sys
    
    parser = argparse.ArgumentParser(
        description="AutoBuild - Multi-language automated build tool",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
  %(prog)s pnpm ./src --output ./dist --mirror
  %(prog)s go ./src --output ./bin/app --mirror
  %(prog)s python ./src --output ./dist --mirror --poetry

Supported languages:
  pnpm    - Frontend JavaScript/TypeScript projects
  go      - Go projects with module support  
  python  - Python projects with pip/poetry/pdm
        """,
    )
    
    parser.add_argument(
        "--version",
        action="version",
        version=f"%(prog)s {__import__('multi_lang_build').__version__}",
    )
    
    subparsers = parser.add_subparsers(
        dest="language",
        title="language",
        description="Build tool for specific language",
    )
    
    pnpm_parser = subparsers.add_parser(
        "pnpm",
        help="Build pnpm-based frontend projects",
        description="Build pnpm-based frontend projects with mirror acceleration",
    )
    pnpm_parser.add_argument("source_dir", type=Path, help="Source directory")
    pnpm_parser.add_argument("-o", "--output", type=Path, required=True, help="Output directory")
    pnpm_parser.add_argument("--mirror/--no-mirror", default=True, help="Enable/disable mirror acceleration")
    pnpm_parser.add_argument("--script", type=str, help="Run specific npm script")
    pnpm_parser.add_argument("--install", action="store_true", help="Install dependencies only")
    pnpm_parser.add_argument("--stream/--no-stream", dest="stream_output", default=True, help="Enable/disable real-time output streaming (default: enabled)")

    go_parser = subparsers.add_parser(
        "go",
        help="Build Go projects",
        description="Build Go projects with module support and mirror acceleration",
    )
    go_parser.add_argument("source_dir", type=Path, help="Source directory")
    go_parser.add_argument("-o", "--output", type=Path, required=True, help="Output file or directory")
    go_parser.add_argument("--mirror", dest="mirror", action="store_true", default=True, help="Enable/disable Go proxy mirror")
    go_parser.add_argument("--no-mirror", dest="mirror", action="store_false", help="Enable/disable Go proxy mirror")
    go_parser.add_argument("--ldflags", type=str, help="Linker flags")
    go_parser.add_argument("--tags", type=str, help="Build tags (comma-separated)")
    go_parser.add_argument("--target", type=str, help="Build target package (e.g., ./cmd/server)")
    go_parser.add_argument("--test", action="store_true", help="Run tests instead of building")
    go_parser.add_argument("--tidy", action="store_true", help="Run go mod tidy")
    go_parser.add_argument("--all", action="store_true", help="Build all packages")
    go_parser.add_argument("--stream/--no-stream", dest="stream_output", default=True, help="Enable/disable real-time output streaming (default: enabled)")

    python_parser = subparsers.add_parser(
        "python",
        help="Build Python projects",
        description="Build Python projects with pip/poetry/pdm and mirror acceleration",
    )
    python_parser.add_argument("source_dir", type=Path, help="Source directory")
    python_parser.add_argument("-o", "--output", type=Path, required=True, help="Output directory")
    python_parser.add_argument("--mirror/--no-mirror", default=True, help="Enable/disable PyPI mirror")
    python_parser.add_argument("--install", action="store_true", help="Install dependencies only")
    python_parser.add_argument("--dev", action="store_true", help="Include development dependencies")
    python_parser.add_argument("--poetry", action="store_true", help="Force using poetry")
    python_parser.add_argument("--create-venv", type=Path, help="Create virtual environment at path")
    python_parser.add_argument("--stream/--no-stream", dest="stream_output", default=True, help="Enable/disable real-time output streaming (default: enabled)")
    
    mirror_parser = subparsers.add_parser(
        "mirror",
        help="Manage mirror configurations",
        description="List or configure domestic mirror acceleration settings",
        epilog="""
Examples:
  %(prog)s mirror list              List all available mirrors
  %(prog)s mirror set pip           Configure pip mirror (default)
  %(prog)s mirror set go            Configure go proxy mirror
  %(prog)s mirror set pnpm          Configure pnpm registry mirror
  %(prog)s mirror show              Show current configuration
  %(prog)s mirror reset             Reset configuration
        """,
    )
    mirror_subparsers = mirror_parser.add_subparsers(dest="mirror_action")

    list_parser = mirror_subparsers.add_parser("list", help="List available mirrors")
    list_parser.add_argument("--json", action="store_true", help="Output as JSON")

    set_parser = mirror_subparsers.add_parser("set", help="Set mirror configuration")
    set_parser.add_argument(
        "type",
        type=str,
        default="pip",
        nargs="?",
        choices=["pip", "go", "npm", "pnpm"],
        help="Package manager type (default: pip)",
    )
    set_parser.add_argument(
        "mirror",
        type=str,
        nargs="?",
        default="pip",
        help="Mirror to use",
    )

    show_parser = mirror_subparsers.add_parser("show", help="Show current configuration")
    show_parser.add_argument(
        "--global",
        dest="global_level",
        action="store_true",
        help="Show global config instead of project-level",
    )

    reset_parser = mirror_subparsers.add_parser("reset", help="Reset configuration")
    reset_parser.add_argument(
        "--global",
        dest="global_level",
        action="store_true",
        help="Reset global config instead of project-level",
    )

    # Register subcommand for IDE integration
    register_parser = subparsers.add_parser(
        "register",
        help="Register as IDE skill (Claude Code, OpenCode, Trae, CodeBuddy)",
        description="Register multi-lang-build as a skill for various AI coding assistants and IDEs",
        epilog="""
Examples:
  %(prog)s register              # Register with Claude Code (default)
  %(prog)s register claude       # Register with Claude Code
  %(prog)s register opencode     # Register with OpenCode
  %(prog)s register trae         # Register with Trae
  %(prog)s register codebuddy    # Register with CodeBuddy
  %(prog)s register all          # Register with all supported IDEs
        """,
    )
    register_parser.add_argument(
        "ide",
        nargs="?",
        default="claude",
        choices=["claude", "opencode", "trae", "codebuddy", "all"],
        help="IDE to register with (default: claude)",
    )
    
    parsed_args = parser.parse_args(args)
    
    if parsed_args.language is None:
        parser.print_help()
        sys.exit(1)
    
    result: BuildResult | None = None
    
    try:
        if parsed_args.language == "pnpm":
            from multi_lang_build.compiler.pnpm import PnpmCompiler

            compiler = PnpmCompiler()

            if parsed_args.script:
                result = compiler.run_script(
                    parsed_args.source_dir,
                    parsed_args.script,
                    mirror_enabled=parsed_args.mirror,
                )
            elif parsed_args.install:
                result = compiler.install_dependencies(
                    parsed_args.source_dir,
                    mirror_enabled=parsed_args.mirror,
                )
            else:
                result = compiler.build(
                    parsed_args.source_dir,
                    parsed_args.output,
                    mirror_enabled=parsed_args.mirror,
                    stream_output=parsed_args.stream_output,
                )

        elif parsed_args.language == "go":
            from multi_lang_build.compiler.go_compiler import GoCompiler

            compiler = GoCompiler()

            if parsed_args.test:
                result = compiler.run_tests(
                    parsed_args.source_dir,
                    mirror_enabled=parsed_args.mirror,
                )
            elif parsed_args.tidy:
                result = compiler.tidy_modules(
                    parsed_args.source_dir,
                    mirror_enabled=parsed_args.mirror,
                )
            elif parsed_args.all:
                result = compiler.build_all(
                    parsed_args.source_dir,
                    parsed_args.output,
                    mirror_enabled=parsed_args.mirror,
                    stream_output=parsed_args.stream_output,
                )
            else:
                tags = parsed_args.tags.split(",") if parsed_args.tags else None
                result = compiler.build_binary(
                    parsed_args.source_dir,
                    parsed_args.output,
                    target=parsed_args.target,
                    mirror_enabled=parsed_args.mirror,
                    ldflags=parsed_args.ldflags,
                    tags=tags,
                    stream_output=parsed_args.stream_output,
                )

        elif parsed_args.language == "python":
            from multi_lang_build.compiler.python import PythonCompiler

            compiler = PythonCompiler()

            if parsed_args.create_venv:
                result = compiler.create_venv(
                    parsed_args.create_venv,
                    mirror_enabled=parsed_args.mirror,
                )
            elif parsed_args.install:
                result = compiler.install_dependencies(
                    parsed_args.source_dir,
                    mirror_enabled=parsed_args.mirror,
                    dev=parsed_args.dev,
                    poetry=parsed_args.poetry,
                )
            else:
                result = compiler.build(
                    parsed_args.source_dir,
                    parsed_args.output,
                    mirror_enabled=parsed_args.mirror,
                    stream_output=parsed_args.stream_output,
                )
        
        elif parsed_args.language == "mirror":
            from multi_lang_build.mirror.cli import configure_mirror, print_mirrors, get_current_config

            if parsed_args.mirror_action == "list":
                if getattr(parsed_args, "json", False):
                    from multi_lang_build.mirror.cli import get_all_mirrors
                    import json
                    print(json.dumps(get_all_mirrors(), indent=2, ensure_ascii=False))
                else:
                    print_mirrors()
            elif parsed_args.mirror_action == "set":
                mirror_type = getattr(parsed_args, "type", "pip")
                mirror_key = getattr(parsed_args, "mirror", "pip")
                success = configure_mirror(mirror_type, mirror_key)
                sys.exit(0 if success else 1)
            elif parsed_args.mirror_action == "show":
                config = get_current_config()
                if config:
                    print("\n📦 Current Mirror Configuration:")
                    print("-" * 40)
                    for key, value in config.items():
                        print(f"  • {key}: {value}")
                    print()
                else:
                    print("\n📦 No mirror configured")
                    print("   Run 'multi-lang-build mirror set <type> <mirror>' to configure")
                    print()
                    print_mirrors()
            else:
                mirror_parser.print_help()

        elif parsed_args.language == "register":
            from multi_lang_build.register import register_skill

            success = register_skill(parsed_args.ide)
            if success:
                print("\n✅ Registration completed successfully!")
                print(f"\nYou can now use 'multi-lang-build' commands in {parsed_args.ide}")
            else:
                print("\n❌ Registration failed for some IDEs.")
            sys.exit(0 if success else 1)

        else:
            parser.print_help()
            sys.exit(1)
        
        if result is not None and result["success"]:
            print(f"Build completed successfully in {result['duration_seconds']:.2f}s")
            if result["output_path"]:
                print(f"Output: {result['output_path']}")
            sys.exit(0)
        elif result is not None:
            print(f"Build failed with code {result['return_code']}")
            if result["stderr"]:
                print(f"Error: {result['stderr']}")
            sys.exit(1)
    
    except Exception as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(2)
