#!/usr/bin/env python3
"""
Crowe Logic CLI — Universal AI Agent

Usage:
    crowe-logic chat                  # Interactive chat session
    crowe-logic run "your prompt"     # Single prompt, get response
    crowe-logic deploy                # Create/recreate the agent
    crowe-logic status                # Show agent status
    crowe-logic tools                 # List available tools
"""

import os
import sys
import json
import time

# Add project root to path
PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, PROJECT_ROOT)

import click
from rich.console import Console
from rich.markdown import Markdown
from rich.panel import Panel
from rich.text import Text

from dotenv import load_dotenv
load_dotenv(os.path.join(PROJECT_ROOT, ".env"))

from cli.branding import (
    welcome_screen, prompt_string, agent_prefix,
    show_inline_image, BANNER_COMPACT, PROMPT_ICON, GOLD, RESET, BOLD,
)

console = Console()

ICON_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "icon.png")

AGENT_ID_FILE = os.path.join(PROJECT_ROOT, ".agent_id")


def get_agent_id() -> str:
    """Load saved agent ID from .agent_id file."""
    if not os.path.exists(AGENT_ID_FILE):
        console.print("[red]No agent found. Run: crowe-logic deploy[/red]")
        sys.exit(1)
    with open(AGENT_ID_FILE) as f:
        data = json.load(f)
    return data["agent_id"]


def get_client():
    """Create and return an AgentsClient."""
    from azure.ai.agents import AgentsClient
    from azure.identity import DefaultAzureCredential
    from config.agent_config import PROJECT_ENDPOINT

    return AgentsClient(
        endpoint=PROJECT_ENDPOINT,
        credential=DefaultAzureCredential(),
    )


def setup_toolset(client):
    """Configure the toolset with auto function calling."""
    from azure.ai.agents.models import FunctionTool, ToolSet, CodeInterpreterTool
    from tools import user_functions

    toolset = ToolSet()
    toolset.add(FunctionTool(user_functions))
    toolset.add(CodeInterpreterTool())
    client.enable_auto_function_calls(toolset)
    return toolset


def stream_response(client, thread_id: str, agent_id: str):
    """Stream agent response with rich formatting."""
    from azure.ai.agents.models import MessageDeltaChunk, ThreadMessage, ThreadRun, RunStep, AgentStreamEvent

    full_text = ""

    with client.runs.stream(thread_id=thread_id, agent_id=agent_id) as stream:
        for event_type, event_data, _ in stream:
            if isinstance(event_data, MessageDeltaChunk):
                if event_data.text:
                    console.print(event_data.text, end="")
                    full_text += event_data.text

            elif isinstance(event_data, ThreadRun):
                if event_data.status == "failed":
                    console.print(f"\n[red]Run failed: {event_data.last_error}[/red]")

            elif isinstance(event_data, RunStep):
                if event_data.type == "tool_calls" and event_data.status == "in_progress":
                    console.print("\n[dim]  (calling tools...)[/dim]", end="")

            elif event_type == AgentStreamEvent.ERROR:
                console.print(f"\n[red]Error: {event_data}[/red]")

            elif event_type == AgentStreamEvent.DONE:
                break

    console.print()  # Final newline
    return full_text


@click.group()
@click.version_option(version="0.1.0", prog_name="crowe-logic")
def main():
    """Crowe Logic — Universal AI Agent powered by gpt-oss-120b"""
    pass


@main.command()
def chat():
    """Start an interactive chat session with the agent."""
    from prompt_toolkit import PromptSession
    from prompt_toolkit.history import FileHistory

    agent_id = get_agent_id()
    client = get_client()
    setup_toolset(client)

    # Create a thread for this session
    thread = client.threads.create()

    # Show inline image in supported terminals (iTerm2, WezTerm, Ghostty)
    show_inline_image(ICON_PATH, width=8)

    # Print the branded welcome screen
    print(welcome_screen())


    history_file = os.path.join(PROJECT_ROOT, ".chat_history")
    session = PromptSession(history=FileHistory(history_file))

    while True:
        try:
            user_input = session.prompt(prompt_string(), multiline=False)
        except (EOFError, KeyboardInterrupt):
            print(f"\n{GOLD}{BOLD}Goodbye.{RESET}")
            break

        user_input = user_input.strip()
        if not user_input:
            continue
        if user_input.lower() in ("exit", "quit", "/exit", "/quit"):
            print(f"{GOLD}{BOLD}Goodbye.{RESET}")
            break

        # Handle CLI meta-commands
        if user_input.lower() == "/tools":
            _list_tools_inline()
            continue
        if user_input.lower() == "/clear":
            console.clear()
            print(welcome_screen())
            continue
        if user_input.lower() == "/status":
            _show_status_inline()
            continue

        # Send message
        client.messages.create(thread_id=thread.id, role="user", content=user_input)

        # Stream response
        console.print()
        print(agent_prefix(), end="", flush=True)
        stream_response(client, thread.id, agent_id)
        console.print()


def _list_tools_inline():
    """Show tools inside the chat session."""
    from tools import user_functions
    print(f"\n{GOLD}{'━' * 52}")
    print(f"  Available Tools ({len(user_functions)} custom + code interpreter){RESET}\n")
    for func in sorted(user_functions, key=lambda f: f.__name__):
        doc = (func.__doc__ or "").strip().split("\n")[0]
        print(f"  {GOLD}{func.__name__:25s}{RESET} {doc}")
    print(f"\n{GOLD}{'━' * 52}{RESET}\n")


def _show_status_inline():
    """Show status inside the chat session."""
    if not os.path.exists(AGENT_ID_FILE):
        print(f"  {GOLD}Status:{RESET} No agent deployed")
        return
    with open(AGENT_ID_FILE) as f:
        data = json.load(f)
    print(f"\n{GOLD}{'━' * 52}{RESET}")
    print(f"  {GOLD}Agent ID:{RESET}  {data.get('agent_id', 'unknown')}")
    print(f"  {GOLD}Name:{RESET}     {data.get('name', 'unknown')}")
    print(f"  {GOLD}Model:{RESET}    {data.get('model', 'unknown')}")
    print(f"  {GOLD}Version:{RESET}  {data.get('version', 'unknown')}")
    print(f"{GOLD}{'━' * 52}{RESET}\n")


@main.command()
@click.argument("prompt")
def run(prompt: str):
    """Run a single prompt and print the response."""
    agent_id = get_agent_id()
    client = get_client()
    setup_toolset(client)

    thread = client.threads.create()
    client.messages.create(thread_id=thread.id, role="user", content=prompt)

    stream_response(client, thread.id, agent_id)


@main.command()
@click.option("--name", default="crowe-logic", help="Agent name")
def deploy(name: str):
    """Create or recreate the Crowe Logic agent."""
    from scripts.create_agent import create_agent
    create_agent(name=name, verbose=True)


@main.command()
def status():
    """Show current agent status."""
    if not os.path.exists(AGENT_ID_FILE):
        console.print("[red]No agent deployed. Run: crowe-logic deploy[/red]")
        return

    with open(AGENT_ID_FILE) as f:
        data = json.load(f)

    console.print(Panel(
        Text.from_markup(
            f"[bold cyan]CROWE LOGIC STATUS[/bold cyan]\n\n"
            f"[bold]Agent ID:[/bold]  {data.get('agent_id', 'unknown')}\n"
            f"[bold]Name:[/bold]     {data.get('name', 'unknown')}\n"
            f"[bold]Version:[/bold]  {data.get('version', 'unknown')}\n"
            f"[bold]Model:[/bold]    {data.get('model', 'unknown')}"
        ),
        border_style="cyan",
        padding=(1, 2),
    ))


@main.command()
def tools():
    """List all available tools."""
    from tools import user_functions

    console.print(Panel("[bold cyan]CROWE LOGIC — AVAILABLE TOOLS[/bold cyan]", border_style="cyan"))
    console.print()

    # Custom function tools
    console.print("[bold]Custom Function Tools:[/bold]")
    for func in sorted(user_functions, key=lambda f: f.__name__):
        doc = (func.__doc__ or "").strip().split("\n")[0]
        console.print(f"  [cyan]{func.__name__:25s}[/cyan] {doc}")

    console.print()
    console.print("[bold]Built-in Azure Tools:[/bold]")
    console.print(f"  [cyan]{'code_interpreter':25s}[/cyan] Run Python code in a sandboxed environment")
    console.print(f"  [cyan]{'bing_grounding':25s}[/cyan] Search the web via Bing (requires connection)")
    console.print(f"  [cyan]{'file_search':25s}[/cyan] RAG over uploaded documents (requires vector store)")
    console.print(f"  [cyan]{'azure_ai_search':25s}[/cyan] Vector search over knowledge base (requires index)")


if __name__ == "__main__":
    main()
