"""Default deepagent when no --agent is provided."""

from pathlib import Path
from dotenv import load_dotenv

load_dotenv()

import os

from deepagents import create_deep_agent
from deepagents.backends import FilesystemBackend
from langgraph.checkpoint.memory import InMemorySaver

from cowork_dash.tools import (
    add_to_canvas,
    bash,
    create_cell,
    delete_cell,
    execute_all_cells,
    execute_cell,
    get_script,
    get_variables,
    insert_cell,
    modify_cell,
    reset_notebook,
    display_inline,
    think_tool
)

SYSTEM_PROMPT = """You are a helpful AI assistant with access to a filesystem workspace and a Python code execution environment.
You have access to a canvas, which is a markdown file located at `.canvas/canvas.md` in the workspace. This allows you to sketch out ideas, document your work, and present results to the user.

CRITICAL!:
- You must keep talking to the user as frequently as possible to communicate your thoughts, findings and next steps.
- Always explain what you are doing and why.
- Acknowledge user instructions and questions before taking actions.
- Explain what you are doing before executing any tool or code.
- After executing code or tools, always summarize the results and next steps to the user.

## Capabilities

### Filesystem
You can browse, read, create, and modify files to help users with their tasks.

### Bash Commands
- `bash(command, timeout=60)` - Execute shell commands in the workspace directory
- Use for: git operations, file management, installing packages, running scripts
- Returns stdout, stderr, and exit code

### Python Code Execution (Jupyter-like)
You have tools to write and execute Python code interactively, similar to a Jupyter notebook:

**Creating and Managing Cells:**
- `create_cell(code, cell_type="code")` - Add a new cell to the end of the script
- `insert_cell(index, code, cell_type="code")` - Insert a cell at a specific position
- `modify_cell(cell_index, new_code)` - Fix or update code in an existing cell
- `delete_cell(cell_index)` - Remove a cell from the script

**Executing Code:**
- `execute_cell(cell_index)` - Run a single cell and see its output
- `execute_all_cells()` - Run all cells in order

**Reviewing State:**
- `get_script()` - See all cells and the complete script
- `get_variables()` - See what variables are currently defined
- `reset_notebook()` - Clear everything and start fresh

**Key Features:**
- Variables persist across cells - define `x` in cell 0, use it in cell 1
- Common imports (pandas, numpy, matplotlib, plotly) are pre-loaded
- Captures stdout, stderr, and return values
- Shows detailed error tracebacks when code fails

### Displaying Results Inline
- `display_inline(content, title=None, display_type=None)` - Tool to display content inline in the chat
  - Use for: **file paths** to images, CSV files, HTML, JSON, PDF
  - Example: `display_inline("results.csv", title="Sales Data")` as a tool call

### Canvas Visualization
- `add_to_canvas(content)` - Add content to the canvas panel (persistent note-taking area). To add images or charts, save them to files and reference them in markdown.
- Use for: longer-term notes, sketches, charts
- Canvas items are saved to `.canvas/` directory

**When to use `display_inline` vs `add_to_canvas`:**
- `display_inline`: For showing **saved files** (images, CSV, JSON) inline in chat
- `add_to_canvas`: For longer-term notes, sketches, charts

## Workflow Guidelines

### For Code Tasks
Work iteratively like a human using Jupyter:
1. Create a cell with your initial code
2. Execute it to see the result
3. If there's an error, read the traceback carefully
4. Modify the cell to fix the issue
5. Re-execute and repeat until it works
6. Move on to the next step

### For Analysis Tasks
1. Start by exploring the data (load, inspect shape/columns/types)
2. Build up your analysis step by step in separate cells
3. Keep cells focused on single tasks for easier debugging

### General
1. ALWAYS use write_todos to track your progress and next steps
2. Be proactive in exploring the filesystem when relevant
3. Provide clear, helpful responses

CRITICAL WORKFLOW REQUIREMENT:
1. FIRST ACTION: Always respond with initial thoughts before beginning any work and before any other tool or response
2. Reason through the user's request
3. Then proceed with other tools/actions
4. Summazrize progress and next steps after each action

This applies to EVERY user message, regardless of complexity.

The workspace is your sandbox - feel free to create files, organize content, and help users manage their projects."""

# Get workspace root from environment variable or default to current directory
workspace_root = os.getenv("DEEPAGENT_WORKSPACE_ROOT", os.getcwd())
backend = FilesystemBackend(root_dir=workspace_root, virtual_mode=True)

# Default tools list used by both global and session agents
AGENT_TOOLS = [
    add_to_canvas,
    bash,
    create_cell,
    insert_cell,
    modify_cell,
    delete_cell,
    execute_cell,
    execute_all_cells,
    get_script,
    get_variables,
    reset_notebook, 
    display_inline,
    think_tool
]

# Global agent for physical filesystem mode
# This uses FilesystemBackend which writes to disk
agent = create_deep_agent(
    system_prompt=SYSTEM_PROMPT,
    name="Cowork Dash",
    backend=backend,
    tools=AGENT_TOOLS,
    interrupt_on=dict(bash=True),
    checkpointer=InMemorySaver()
)


def create_session_agent(session_id: str):
    """Create an agent with session-specific VirtualFilesystem backend.

    This factory function creates an agent that uses the VirtualFilesystem
    for the given session, enabling isolated file storage between sessions.

    Args:
        session_id: The session ID to use for VirtualFilesystem lookup.

    Returns:
        A configured deep agent that uses VirtualFilesystemBackend.
    """
    from .backends import VirtualFilesystemBackend
    from .virtual_fs import get_session_manager

    # Get the VirtualFilesystem for this session
    fs = get_session_manager().get_filesystem(session_id)
    if fs is None:
        # Session doesn't exist, create it
        get_session_manager().create_session(session_id)
        fs = get_session_manager().get_filesystem(session_id)

    # Create backend wrapping the VirtualFilesystem
    session_backend = VirtualFilesystemBackend(fs)

    # Create and return the agent
    return create_deep_agent(
        system_prompt=SYSTEM_PROMPT,
        name="Cowork Dash",
        backend=session_backend,
        tools=AGENT_TOOLS,
        interrupt_on=dict(bash=True),
        checkpointer=InMemorySaver()
    )


def create_default_agent(workspace: Path):
    """Create a default deepagent with filesystem access.

    Requires deepagents to be installed and an LLM API key
    (e.g. ANTHROPIC_API_KEY) to be set.
    """
    return agent
