"""Tool config creation modal for creating new tool configurations.

Provides a modal screen that allows users to create a new tool configuration
with required fields: name, tool_id, config JSON, and optional description.
"""

import json
from dataclasses import dataclass
from typing import Any

from textual import on, work
from textual.app import ComposeResult
from textual.containers import Horizontal, VerticalScroll
from textual.widgets import (
    Button,
    Input,
    Label,
    RadioButton,
    RadioSet,
    Static,
    TextArea,
)

from cli.infrastructure.scope_utils import get_scope_from_radioset
from cli.tui.widgets.base_form_modal import BaseFormModal

from alloy_runtime_sdk.api_client.client import ApiClient
from alloy_runtime_types.dtos.tool_configs import CreateToolConfigRequest
from alloy_runtime_types.enums.ownership_scope import OwnershipScope


@dataclass
class ToolConfigCreateResult:
    """Result of successful tool config creation."""

    config_id: str
    config_name: str


class ToolConfigCreateModal(BaseFormModal[ToolConfigCreateResult]):
    """Modal for creating a new tool configuration.

    Provides a form with:
    - Required fields: name, tool_id, config (JSON)
    - Scope selection (user/organization/global)
    - Optional: description

    Usage:
        def on_config_created(result: ToolConfigCreateResult | None):
            if result is not None:
                self.notify(f"Created config: {result.config_name}")
                self._do_search("")  # Refresh list

        client = await self.app.store.get_client()
        self.app.push_screen(
            ToolConfigCreateModal(client=client),
            on_config_created
        )
    """

    def __init__(
        self,
        client: ApiClient,
        **kwargs: Any,
    ) -> None:
        """Initialize the tool config creation modal.

        Args:
            client: ApiClient instance for API calls
        """
        super().__init__(**kwargs)
        self._client = client

    def compose(self) -> ComposeResult:
        with VerticalScroll(id="tool-config-create-modal"):
            yield Label("Create Tool Config", classes="modal-title")

            # ===== REQUIRED FIELDS =====
            yield Static("[bold]Required[/]", classes="form-section")

            yield Static("Name", classes="field-label")
            yield Input(
                placeholder="e.g., RAG with HyDE, Fast Web Search",
                id="name-input",
            )

            yield Static("Tool ID", classes="field-label")
            yield Input(
                placeholder="e.g., rag_search, web_search",
                id="tool-id-input",
            )

            yield Static("Scope", classes="field-label")
            with RadioSet(id="scope-radios"):
                yield RadioButton("User (personal)", id="scope-user")
                yield RadioButton("Organization", id="scope-org", value=True)
                yield RadioButton("Global", id="scope-global")

            yield Static(
                "Configuration (JSON object with tool parameters)",
                classes="field-label",
            )
            yield TextArea(
                id="config-textarea",
                classes="definition-input",
            )

            # ===== OPTIONAL FIELDS =====
            yield Static("[bold]Optional[/]", classes="form-section")

            yield Static("Description", classes="field-label")
            yield Input(
                placeholder="Brief description of this configuration",
                id="description-input",
            )

            # Error display
            yield Static("", id="error-display", classes="error-display")

            with Horizontal(classes="button-row"):
                yield Button("Create Config", id="create-btn", variant="success")
                yield Button("Cancel", id="cancel-btn", variant="default")

    def on_mount(self) -> None:
        """Focus the name input and set default config on mount."""
        self.query_one("#config-textarea", TextArea).text = "{}"
        self.query_one("#name-input", Input).focus()

    @on(Button.Pressed, "#create-btn")
    def on_create_pressed(self, event: Button.Pressed) -> None:
        """Handle create button press."""
        self.action_submit()

    @on(Button.Pressed, "#cancel-btn")
    def on_cancel_pressed(self, event: Button.Pressed) -> None:
        """Handle cancel button press."""
        self.dismiss(None)

    def action_submit(self) -> None:
        """Handle form submission."""
        try:
            self._validate_fields()
            self._hide_error()
            self._finalize_submission()
        except ValueError as e:
            self._show_error(str(e))

    def _validate_fields(self) -> None:
        """Validate all required fields."""
        name = self.query_one("#name-input", Input).value.strip()
        if not name:
            raise ValueError("Name is required")
        if len(name) > 255:
            raise ValueError("Name must be 255 characters or less")

        tool_id = self.query_one("#tool-id-input", Input).value.strip()
        if not tool_id:
            raise ValueError("Tool ID is required")

        config_text = self.query_one("#config-textarea", TextArea).text.strip()
        if not config_text:
            raise ValueError("Configuration is required")

        try:
            config = json.loads(config_text)
            if not isinstance(config, dict):
                raise ValueError(
                    "Configuration must be a JSON object (not array/primitive)"
                )
        except json.JSONDecodeError as e:
            raise ValueError(f"Invalid JSON in configuration: {e.msg}")

    def _get_scope(self) -> OwnershipScope:
        """Get scope from RadioSet."""
        return get_scope_from_radioset(self.query_one("#scope-radios", RadioSet))

    def _build_request(self) -> CreateToolConfigRequest:
        """Build the API request."""
        name = self.query_one("#name-input", Input).value.strip()
        tool_id = self.query_one("#tool-id-input", Input).value.strip()
        config_text = self.query_one("#config-textarea", TextArea).text.strip()
        config = json.loads(config_text)
        description = self.query_one("#description-input", Input).value.strip() or None

        return CreateToolConfigRequest(
            name=name,
            tool_id=tool_id,
            config=config,
            description=description,
            scope=self._get_scope(),
        )

    @work(exclusive=True)
    async def _finalize_submission(self) -> None:
        """Submit to API."""
        try:
            request = self._build_request()
            response = await self._client.create_tool_config(request)

            result = ToolConfigCreateResult(
                config_id=str(response.id),
                config_name=response.name,
            )
            self.dismiss(result)

        except Exception as e:
            error_msg = str(e)
            # Provide user-friendly error messages
            if "409" in error_msg or "conflict" in error_msg.lower():
                self._show_error(
                    "A tool config with this name already exists in this scope"
                )
            elif "validation" in error_msg.lower():
                self._show_error(f"Invalid configuration: {error_msg}")
            else:
                self._show_error(f"Failed to create tool config: {error_msg}")
