"""
AI Coder (CQ-AI) - Terminal-native AI coding agent

Main CLI entry point using Typer.
"""

import os
import sys
from pathlib import Path
from typing import Optional

import typer
import yaml
from dotenv import load_dotenv
from rich.console import Console
from rich.panel import Panel

from ai_coder import __version__
from ai_coder.agent.orchestrator import AgentOrchestrator, AgentConfig
from ai_coder.llm.interface import LLMConfig, get_provider

# Load environment variables
load_dotenv()

# Initialize CLI app
app = typer.Typer(
    name="cq",
    help="Current Quotient AI — Terminal-native AI coding agent",
    add_completion=False,
    invoke_without_command=True,
)

console = Console()


def load_config(config_path: Optional[Path] = None) -> dict:
    """Load configuration from YAML file."""
    if config_path is None:
        # Look for config in current directory or home
        candidates = [
            Path.cwd() / "config.yaml",
            Path.cwd() / ".ai-coder" / "config.yaml",
            Path.home() / ".ai-coder" / "config.yaml",
        ]
        for candidate in candidates:
            if candidate.exists():
                config_path = candidate
                break

    if config_path and config_path.exists():
        with open(config_path, encoding="utf-8") as f:
            return yaml.safe_load(f) or {}

    return {}


def get_api_key(provider: str) -> str:
    """Get API key from environment."""
    if provider == "openai":
        key = os.getenv("OPENAI_API_KEY", "")
    elif provider == "anthropic":
        key = os.getenv("ANTHROPIC_API_KEY", "")
    else:
        key = os.getenv(f"{provider.upper()}_API_KEY", "")

    if not key:
        console.print(f"[red]Error: {provider.upper()}_API_KEY not set[/red]")
        console.print(f"Set it in your environment or in a .env file")
        raise typer.Exit(1)

    return key


@app.callback()
def default_callback(
    ctx: typer.Context,
    project_dir: Optional[Path] = typer.Option(
        None, "--project", "-p",
        help="Project directory (default: current directory)",
    ),
    provider: Optional[str] = typer.Option(
        None, "--provider",
        help="LLM provider (openai, anthropic, huggingface, ollama, etc.)",
    ),
    model: Optional[str] = typer.Option(
        None, "--model", "-m",
        help="Model to use",
    ),
    api_key: Optional[str] = typer.Option(
        None, "--api-key", "-k",
        help="API key for the LLM provider",
    ),
):
    """
    CQ-AI — your AI-powered coding assistant.

    Run without a subcommand to launch the interactive menu.
    """
    # Store global options in context for sub-commands
    ctx.ensure_object(dict)
    ctx.obj["project_dir"] = project_dir
    ctx.obj["provider"] = provider
    ctx.obj["model"] = model
    ctx.obj["api_key"] = api_key

    # If no subcommand was invoked, launch interactive menu
    if ctx.invoked_subcommand is None:
        from ai_coder.interactive import launch_interactive
        launch_interactive(
            project_dir=project_dir,
            provider=provider,
            model=model,
            api_key=api_key,
        )
        raise typer.Exit(0)


@app.command()
def run(
    task: str = typer.Argument(..., help="Task description in natural language"),
    project_dir: Optional[Path] = typer.Option(
        None,
        "--project", "-p",
        help="Project directory (default: current directory)",
    ),
    provider: Optional[str] = typer.Option(
        None,
        "--provider",
        help="LLM provider (openai, anthropic, huggingface, etc.)",
    ),
    model: Optional[str] = typer.Option(
        None,
        "--model", "-m",
        help="Model to use (e.g., gpt-4o, claude-3-5-sonnet)",
    ),
    api_key: Optional[str] = typer.Option(
        None,
        "--api-key", "-k",
        help="API key for the LLM provider (overrides environment variable)",
    ),
    max_iterations: Optional[int] = typer.Option(
        None,
        "--max-iterations", "-i",
        help="Maximum iterations for task completion",
    ),
    auto_confirm: bool = typer.Option(
        False,
        "--auto-confirm", "-y",
        help="Auto-confirm file changes (use with caution)",
    ),
    verbose: bool = typer.Option(
        False,
        "--verbose", "-v",
        help="Enable verbose output",
    ),
):
    """
    Execute an AI-assisted coding task.
    
    Example:
        cq run "Add OAuth login to this app"
        cq run "Fix failing unit tests" --verbose
        cq run "Refactor the database module" -p ./my-project
    """
    # Load config
    config = load_config()
    llm_config = config.get("llm", {})
    agent_config = config.get("agent", {})

    # Override with CLI options
    provider_name = provider or llm_config.get("provider", "openai")
    model_name = model or llm_config.get("model", "gpt-4o")
    iterations = max_iterations or agent_config.get("max_iterations", 100)

    # Resolve project directory
    project_path = (project_dir or Path.cwd()).resolve()

    if not project_path.exists():
        console.print(f"[red]Error: Project directory not found: {project_path}[/red]")
        raise typer.Exit(1)

    # Display banner
    console.print(Panel(
        f"[bold blue]CQ-AI v{__version__}[/bold blue]\n"
        f"Developed by CQ Team\n"
        f"Provider: {provider_name} | Model: {model_name}\n"
        f"Project: {project_path}",
        border_style="blue",
    ))

    # Initialize LLM
    try:
        # Import providers to register them
        from ai_coder.llm import openai_provider, anthropic_provider, custom_provider, gemini_provider, openrouter_provider, huggingface_provider

        # Get API key (CLI option takes precedence over environment)
        # Local providers like ollama and lmstudio don't need API keys
        keyless_providers = ["ollama", "lmstudio", "custom"]
        
        resolved_api_key = api_key  # Use CLI-provided key if available
        if not resolved_api_key and provider_name not in keyless_providers:
            try:
                resolved_api_key = get_api_key(provider_name)
            except typer.Exit:
                raise
        elif not resolved_api_key and provider_name in keyless_providers:
            console.print(f"[dim]No API key required for {provider_name}[/dim]")

        # Get API base URL from config or environment
        api_base = llm_config.get("api_base") or os.getenv(f"{provider_name.upper()}_API_BASE")

        llm_cfg = LLMConfig(
            model=model_name,
            max_tokens=llm_config.get("max_tokens", 4096),
            temperature=llm_config.get("temperature", 0.1),
            api_key=resolved_api_key,
            api_base=api_base,
        )

        llm = get_provider(provider_name, llm_cfg)

    except Exception as e:
        console.print(f"[red]Error initializing LLM: {e}[/red]")
        if verbose:
            console.print_exception()
        raise typer.Exit(1)

    # Initialize agent
    agent_cfg = AgentConfig(
        max_iterations=iterations,
        auto_confirm=auto_confirm or agent_config.get("auto_confirm", False),
        verbose=verbose or agent_config.get("verbose", False),
        provider=provider_name,
        model=model_name,
    )

    agent = AgentOrchestrator(
        llm=llm,
        project_root=project_path,
        config=agent_cfg,
    )

    # Run the task
    success = agent.run(task)

    # Exit with appropriate code
    raise typer.Exit(0 if success else 1)


@app.command()
def init(
    project_dir: Optional[Path] = typer.Option(
        None,
        "--project", "-p",
        help="Project directory (default: current directory)",
    ),
):
    """
    Initialize AI Coder configuration in a project.
    
    Creates a config.yaml file with default settings.
    """
    project_path = (project_dir or Path.cwd()).resolve()
    config_dir = project_path / ".ai-coder"
    config_file = config_dir / "config.yaml"

    if config_file.exists():
        console.print(f"[yellow]Config already exists: {config_file}[/yellow]")
        if not typer.confirm("Overwrite?"):
            raise typer.Exit(0)

    # Create default config
    default_config = """# CQ-AI Configuration

# LLM Provider Settings
# Supported providers: openai, anthropic, ollama, lmstudio, together, groq, fireworks, azure, custom
llm:
  provider: "openai"
  model: "gpt-4o"
  max_tokens: 4096
  temperature: 0.1
  # api_base: "https://api.example.com/v1"  # Optional: custom API endpoint

# Agent Behavior
agent:
  max_iterations: 10
  auto_confirm: false
  verbose: false

# Safety Settings
safety:
  confirm_delete: true
  restrict_to_project: true
  max_file_size: 1048576
  command_timeout: 60

# ─── Custom Provider Examples ───
# 
# Ollama (local):
#   provider: "ollama"
#   model: "llama3.1"
#
# LM Studio (local):
#   provider: "lmstudio"
#   model: "local-model"
#
# Together AI:
#   provider: "together"
#   model: "meta-llama/Llama-3-70b-chat-hf"
#
# Groq:
#   provider: "groq"
#   model: "llama-3.1-70b-versatile"
#
# Any OpenAI-compatible API:
#   provider: "custom"
#   api_base: "https://your-api.com/v1"
#   model: "your-model-name"
"""

    config_dir.mkdir(parents=True, exist_ok=True)
    config_file.write_text(default_config)

    # Create .env template
    env_file = project_path / ".env"
    if not env_file.exists():
        env_template = """# CQ-AI Environment Variables
OPENAI_API_KEY=sk-your-key-here
# ANTHROPIC_API_KEY=sk-ant-your-key-here
"""
        env_file.write_text(env_template)
        console.print(f"[green]Created .env template: {env_file}[/green]")

    console.print(f"[green]✓ Initialized CQ-AI config: {config_file}[/green]")
    console.print("\nNext steps:")
    console.print("  1. Set your API key in .env or environment")
    console.print("  2. Customize settings in .ai-coder/config.yaml")
    console.print("  3. Run: cq run 'your task'")


@app.command()
def status():
    """Show the status of the current session."""
    project_path = Path.cwd().resolve()
    session_file = project_path / ".ai-coder" / "session.json"

    if not session_file.exists():
        console.print("[yellow]No active session found[/yellow]")
        raise typer.Exit(0)

    try:
        import json
        data = json.loads(session_file.read_text())

        if data.get("task"):
            task = data["task"]
            console.print(Panel(
                f"Task: {task.get('description', 'Unknown')}\n"
                f"Status: {task.get('status', 'Unknown')}\n"
                f"Iterations: {task.get('iterations', 0)}\n"
                f"Started: {task.get('created_at', 'Unknown')}",
                title="[bold]Session Status[/bold]",
                border_style="blue",
            ))
        else:
            console.print("[yellow]No active task[/yellow]")

    except Exception as e:
        console.print(f"[red]Error reading session: {e}[/red]")


@app.command()
def version():
    """Show the version of CQ-AI."""
    console.print(f"CQ-AI v{__version__}")


@app.command()
def feature(
    description: str = typer.Argument(..., help="Feature description"),
    project_dir: Optional[Path] = typer.Option(
        None,
        "--project", "-p",
        help="Project directory (default: current directory)",
    ),
    provider: Optional[str] = typer.Option(
        None,
        "--provider",
        help="LLM provider",
    ),
    model: Optional[str] = typer.Option(
        None,
        "--model", "-m",
        help="Model to use",
    ),
    api_key: Optional[str] = typer.Option(
        None,
        "--api-key", "-k",
        help="API key for the LLM provider",
    ),
):
    """
    Start a guided 7-phase feature development workflow.
    
    Phases: Discovery → Exploration → Questions → Architecture → Implementation → Review → Summary
    
    Example:
        cq feature "Add OAuth login"
        cq feature "Implement caching layer" --provider openai
    """
    from ai_coder.workflow.engine import WorkflowEngine
    from ai_coder.tools.base import create_tool_registry
    
    # Load config
    config = load_config()
    llm_config = config.get("llm", {})
    
    provider_name = provider or llm_config.get("provider", "openai")
    model_name = model or llm_config.get("model", "gpt-4o")
    project_path = (project_dir or Path.cwd()).resolve()
    
    console.print(Panel(
        f"[bold blue]AI Coder Feature Development[/bold blue]\n"
        f"Feature: {description}\n"
        f"Provider: {provider_name} | Model: {model_name}",
        border_style="blue",
    ))
    
    # Initialize LLM
    keyless_providers = {"ollama", "lmstudio", "custom"}
    if provider_name in keyless_providers:
        key = api_key or ""
    else:
        key = api_key or get_api_key(provider_name)
    
    try:
        llm = get_provider(
            provider_name,
            LLMConfig(
                model=model_name,
                api_key=key,
            )
        )
    except Exception as e:
        console.print(f"[red]Error initializing LLM: {e}[/red]")
        raise typer.Exit(1)
    
    # Initialize workflow
    tool_registry = create_tool_registry(project_path)
    workflow = WorkflowEngine(
        llm=llm,
        tool_registry=tool_registry,
        project_root=project_path,
    )
    
    success = workflow.start(description)
    raise typer.Exit(0 if success else 1)


@app.command()
def explore(
    query: str = typer.Argument(..., help="What to explore in the codebase"),
    project_dir: Optional[Path] = typer.Option(
        None,
        "--project", "-p",
        help="Project directory (default: current directory)",
    ),
    provider: Optional[str] = typer.Option(
        None,
        "--provider",
        help="LLM provider",
    ),
    model: Optional[str] = typer.Option(
        None,
        "--model", "-m",
        help="Model to use",
    ),
    api_key: Optional[str] = typer.Option(
        None,
        "--api-key", "-k",
        help="API key for the LLM provider",
    ),
):
    """
    Launch a code-explorer agent to analyze the codebase.
    
    Example:
        cq explore "How does authentication work?"
        cq explore "Map the database layer"
    """
    from ai_coder.agents.launcher import AgentLauncher
    from ai_coder.agents.base import AgentType
    from ai_coder.tools.base import create_tool_registry
    
    # Load config
    config = load_config()
    llm_config = config.get("llm", {})
    
    provider_name = provider or llm_config.get("provider", "openai")
    model_name = model or llm_config.get("model", "gpt-4o")
    project_path = (project_dir or Path.cwd()).resolve()
    
    console.print(Panel(
        f"[bold yellow]🔍 Code Explorer[/bold yellow]\n"
        f"Query: {query}",
        border_style="yellow",
    ))
    
    # Initialize LLM
    keyless_providers = {"ollama", "lmstudio", "custom"}
    if provider_name in keyless_providers:
        key = api_key or ""
    else:
        key = api_key or get_api_key(provider_name)
    
    try:
        llm = get_provider(
            provider_name,
            LLMConfig(
                model=model_name,
                api_key=key,
            )
        )
    except Exception as e:
        console.print(f"[red]Error initializing LLM: {e}[/red]")
        raise typer.Exit(1)
    
    # Launch explorer agent
    tool_registry = create_tool_registry(project_path)
    launcher = AgentLauncher(llm, tool_registry, project_path)
    result = launcher.launch_single(AgentType.CODE_EXPLORER, query)
    
    if result.success:
        console.print(result.output)
        if result.key_files:
            console.print("\n[bold]Key Files:[/bold]")
            for f in result.key_files[:10]:
                console.print(f"  • {f}")
        raise typer.Exit(0)
    else:
        console.print(f"[red]Error: {result.error}[/red]")
        raise typer.Exit(1)


@app.command()
def review(
    target: Optional[str] = typer.Argument(
        None,
        help="File or directory to review (default: unstaged changes)",
    ),
    project_dir: Optional[Path] = typer.Option(
        None,
        "--project", "-p",
        help="Project directory (default: current directory)",
    ),
    provider: Optional[str] = typer.Option(
        None,
        "--provider",
        help="LLM provider",
    ),
    model: Optional[str] = typer.Option(
        None,
        "--model", "-m",
        help="Model to use",
    ),
    api_key: Optional[str] = typer.Option(
        None,
        "--api-key", "-k",
        help="API key for the LLM provider",
    ),
):
    """
    Launch a code-reviewer agent to review code.
    
    Example:
        cq review                          # Review unstaged changes
        cq review src/auth/                # Review specific directory
        cq review main.py                  # Review specific file
    """
    from ai_coder.agents.launcher import AgentLauncher
    from ai_coder.agents.base import AgentType
    from ai_coder.tools.base import create_tool_registry
    import subprocess
    
    # Load config
    config = load_config()
    llm_config = config.get("llm", {})
    
    provider_name = provider or llm_config.get("provider", "openai")
    model_name = model or llm_config.get("model", "gpt-4o")
    project_path = (project_dir or Path.cwd()).resolve()
    
    # Get review target
    if target:
        review_prompt = f"Review the code in: {target}"
    else:
        # Get unstaged changes
        try:
            result = subprocess.run(
                ["git", "diff"],
                cwd=project_path,
                capture_output=True,
                text=True,
            )
            if result.stdout.strip():
                review_prompt = f"Review these unstaged changes:\n\n```diff\n{result.stdout}\n```"
            else:
                console.print("[yellow]No unstaged changes found[/yellow]")
                raise typer.Exit(0)
        except Exception:
            console.print("[yellow]Could not get git diff, please specify a target[/yellow]")
            raise typer.Exit(1)
    
    console.print(Panel(
        f"[bold red]🔍 Code Reviewer[/bold red]\n"
        f"Target: {target or 'unstaged changes'}",
        border_style="red",
    ))
    
    # Initialize LLM
    keyless_providers = {"ollama", "lmstudio", "custom"}
    if provider_name in keyless_providers:
        key = api_key or ""
    else:
        key = api_key or get_api_key(provider_name)
    
    try:
        llm = get_provider(
            provider_name,
            LLMConfig(
                model=model_name,
                api_key=key,
            )
        )
    except Exception as e:
        console.print(f"[red]Error initializing LLM: {e}[/red]")
        raise typer.Exit(1)
    
    # Launch reviewer agent
    tool_registry = create_tool_registry(project_path)
    launcher = AgentLauncher(llm, tool_registry, project_path)
    result = launcher.launch_single(AgentType.CODE_REVIEWER, review_prompt)
    
    if result.success:
        console.print(result.output)
        raise typer.Exit(0)
    else:
        console.print(f"[red]Error: {result.error}[/red]")
        raise typer.Exit(1)


def _launch_agent(agent_type_str: str, prompt: str, project_dir, provider, model, api_key):
    """Shared helper to launch any agent type from CLI."""
    from ai_coder.agents.launcher import AgentLauncher
    from ai_coder.agents.base import AgentType
    from ai_coder.tools.base import create_tool_registry
    
    config = load_config()
    llm_config = config.get("llm", {})
    
    provider_name = provider or llm_config.get("provider", "openai")
    model_name = model or llm_config.get("model", "gpt-4o")
    project_path = (project_dir or Path.cwd()).resolve()
    
    # Map string to AgentType
    type_map = {t.value: t for t in AgentType}
    agent_type = type_map.get(agent_type_str)
    if not agent_type:
        console.print(f"[red]Unknown agent type: {agent_type_str}[/red]")
        raise typer.Exit(1)
    
    console.print(Panel(
        f"[bold {agent_type.color}]{agent_type.display_name}[/bold {agent_type.color}]\n"
        f"Task: {prompt}",
        border_style=agent_type.color,
    ))
    
    keyless_providers = {"ollama", "lmstudio", "custom"}
    if provider_name in keyless_providers:
        key = api_key or ""
    else:
        key = api_key or get_api_key(provider_name)
    
    try:
        llm = get_provider(provider_name, LLMConfig(model=model_name, api_key=key))
    except Exception as e:
        console.print(f"[red]Error initializing LLM: {e}[/red]")
        raise typer.Exit(1)
    
    tool_registry = create_tool_registry(project_path)
    launcher = AgentLauncher(llm, tool_registry, project_path)
    result = launcher.launch_single(agent_type, prompt)
    
    if result.success:
        if result.key_files:
            console.print("\n[bold]Key Files:[/bold]")
            for f in result.key_files[:10]:
                console.print(f"  • {f}")
        raise typer.Exit(0)
    else:
        console.print(f"[red]Error: {result.error}[/red]")
        raise typer.Exit(1)


# Common options for agent commands
_project_opt = typer.Option(None, "--project", "-p", help="Project directory")
_provider_opt = typer.Option(None, "--provider", help="LLM provider")
_model_opt = typer.Option(None, "--model", "-m", help="Model to use")
_key_opt = typer.Option(None, "--api-key", "-k", help="API key")


@app.command()
def plan(
    task: str = typer.Argument(..., help="Feature or change to plan"),
    project_dir: Optional[Path] = _project_opt,
    provider: Optional[str] = _provider_opt,
    model: Optional[str] = _model_opt,
    api_key: Optional[str] = _key_opt,
):
    """
    Create an implementation plan before writing code.
    
    Example:
        cq plan "Add user authentication with OAuth"
        cq plan "Refactor database layer" --provider ollama
    """
    _launch_agent("planner", task, project_dir, provider, model, api_key)


@app.command()
def security(
    target: str = typer.Argument(".", help="File or directory to audit"),
    project_dir: Optional[Path] = _project_opt,
    provider: Optional[str] = _provider_opt,
    model: Optional[str] = _model_opt,
    api_key: Optional[str] = _key_opt,
):
    """
    Run a security audit on the codebase.
    
    Example:
        cq security
        cq security src/auth/
    """
    prompt = f"Perform a security audit on: {target}. Check for OWASP Top 10, injection, auth issues, secrets in code."
    _launch_agent("security-reviewer", prompt, project_dir, provider, model, api_key)


@app.command()
def tdd(
    feature: str = typer.Argument(..., help="Feature to implement with TDD"),
    project_dir: Optional[Path] = _project_opt,
    provider: Optional[str] = _provider_opt,
    model: Optional[str] = _model_opt,
    api_key: Optional[str] = _key_opt,
):
    """
    Implement a feature using Test-Driven Development.
    
    Example:
        cq tdd "Add a function to calculate fibonacci numbers"
        cq tdd "Create user registration with validation"
    """
    _launch_agent("tdd-guide", feature, project_dir, provider, model, api_key)


@app.command(name="build-fix")
def build_fix(
    command: str = typer.Argument("", help="Build command to run (auto-detected if empty)"),
    project_dir: Optional[Path] = _project_opt,
    provider: Optional[str] = _provider_opt,
    model: Optional[str] = _model_opt,
    api_key: Optional[str] = _key_opt,
):
    """
    Fix build errors automatically.
    
    Example:
        cq build-fix
        cq build-fix "npm run build"
        cq build-fix "cargo build"
    """
    if command:
        prompt = f"Run '{command}', diagnose any errors, and fix them."
    else:
        prompt = "Detect the project type, run the build command, diagnose errors, and fix them."
    _launch_agent("build-fixer", prompt, project_dir, provider, model, api_key)


@app.command()
def debug(
    issue: str = typer.Argument(..., help="Description of the bug or issue"),
    project_dir: Optional[Path] = _project_opt,
    provider: Optional[str] = _provider_opt,
    model: Optional[str] = _model_opt,
    api_key: Optional[str] = _key_opt,
):
    """
    Debug and fix an issue systematically.
    
    Example:
        cq debug "Login fails with 401 error"
        cq debug "Tests timeout on CI"
    """
    _launch_agent("debugger", issue, project_dir, provider, model, api_key)


@app.command()
def refactor(
    target: str = typer.Argument(".", help="File or module to refactor"),
    project_dir: Optional[Path] = _project_opt,
    provider: Optional[str] = _provider_opt,
    model: Optional[str] = _model_opt,
    api_key: Optional[str] = _key_opt,
):
    """
    Refactor code to improve quality without changing behavior.
    
    Example:
        cq refactor src/utils.py
        cq refactor "the authentication module"
    """
    prompt = f"Refactor: {target}. Improve code quality, reduce duplication, improve naming. Keep behavior unchanged."
    _launch_agent("refactor", prompt, project_dir, provider, model, api_key)


@app.command()
def skills():
    """
    List all available skills.
    
    Skills are domain knowledge files that agents can load on-demand.
    
    Example:
        cq skills
    """
    from ai_coder.skills.loader import SkillLoader
    
    skills_dir = Path(__file__).parent / "skills"
    loader = SkillLoader(skills_dir)
    
    if not loader.skills:
        console.print("[dim]No skills found.[/dim]")
        raise typer.Exit(0)
    
    console.print("\n[bold cyan]📚 Available Skills[/bold cyan]\n")
    for name, skill in sorted(loader.skills.items()):
        console.print(f"  [bold]{name}[/bold] - {skill['description']}")
    
    console.print(f"\n[dim]Total: {len(loader.skills)} skills[/dim]")
    console.print("[dim]Agents load skills automatically with the use_skill tool[/dim]")
    raise typer.Exit(0)


@app.command()
def build(
    description: str = typer.Argument(..., help="What to build (e.g., 'a portfolio website')"),
    project_dir: Optional[Path] = typer.Option(
        None,
        "--project", "-p",
        help="Output directory for the project (default: current directory)",
    ),
    provider: Optional[str] = typer.Option(
        None,
        "--provider",
        help="LLM provider",
    ),
    model: Optional[str] = typer.Option(
        None,
        "--model", "-m",
        help="Model to use",
    ),
    api_key: Optional[str] = typer.Option(
        None,
        "--api-key", "-k",
        help="API key for the LLM provider",
    ),
    max_iterations: Optional[int] = typer.Option(
        30,
        "--max-iterations", "-i",
        help="Maximum iterations (default: 30)",
    ),
):
    """
    Plan and build a project from scratch.

    This is the all-in-one command: describe what you want, and the AI
    creates an implementation plan then builds the entire project.

    Example:
        cq build "a portfolio website with hero, projects, and contact sections"
        cq build "a REST API with Flask for a todo app" -p ./todo-api
        cq build "a React dashboard with charts" --provider huggingface
    """
    # Load config
    config = load_config()
    llm_config = config.get("llm", {})

    provider_name = provider or llm_config.get("provider", "openai")
    model_name = model or llm_config.get("model", "gpt-4o")
    project_path = (project_dir or Path.cwd()).resolve()

    # Create project dir if needed
    project_path.mkdir(parents=True, exist_ok=True)

    console.print(Panel(
        f"[bold green]🏗️  Build Mode[/bold green]\n"
        f"Building: {description}\n"
        f"Directory: {project_path}\n"
        f"Provider: {provider_name} | Model: {model_name}",
        border_style="green",
    ))

    # Get API key
    keyless_providers = {"ollama", "lmstudio", "custom"}
    if provider_name in keyless_providers:
        key = api_key or ""
    else:
        key = api_key or get_api_key(provider_name)

    # Get API base URL
    api_base = llm_config.get("api_base") or os.getenv(f"{provider_name.upper()}_API_BASE")

    try:
        llm_cfg = LLMConfig(
            model=model_name,
            max_tokens=llm_config.get("max_tokens", 4096),
            temperature=llm_config.get("temperature", 0.1),
            api_key=key,
            api_base=api_base,
        )
        llm = get_provider(provider_name, llm_cfg)
    except Exception as e:
        console.print(f"[red]Error initializing LLM: {e}[/red]")
        raise typer.Exit(1)

    # Build the enriched task prompt
    enriched_task = f"""Build this project from scratch: {description}

INSTRUCTIONS:
1. First, create an implementation plan listing all files you need to create
2. Then create each file one by one using the write_file tool
3. Start with the main HTML file (index.html), then CSS (style.css), then JavaScript (script.js)
4. Make the design modern, responsive, and visually impressive
5. Use clean, well-structured code
6. When all files are created, call task_complete

IMPORTANT:
- Create ALL files needed for a complete, working project
- Do NOT just plan — actually CREATE the files using write_file
- Each file should be complete and production-ready"""

    # Initialize orchestrator with auto-confirm (building from scratch)
    agent_cfg = AgentConfig(
        max_iterations=max_iterations,
        auto_confirm=True,  # No need to confirm when building from scratch
        verbose=False,
        provider=provider_name,
        model=model_name,
    )

    agent = AgentOrchestrator(
        llm=llm,
        project_root=project_path,
        config=agent_cfg,
    )

    # Run the build task
    success = agent.run(enriched_task)

    if success:
        console.print("\n[bold green]✅ Build complete![/bold green]")
        console.print(f"[dim]Project files are in: {project_path}[/dim]")
    else:
        console.print("\n[yellow]Build did not complete fully. Check output above.[/yellow]")

    raise typer.Exit(0 if success else 1)


def main():
    """Main entry point."""
    app()


if __name__ == "__main__":
    main()

