#!/usr/bin/env python3
"""PRManage - Fetch and run GitHub PRs locally for different tech stacks."""

import click
import sys
from pathlib import Path

from pr_fetcher.git_utils import GitUtils
from pr_fetcher.stack_detect import StackDetector, TechStack
from pr_fetcher.commands import CommandRunner


@click.command()
@click.argument('repo_url')
@click.argument('pr_number', type=int)
@click.option('--work-dir', '-w', default='./repos', 
              help='Directory to clone repositories (default: ./repos)')
@click.option('--skip-tests', '-s', is_flag=True, 
              help='Skip running tests, only install dependencies')
@click.option('--dry-run', '-n', is_flag=True, 
              help='Show what commands would be run without executing them')
@click.option('--verbose', '-v', is_flag=True, 
              help='Show verbose output')
def main(repo_url: str, pr_number: int, work_dir: str, skip_tests: bool, 
         dry_run: bool, verbose: bool):
    """Fetch and run a GitHub PR locally.
    
    REPO_URL: GitHub repository URL (e.g., https://github.com/owner/repo)
    PR_NUMBER: Pull request number to fetch and test
    
    Examples:
        prmanage https://github.com/laravel/laravel 123
        prmanage git@github.com:phoenixframework/phoenix.git 456 --skip-tests
        prmanage https://github.com/python/cpython 789 --dry-run
    """
    
    print("🚀 PRManage - GitHub PR Local Runner")
    print("=" * 50)
    
    if verbose:
        print(f"Repository URL: {repo_url}")
        print(f"PR Number: {pr_number}")
        print(f"Work Directory: {work_dir}")
        print(f"Skip Tests: {skip_tests}")
        print(f"Dry Run: {dry_run}")
        print()
    
    try:
        # Initialize Git utilities
        git_utils = GitUtils(work_dir)
        
        # Step 1: Get PR information
        print("📋 Fetching PR information...")
        pr_info = git_utils.get_pr_info(repo_url, pr_number)
        
        if pr_info:
            print(f"✅ Found PR #{pr_number}: {pr_info['title']}")
            print(f"   State: {pr_info['state']}")
            print(f"   Author: {pr_info['user']['login']}")
            if verbose and pr_info.get('body'):
                print(f"   Description: {pr_info['body'][:100]}...")
        else:
            print(f"⚠️  Could not fetch PR info (continuing anyway)")
        
        # Step 2: Clone or update repository
        print("\n📥 Cloning/updating repository...")
        repo_path = git_utils.clone_or_update_repo(repo_url)
        
        # Step 3: Fetch and checkout PR
        print(f"\n🔄 Fetching PR #{pr_number}...")
        if not git_utils.fetch_and_checkout_pr(repo_path, pr_number):
            print("❌ Failed to fetch PR. Exiting.")
            sys.exit(1)
        
        # Step 4: Detect tech stack
        print("\n🔍 Detecting tech stack...")
        detector = StackDetector(repo_path)
        stack_info = detector.get_stack_info()
        
        stack = TechStack(stack_info['stack'])
        print(f"✅ Detected stack: {stack.value.upper()}")
        
        if verbose and stack_info['indicators']:
            print(f"   Indicators: {', '.join(stack_info['indicators'])}")
        
        if stack == TechStack.UNKNOWN:
            print("⚠️  Unknown tech stack. Cannot run automated commands.")
            print("   You can manually run commands in:", repo_path)
            sys.exit(0)
        
        # Step 5: Run commands
        command_runner = CommandRunner(repo_path)
        
        if dry_run:
            print(f"\n🔍 Commands that would be run for {stack.value}:")
            commands = command_runner.get_stack_commands(stack)
            for i, (command, description) in enumerate(commands, 1):
                print(f"   {i}. {description}")
                print(f"      Command: {' '.join(command)}")
            print(f"\nTo execute these commands, run without --dry-run flag")
            return
        
        print(f"\n⚡ Running {stack.value} commands...")
        success = command_runner.run_commands(stack)
        
        # Step 6: Summary
        print("\n" + "=" * 50)
        if success:
            print("✅ All commands completed successfully!")
            print(f"🎉 PR #{pr_number} is ready for testing in: {repo_path}")
        else:
            print("⚠️  Some commands failed. Check the output above.")
            print(f"📁 Project location: {repo_path}")
        
        print(f"\n💡 To work with the PR manually:")
        print(f"   cd {repo_path}")
        
        if not success:
            sys.exit(1)
            
    except KeyboardInterrupt:
        print("\n\n⚠️  Operation cancelled by user.")
        sys.exit(1)
    except Exception as e:
        print(f"\n❌ Unexpected error: {e}")
        if verbose:
            import traceback
            traceback.print_exc()
        sys.exit(1)


@click.group()
def cli():
    """PRManage command line interface."""
    pass


@cli.command()
@click.argument('directory', type=click.Path(exists=True))
def detect(directory):
    """Detect tech stack of a local directory.
    
    DIRECTORY: Path to the project directory to analyze
    """
    print("🔍 Detecting tech stack...")
    
    detector = StackDetector(Path(directory))
    stack_info = detector.get_stack_info()
    
    stack = TechStack(stack_info['stack'])
    print(f"Stack: {stack.value.upper()}")
    print(f"Confidence: {stack_info['confidence']}")
    
    if stack_info['indicators']:
        print(f"Indicators found:")
        for indicator in stack_info['indicators']:
            print(f"  - {indicator}")
    
    if stack != TechStack.UNKNOWN:
        command_runner = CommandRunner(Path(directory))
        commands = command_runner.get_stack_commands(stack)
        
        print(f"\nCommands that would be run:")
        for i, (command, description) in enumerate(commands, 1):
            print(f"  {i}. {description}")
            print(f"     {' '.join(command)}")


@cli.command()
def version():
    """Show version information."""
    from pr_fetcher import __version__
    print(f"PRManage version {__version__}")


if __name__ == '__main__':
    # Support both direct script usage and CLI group commands
    if len(sys.argv) > 1 and sys.argv[1] in ['detect', 'version']:
        cli()
    elif len(sys.argv) == 1 or (len(sys.argv) == 2 and sys.argv[1] in ['--help', '-h']):
        # Show main command help instead of group help
        main(['--help'])
    else:
        main()