"""Label tools - Source label management with consolidated label tool."""

from ...services import ServiceError, ValidationError
from ...services import labels as labels_service
from ._utils import ResultDict, coerce_list, error_result, get_client, logged_tool


@logged_tool()
def label(
    notebook_id: str,
    action: str,
    label_id: str | None = None,
    label_ids: str | list[str] | None = None,
    name: str | None = None,
    emoji: str | None = None,
    source_id: str | None = None,
    unlabeled_only: bool = False,
    confirm: bool = False,
) -> ResultDict:
    """Manage source labels in a notebook. Unified tool for all label operations.

    Labels let you organize sources into thematic categories. Requires 5+ sources
    for auto-labeling. Sources can belong to multiple labels simultaneously.

    Supports: auto, list, reorganize, create, rename, set_emoji, move_source, delete

    Args:
        notebook_id: Notebook UUID
        action: Operation to perform:
            - auto: AI auto-labels all sources into thematic categories
            - list: List current labels (triggers AI if none exist)
            - reorganize: Force AI re-categorization (requires confirm=True unless unlabeled_only=True)
            - create: Create a new empty label (requires name)
            - rename: Rename a label (requires label_id, name)
            - set_emoji: Set or clear emoji on a label (requires label_id, emoji)
            - move_source: Assign a source to a label (requires label_id, source_id)
            - delete: Delete label(s) permanently (requires label_id or label_ids, confirm=True)
        label_id: Label UUID (required for rename, set_emoji, move_source, delete)
        label_ids: List of label UUIDs for batch delete (alternative to label_id)
        name: Label display name (required for create and rename)
        emoji: Emoji character for set_emoji (e.g. "📊"), or "" to clear
        source_id: Source UUID to assign (required for move_source)
        unlabeled_only: For reorganize: if True, only label sources not yet in any label.
            If False (default), replaces ALL existing labels from scratch (requires confirm=True).
        confirm: Must be True for delete action and for reorganize with unlabeled_only=False

    Returns:
        Action-specific response with status

    Example:
        label(notebook_id="abc", action="auto")
        label(notebook_id="abc", action="list")
        label(notebook_id="abc", action="reorganize", confirm=True)
        label(notebook_id="abc", action="reorganize", unlabeled_only=True)
        label(notebook_id="abc", action="create", name="Research", emoji="📚")
        label(notebook_id="abc", action="rename", label_id="xyz", name="Better Name")
        label(notebook_id="abc", action="set_emoji", label_id="xyz", emoji="🎯")
        label(notebook_id="abc", action="move_source", label_id="xyz", source_id="src-id")
        label(notebook_id="abc", action="delete", label_id="xyz", confirm=True)
    """
    valid_actions = (
        "auto",
        "list",
        "reorganize",
        "create",
        "rename",
        "set_emoji",
        "move_source",
        "delete",
    )

    if action not in valid_actions:
        return {
            "status": "error",
            "error": f"Unknown action '{action}'. Valid actions: {', '.join(valid_actions)}",
        }

    try:
        client = get_client()

        if action == "auto":
            result = labels_service.auto_label(client, notebook_id)
            return {"status": "success", "action": "auto", **result}

        elif action == "list":
            result = labels_service.list_labels(client, notebook_id)
            return {"status": "success", "action": "list", **result}

        elif action == "reorganize":
            if not unlabeled_only and not confirm:
                return error_result(
                    "Reorganizing all sources replaces existing labels. Set confirm=True after "
                    "user approval, or use unlabeled_only=True to only label unlabeled sources.",
                    warning="This will NOT preserve existing labels.",
                )
            result = labels_service.reorganize_labels(client, notebook_id, unlabeled_only)
            scope = "unlabeled sources" if unlabeled_only else "all sources"
            return {"status": "success", "action": "reorganize", "scope": scope, **result}

        elif action == "create":
            if not name:
                return error_result("name is required for action='create'")
            result = labels_service.create_label(client, notebook_id, name, emoji or "")
            return {"status": "success", "action": "create", **result}

        elif action == "rename":
            if not label_id:
                return error_result("label_id is required for action='rename'")
            if not name:
                return error_result("name is required for action='rename'")
            result = labels_service.rename_label(client, notebook_id, label_id, name)
            return {"status": "success", "action": "rename", **result}

        elif action == "set_emoji":
            if not label_id:
                return error_result("label_id is required for action='set_emoji'")
            if emoji is None:
                return error_result("emoji is required for action='set_emoji' (use \"\" to clear)")
            result = labels_service.set_label_emoji(client, notebook_id, label_id, emoji)
            return {"status": "success", "action": "set_emoji", **result}

        elif action == "move_source":
            if not label_id:
                return error_result("label_id is required for action='move_source'")
            if not source_id:
                return error_result("source_id is required for action='move_source'")
            result = labels_service.move_source_to_label(client, notebook_id, label_id, source_id)
            return {"status": "success", "action": "move_source", **result}

        elif action == "delete":
            ids = coerce_list(label_ids) or ([label_id] if label_id else None)
            if not ids:
                return error_result("label_id or label_ids is required for action='delete'")
            if not confirm:
                return error_result(
                    "Deletion not confirmed. Set confirm=True after user approval.",
                    warning="This action is IRREVERSIBLE. Sources will be preserved.",
                )
            result = labels_service.delete_labels(client, notebook_id, ids)
            return {"status": "success", "action": "delete", **result}

        return error_result(f"Unhandled action: {action}")

    except (ServiceError, ValidationError) as e:
        return error_result(e.user_message)
    except Exception as e:
        return error_result(str(e))
