"""
Enhanced CLI with multi-agent support and new operations

Adds build/plan agent switching, file operations, bash execution, and git integration.
"""

import sys
from pathlib import Path
from typing import Optional

import click
from rich.console import Console
from rich.markdown import Markdown
from rich.panel import Panel
from rich.syntax import Syntax
from rich.table import Table

from groknroll import __version__
from groknroll.agents.agent_manager import AgentManager
from groknroll.operations.bash_ops import BashOperations
from groknroll.operations.file_ops import FileOperations
from groknroll.operations.git_ops import GitOperations

console = Console()


@click.group(invoke_without_command=True)
@click.option("--version", is_flag=True, help="Show version")
@click.pass_context
def main(ctx, version):
    """
    🎸 groknroll 2.0 - The Ultimate CLI Coding Agent

    Now with multi-agent support, file operations, bash execution, and git integration!
    """
    if version:
        console.print(f"[bold cyan]groknroll[/bold cyan] version {__version__}")
        return

    if ctx.invoked_subcommand is None:
        console.print(ctx.get_help())


# ============================================================================
# Agent Commands
# ============================================================================


@main.command()
@click.argument("task", nargs=-1, required=True)
@click.option("--path", type=click.Path(exists=True), help="Project path")
@click.option(
    "--agent",
    type=click.Choice(["build", "plan"]),
    default="build",
    help="Agent to use (build=full access, plan=read-only)",
)
def build(task: tuple, path: Optional[str], agent: str):
    """Execute task with build or plan agent"""
    project_path = Path(path) if path else Path.cwd()
    task_str = " ".join(task)

    try:
        with console.status(f"[bold cyan]{agent.title()} agent working...") as status:
            manager = AgentManager(project_path)
            response = manager.execute(task_str, agent=agent)

        # Display response
        console.print()
        if response.success:
            console.print(
                Panel(
                    Markdown(response.message),
                    title=f"[bold green]✓ {agent.title()} Agent[/bold green]",
                    border_style="green",
                )
            )

            # Show metrics
            console.print(
                f"\n[dim]Completed in {response.time:.1f}s (cost: ${response.cost:.4f})[/dim]"
            )
        else:
            console.print(
                Panel(
                    response.message,
                    title=f"[bold red]✗ {agent.title()} Agent Failed[/bold red]",
                    border_style="red",
                )
            )

    except Exception as e:
        console.print(f"[bold red]Error:[/bold red] {e}")
        sys.exit(1)


@main.command()
@click.option("--path", type=click.Path(exists=True), help="Project path")
def agents(path: Optional[str]):
    """List available agents"""
    project_path = Path(path) if path else Path.cwd()

    try:
        manager = AgentManager(project_path)
        agent_list = manager.list_agents()

        # Create table
        table = Table(title="Available Agents", show_header=True)
        table.add_column("Name", style="cyan")
        table.add_column("Description", style="white")
        table.add_column("Active", style="green")
        table.add_column("Capabilities", style="dim")

        for agent_info in agent_list:
            table.add_row(
                agent_info.name,
                agent_info.description,
                "✓" if agent_info.is_active else "",
                ", ".join(agent_info.capabilities[:3]) + "...",
            )

        console.print()
        console.print(table)

    except Exception as e:
        console.print(f"[bold red]Error:[/bold red] {e}")
        sys.exit(1)


# ============================================================================
# File Operations Commands
# ============================================================================


@main.command()
@click.argument("file_path", type=click.Path(exists=True))
@click.option("--syntax", is_flag=True, help="Syntax highlighting")
def read(file_path: str, syntax: bool):
    """Read file contents"""
    path = Path(file_path)

    try:
        file_ops = FileOperations(Path.cwd())
        result = file_ops.read_file(path)

        if result.success:
            console.print()
            if syntax:
                # Detect language from extension
                extension = path.suffix.lstrip(".")
                syntax_obj = Syntax(
                    result.message, extension or "text", theme="monokai", line_numbers=True
                )
                console.print(syntax_obj)
            else:
                console.print(
                    Panel(result.message, title=f"[cyan]{path.name}[/cyan]", border_style="cyan")
                )
        else:
            console.print(f"[bold red]Error:[/bold red] {result.message}")
            sys.exit(1)

    except Exception as e:
        console.print(f"[bold red]Error:[/bold red] {e}")
        sys.exit(1)


@main.command()
@click.argument("file_path", type=click.Path())
@click.argument("content")
@click.option("--overwrite", is_flag=True, help="Overwrite if exists")
def write(file_path: str, content: str, overwrite: bool):
    """Write content to file"""
    path = Path(file_path)

    try:
        file_ops = FileOperations(Path.cwd())
        result = file_ops.write_file(path, content, overwrite=overwrite)

        if result.success:
            console.print(f"[bold green]✓[/bold green] {result.message}")
            if result.backup_path:
                console.print(f"[dim]Backup: {result.backup_path.name}[/dim]")
        else:
            console.print(f"[bold red]Error:[/bold red] {result.message}")
            sys.exit(1)

    except Exception as e:
        console.print(f"[bold red]Error:[/bold red] {e}")
        sys.exit(1)


@main.command()
@click.argument("file_path", type=click.Path(exists=True))
@click.option("--backup/--no-backup", default=True, help="Create backup")
def delete(file_path: str, backup: bool):
    """Delete file"""
    path = Path(file_path)

    try:
        file_ops = FileOperations(Path.cwd())
        result = file_ops.delete_file(path, backup=backup)

        if result.success:
            console.print(f"[bold green]✓[/bold green] {result.message}")
            if result.backup_path:
                console.print(f"[dim]Backup: {result.backup_path.name}[/dim]")
        else:
            console.print(f"[bold red]Error:[/bold red] {result.message}")
            sys.exit(1)

    except Exception as e:
        console.print(f"[bold red]Error:[/bold red] {e}")
        sys.exit(1)


# ============================================================================
# Bash Operations Commands
# ============================================================================


@main.command()
@click.argument("command")
@click.option("--cwd", type=click.Path(exists=True), help="Working directory")
@click.option("--timeout", type=int, default=300, help="Timeout in seconds")
def run(command: str, cwd: Optional[str], timeout: int):
    """Execute bash command"""
    work_dir = Path(cwd) if cwd else Path.cwd()

    try:
        bash_ops = BashOperations(Path.cwd())
        result = bash_ops.execute(command, cwd=work_dir, timeout=timeout)

        console.print()
        if result.success:
            console.print(
                Panel(
                    result.stdout or "[dim]No output[/dim]",
                    title=f"[bold green]✓ Command: {command}[/bold green]",
                    border_style="green",
                )
            )
        else:
            console.print(
                Panel(
                    result.stderr or result.stdout,
                    title=f"[bold red]✗ Command Failed (exit {result.exit_code})[/bold red]",
                    border_style="red",
                )
            )
            sys.exit(result.exit_code)

    except Exception as e:
        console.print(f"[bold red]Error:[/bold red] {e}")
        sys.exit(1)


# ============================================================================
# Git Operations Commands
# ============================================================================


@main.command()
@click.option("--path", type=click.Path(exists=True), help="Repository path")
def git_status(path: Optional[str]):
    """Show git status"""
    repo_path = Path(path) if path else Path.cwd()

    try:
        git_ops = GitOperations(repo_path)
        status = git_ops.status()

        # Create status display
        console.print()
        console.print(
            Panel.fit(
                f"[bold cyan]Branch:[/bold cyan] {status.branch}\n"
                f"[cyan]Ahead:[/cyan] {status.ahead}  [cyan]Behind:[/cyan] {status.behind}\n"
                f"[green]Staged:[/green] {len(status.staged)}  "
                f"[yellow]Unstaged:[/yellow] {len(status.unstaged)}  "
                f"[red]Untracked:[/red] {len(status.untracked)}",
                title="[bold]Git Status[/bold]",
                border_style="cyan",
            )
        )

        # Show file lists
        if status.staged:
            console.print("\n[bold green]Staged files:[/bold green]")
            for file in status.staged[:10]:
                console.print(f"  [green]+[/green] {file}")

        if status.unstaged:
            console.print("\n[bold yellow]Unstaged files:[/bold yellow]")
            for file in status.unstaged[:10]:
                console.print(f"  [yellow]M[/yellow] {file}")

        if status.untracked:
            console.print("\n[bold red]Untracked files:[/bold red]")
            for file in status.untracked[:10]:
                console.print(f"  [red]?[/red] {file}")

    except Exception as e:
        console.print(f"[bold red]Error:[/bold red] {e}")
        sys.exit(1)


@main.command()
@click.argument("message")
@click.option("--path", type=click.Path(exists=True), help="Repository path")
@click.option("--all", "all_files", is_flag=True, help="Stage all files")
def git_commit(message: str, path: Optional[str], all_files: bool):
    """Create git commit"""
    repo_path = Path(path) if path else Path.cwd()

    try:
        git_ops = GitOperations(repo_path)

        # Stage all if requested
        if all_files:
            add_result = git_ops.add(all_files=True)
            if not add_result.success:
                console.print(f"[bold red]Error staging files:[/bold red] {add_result.message}")
                sys.exit(1)

        # Commit
        result = git_ops.commit(message)

        if result.success:
            console.print(f"[bold green]✓[/bold green] {result.message}")
        else:
            console.print(f"[bold red]Error:[/bold red] {result.message}")
            sys.exit(1)

    except Exception as e:
        console.print(f"[bold red]Error:[/bold red] {e}")
        sys.exit(1)


@main.command()
@click.option("--path", type=click.Path(exists=True), help="Repository path")
@click.option("--remote", default="origin", help="Remote name")
@click.option("--force", is_flag=True, help="Force push")
def git_push(path: Optional[str], remote: str, force: bool):
    """Push to remote"""
    repo_path = Path(path) if path else Path.cwd()

    try:
        git_ops = GitOperations(repo_path)
        result = git_ops.push(remote=remote, force=force)

        if result.success:
            console.print(f"[bold green]✓[/bold green] {result.message}")
        else:
            console.print(f"[bold red]Error:[/bold red] {result.message}")
            sys.exit(1)

    except Exception as e:
        console.print(f"[bold red]Error:[/bold red] {e}")
        sys.exit(1)


@main.command()
@click.argument("title")
@click.option("--body", help="PR description")
@click.option("--base", default="main", help="Base branch")
@click.option("--draft", is_flag=True, help="Create as draft")
@click.option("--path", type=click.Path(exists=True), help="Repository path")
def create_pr(title: str, body: Optional[str], base: str, draft: bool, path: Optional[str]):
    """Create pull request"""
    repo_path = Path(path) if path else Path.cwd()

    try:
        git_ops = GitOperations(repo_path)
        result = git_ops.create_pr(title=title, body=body, base=base, draft=draft)

        if result.success:
            console.print("[bold green]✓ PR created![/bold green]")
            console.print(f"\n{result.output}")
        else:
            console.print(f"[bold red]Error:[/bold red] {result.message}")
            sys.exit(1)

    except Exception as e:
        console.print(f"[bold red]Error:[/bold red] {e}")
        sys.exit(1)


if __name__ == "__main__":
    main()
