"""Database search tools."""

from pydantic_ai import RunContext
from pydantic_ai.toolsets import FunctionToolset

from pydanticai_multiagent.dependencies import BaseDeps

db_search_toolset: FunctionToolset[BaseDeps] = FunctionToolset()


@db_search_toolset.tool
async def query_users(
    ctx: RunContext[BaseDeps],
    email: str | None = None,
    name_contains: str | None = None,
    is_active: bool | None = None,
    limit: int = 10,
) -> str:
    """Query user records from the database.

    Args:
        ctx: The run context with dependencies.
        email: Filter by exact email match.
        name_contains: Filter by name containing this string.
        is_active: Filter by active status.
        limit: Maximum number of records to return.
    """
    conditions = []
    params: list[str | bool] = []

    if email:
        conditions.append("email = $" + str(len(params) + 1))
        params.append(email)
    if name_contains:
        conditions.append("name ILIKE $" + str(len(params) + 1))
        params.append(f"%{name_contains}%")
    if is_active is not None:
        conditions.append("is_active = $" + str(len(params) + 1))
        params.append(is_active)

    where_clause = " AND ".join(conditions) if conditions else "1=1"
    query = f"SELECT id, email, name, is_active FROM users WHERE {where_clause} LIMIT {limit}"

    users = await ctx.deps.db.fetch_all(query, *params)

    if not users:
        return "No users found matching the criteria."

    formatted = []
    for u in users:
        status = "active" if u["is_active"] else "inactive"
        formatted.append(f"- {u['name']} ({u['email']}) [{status}]")

    return f"Found {len(users)} user(s):\n" + "\n".join(formatted)


@db_search_toolset.tool
async def query_orders(
    ctx: RunContext[BaseDeps],
    user_id: str | None = None,
    status: str | None = None,
    limit: int = 10,
) -> str:
    """Query order records from the database.

    Args:
        ctx: The run context with dependencies.
        user_id: Filter by user ID.
        status: Filter by order status (pending, completed, cancelled).
        limit: Maximum number of records to return.
    """
    conditions = []
    params: list[str] = []

    if user_id:
        conditions.append("user_id = $" + str(len(params) + 1))
        params.append(user_id)
    if status:
        conditions.append("status = $" + str(len(params) + 1))
        params.append(status)

    where_clause = " AND ".join(conditions) if conditions else "1=1"
    query = f"""
        SELECT id, user_id, status, total_amount, created_at
        FROM orders
        WHERE {where_clause}
        ORDER BY created_at DESC
        LIMIT {limit}
    """

    orders = await ctx.deps.db.fetch_all(query, *params)

    if not orders:
        return "No orders found matching the criteria."

    formatted = []
    for o in orders:
        formatted.append(
            f"- Order {o['id']}: ${o['total_amount']:.2f} ({o['status']}) - {o['created_at']}"
        )

    return f"Found {len(orders)} order(s):\n" + "\n".join(formatted)


@db_search_toolset.tool
async def get_user_statistics(
    ctx: RunContext[BaseDeps],
    user_id: str,
) -> str:
    """Get statistics for a specific user.

    Args:
        ctx: The run context with dependencies.
        user_id: The user ID to get statistics for.
    """
    stats_query = """
        SELECT
            COUNT(*) as total_orders,
            COALESCE(SUM(total_amount), 0) as total_spent,
            COALESCE(AVG(total_amount), 0) as avg_order_value
        FROM orders
        WHERE user_id = $1
    """

    result = await ctx.deps.db.fetch_one(stats_query, user_id)

    if not result:
        return f"No data found for user: {user_id}"

    return f"""User Statistics for {user_id}:
- Total Orders: {result['total_orders']}
- Total Spent: ${result['total_spent']:.2f}
- Average Order Value: ${result['avg_order_value']:.2f}"""
