"""Tool config create command implementation."""

import json
from typing import Any, Optional, cast

import typer

from cli.commands.flag_utils import validate_scope
from cli.commands.tool_configs.create.presenter import (
    present_tool_config_create_success,
)
from cli.infrastructure.command import async_command, authenticated_client
from cli.infrastructure.file_content import FileContentError, resolve_content
from alloy_runtime_types.dtos.tool_configs import CreateToolConfigRequest
from alloy_runtime_types.enums.ownership_scope import OwnershipScope


def tool_configs_create_command(
    name: str = typer.Option(
        ...,
        "-n",
        "--name",
        help="Human-readable name for this tool config",
    ),
    tool_id: str = typer.Option(
        ...,
        "--tool-id",
        help="Tool implementation ID (e.g., 'rag_search', 'web_search')",
    ),
    config: str = typer.Option(
        ...,
        "-c",
        "--config",
        help="Tool configuration as JSON (or @file.json to read from file)",
    ),
    description: Optional[str] = typer.Option(
        None,
        "-d",
        "--description",
        help="Optional description of what this config is for",
    ),
    scope: Optional[str] = typer.Option(
        None,
        "--scope",
        help="Ownership scope: organization (default), user, global",
    ),
) -> None:
    """Create a reusable tool configuration.

    Tool configs store validated configurations that can be referenced by multiple
    agents, eliminating duplication.

    Examples:
        alloy tool-configs create -n "RAG with HyDE" --tool-id rag_search -c '{"top_k": 10}'
        alloy tool-configs create -n "Web Search" --tool-id web_search -c @config.json
        alloy tool-configs create -n "Search" --tool-id rag_search -c '{}' --scope organization
    """
    _execute_create_from_flags(
        name=name,
        tool_id=tool_id,
        config=config,
        description=description,
        scope=scope,
    )


@async_command
async def _execute_create(request: CreateToolConfigRequest) -> None:
    """Execute the tool config creation with the given request."""
    async with authenticated_client() as (_config, client):
        response = await client.create_tool_config(request)

    present_tool_config_create_success(response)


def _execute_create_from_flags(
    name: str,
    tool_id: str,
    config: str,
    description: Optional[str],
    scope: Optional[str],
) -> None:
    """Build and execute tool config creation from command flags."""
    # Resolve @file reference for config
    try:
        config_content = resolve_content(config)
    except FileContentError as e:
        raise typer.BadParameter(str(e))

    if not config_content:
        raise typer.BadParameter("Config cannot be empty")

    # Parse config as JSON
    try:
        config_dict_raw = json.loads(config_content)
    except json.JSONDecodeError as e:
        raise typer.BadParameter(f"Invalid JSON in config: {e}")

    if not isinstance(config_dict_raw, dict):
        raise typer.BadParameter("Config must be a JSON object")

    config_dict = cast(dict[str, Any], config_dict_raw)

    # Parse scope
    ownership_scope = OwnershipScope.ORGANIZATION
    if scope:
        ownership_scope = validate_scope(scope)

    # Build request
    request = CreateToolConfigRequest(
        name=name,
        tool_id=tool_id,
        config=config_dict,
        description=description,
        scope=ownership_scope,
    )

    _execute_create(request)
