"""MCP tools for listing and inspecting Portal collections."""

import json
from urllib.parse import urlparse, urlunparse

from mcp.types import TextContent, Tool

from maeris_mcp.maeris.client import MaerisClient
from maeris_mcp.maeris.types import MaerisAPI


def list_collections_tool() -> Tool:
    """Return the tool definition for list_collections."""
    return Tool(
        name="list_collections",
        description=(
            "List all root-level API collections for the connected Maeris app. "
            "Uses the credentials from 'maeris login'. "
            "Returns an array of {id, name, created_at} objects."
        ),
        inputSchema={
            "type": "object",
            "properties": {},
            "required": [],
        },
    )


def get_collection_tool() -> Tool:
    """Return the tool definition for get_collection."""
    return Tool(
        name="get_collection",
        description=(
            "Get metadata and immediate children (sub-collections and APIs) for a single collection. "
            "Looks up the collection by name. "
            "Returns {collection, subCollections, apis}."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "name": {
                    "type": "string",
                    "description": "The name of the collection to retrieve.",
                },
            },
            "required": ["name"],
        },
    )


def list_subcollections_tool() -> Tool:
    """Return the tool definition for list_subcollections."""
    return Tool(
        name="list_subcollections",
        description=(
            "List the immediate sub-collections of a named collection. "
            "Does not include APIs — use get_collection for those. "
            "Returns an array of {id, name} objects."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "name": {
                    "type": "string",
                    "description": "The name of the parent collection.",
                },
            },
            "required": ["name"],
        },
    )


def search_collections_tool() -> Tool:
    """Return the tool definition for search_collections."""
    return Tool(
        name="search_collections",
        description=(
            "Search for collections whose name contains the given query string (case-insensitive). "
            "Searches across all depths of the collection hierarchy. "
            "Returns an array of {id, name, parentId} objects with where each match was found."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "query": {
                    "type": "string",
                    "description": "Substring to search for in collection names.",
                },
            },
            "required": ["query"],
        },
    )


def get_collection_tree_tool() -> Tool:
    """Return the tool definition for get_collection_tree."""
    return Tool(
        name="get_collection_tree",
        description=(
            "Recursively fetch the full collection hierarchy under a named root collection. "
            "Each node includes its sub-collections and APIs. "
            "Use the depth parameter to limit how many levels deep to traverse (default: 3)."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "name": {
                    "type": "string",
                    "description": "The name of the root collection to start from.",
                },
                "depth": {
                    "type": "integer",
                    "description": "Maximum levels to recurse. Default: 4.",
                    "default": 4,
                    "minimum": 1,
                    "maximum": 10,
                },
            },
            "required": ["name"],
        },
    )


def create_collection_tool() -> Tool:
    """Return the tool definition for create_collection."""
    return Tool(
        name="create_collection",
        description=(
            "Create a new API collection in Maeris. "
            "Optionally nest it under an existing collection by providing parent_name."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "name": {
                    "type": "string",
                    "description": "Name for the new collection.",
                },
                "parent_name": {
                    "type": "string",
                    "description": "Name of the parent collection to nest under. Omit to create a root-level collection.",
                },
            },
            "required": ["name"],
        },
    )


async def handle_create_collection(arguments: dict) -> list[TextContent]:
    """Handle create_collection tool call."""
    name = arguments.get("name")
    if not name:
        return [TextContent(type="text", text="Error: name is required")]

    parent_name = arguments.get("parent_name")
    parent_collection_id = ""

    async with MaerisClient() as client:
        if parent_name:
            parent = await _find_collection_by_name(client, parent_name)
            if not parent:
                return [TextContent(type="text", text=f"Error: no collection found with name '{parent_name}'")]
            parent_collection_id = parent["api_collection_id"]

        collection_id = await client.create_collection(name, parent_collection_id)

    result = {"id": collection_id, "name": name, "parentId": parent_collection_id or None}
    return [TextContent(type="text", text=json.dumps(result, indent=2))]


def rename_collection_tool() -> Tool:
    return Tool(
        name="rename_collection",
        description="Rename an existing collection. Looks up the collection by its current name.",
        inputSchema={
            "type": "object",
            "properties": {
                "name": {"type": "string", "description": "Current name of the collection to rename."},
                "new_name": {"type": "string", "description": "New name for the collection."},
            },
            "required": ["name", "new_name"],
        },
    )


def delete_collection_tool() -> Tool:
    return Tool(
        name="delete_collection",
        description="Delete a collection by name. This is irreversible.",
        inputSchema={
            "type": "object",
            "properties": {
                "name": {"type": "string", "description": "Name of the collection to delete."},
            },
            "required": ["name"],
        },
    )


async def handle_rename_collection(arguments: dict) -> list[TextContent]:
    name = arguments.get("name")
    new_name = arguments.get("new_name")
    if not name or not new_name:
        return [TextContent(type="text", text="Error: name and new_name are required")]
    async with MaerisClient() as client:
        match = await _find_collection_by_name(client, name)
        if not match:
            return [TextContent(type="text", text=f"Error: no collection found with name '{name}'")]
        parent_id = match["_parent_id"]
        await client.rename_collection(match["api_collection_id"], new_name)
        updated = await client.get_collection(match["api_collection_id"])
        if parent_id:
            children_map = await client.get_collection_children([parent_id])
            siblings = [
                {"id": s["api_collection_id"], "name": s["name"]}
                for s in children_map.get(parent_id, {}).get("api_collections", [])
            ]
        else:
            roots = await client.get_collections()
            siblings = [
                {"id": c["api_collection_id"], "name": c["name"]}
                for c in roots
            ]
    result = {
        "renamed": {"id": match["api_collection_id"], "oldName": name, "newName": new_name},
        "collection": {
            "id": updated["api_collection_id"],
            "name": updated["name"],
            "topLevel": updated.get("top_level"),
            "created_at": updated.get("created_at"),
        },
        "siblings": siblings,
    }
    return [TextContent(type="text", text=json.dumps(result, indent=2))]


async def handle_delete_collection(arguments: dict) -> list[TextContent]:
    name = arguments.get("name")
    if not name:
        return [TextContent(type="text", text="Error: name is required")]
    async with MaerisClient() as client:
        match = await _find_collection_by_name(client, name)
        if not match:
            return [TextContent(type="text", text=f"Error: no collection found with name '{name}'")]
        parent_id = match["_parent_id"]
        await client.delete_collection(match["api_collection_id"])
        if parent_id:
            children_map = await client.get_collection_children([parent_id])
            siblings = [
                {"id": s["api_collection_id"], "name": s["name"]}
                for s in children_map.get(parent_id, {}).get("api_collections", [])
            ]
        else:
            roots = await client.get_collections()
            siblings = [
                {"id": c["api_collection_id"], "name": c["name"]}
                for c in roots
            ]
    result = {
        "deleted": {"id": match["api_collection_id"], "name": name},
        "siblings": siblings,
    }
    return [TextContent(type="text", text=json.dumps(result, indent=2))]


async def _get_children(client: MaerisClient, collection_id: str) -> dict:
    """Fetch children for a single collection, returning the children payload."""
    children_map = await client.get_collection_children([collection_id])
    return children_map.get(collection_id, {})


async def _find_collection_by_path(client: MaerisClient, path: str) -> dict | None:
    """Find a collection by a `>` separated path, e.g. 'API > API'.

    The first segment is resolved via full BFS (same as _find_collection_by_name),
    then each subsequent segment is matched against the direct children of the
    previously found collection. Returns the matched collection dict with
    '_parent_id', or None if any segment is not found.
    """
    segments = [s.strip() for s in path.split(">")]

    # Use full BFS for the first segment so it works at any depth
    current = await _find_collection_by_name(client, segments[0])
    if current is None:
        return None

    parent_id: str | None = current.get("_parent_id")

    # Traverse remaining segments by checking direct children only
    for segment in segments[1:]:
        parent_id = current["api_collection_id"]
        children = await _get_children(client, parent_id)
        current = None
        for sub in children.get("api_collections", []):
            if sub["name"].lower() == segment.lower():
                current = {**sub, "_parent_id": parent_id}
                break
        if current is None:
            return None

    return current


async def _find_collection_by_name(client: MaerisClient, name: str) -> dict | None:
    """BFS across the full hierarchy to find a collection by exact name (case-insensitive).

    Fetches children one collection at a time to avoid unreliable batch endpoint behaviour.
    Returns the matched collection dict with an extra '_parent_id' key (None for root collections).
    """
    roots = await client.get_collections()
    queue: list[tuple[dict, str | None]] = [(c, None) for c in roots]

    while queue:
        col, parent_id = queue.pop(0)
        if col["name"].lower() == name.lower():
            return {**col, "_parent_id": parent_id}
        children = await _get_children(client, col["api_collection_id"])
        for sub in children.get("api_collections", []):
            queue.append((sub, col["api_collection_id"]))

    return None


async def handle_list_collections(arguments: dict) -> list[TextContent]:
    """Handle list_collections tool call."""
    async with MaerisClient() as client:
        collections = await client.get_collections()
    result = [
        {"id": c["api_collection_id"], "name": c["name"], "created_at": c.get("created_at")}
        for c in collections
    ]
    return [TextContent(type="text", text=json.dumps(result, indent=2))]


async def handle_get_collection(arguments: dict) -> list[TextContent]:
    """Handle get_collection tool call."""
    name = arguments.get("name")
    if not name:
        return [TextContent(type="text", text="Error: name is required")]
    async with MaerisClient() as client:
        match = await _find_collection_by_name(client, name)
        if not match:
            return [TextContent(type="text", text=f"Error: no collection found with name '{name}'")]
        collection_id = match["api_collection_id"]
        metadata = await client.get_collection(collection_id)
        children_map = await client.get_collection_children([collection_id])
    children = children_map.get(collection_id, {})
    result = {
        "collection": {
            "id": metadata["api_collection_id"],
            "name": metadata["name"],
            "appid": metadata.get("appid"),
            "topLevel": metadata.get("top_level"),
        },
        "subCollections": [
            {"id": s["api_collection_id"], "name": s["name"]}
            for s in children.get("api_collections", [])
        ],
        "apis": [
            {
                "id": a["api_id"],
                "name": a["name"],
                "method": a["method"].upper(),
                "url": a["url"],
            }
            for a in children.get("apis", [])
        ],
    }
    return [TextContent(type="text", text=json.dumps(result, indent=2))]


async def handle_list_subcollections(arguments: dict) -> list[TextContent]:
    """Handle list_subcollections tool call."""
    name = arguments.get("name")
    if not name:
        return [TextContent(type="text", text="Error: name is required")]
    async with MaerisClient() as client:
        match = await _find_collection_by_name(client, name)
        if not match:
            return [TextContent(type="text", text=f"Error: no collection found with name '{name}'")]
        collection_id = match["api_collection_id"]
        children_map = await client.get_collection_children([collection_id])
    children = children_map.get(collection_id, {})
    result = [
        {"id": s["api_collection_id"], "name": s["name"]}
        for s in children.get("api_collections", [])
    ]
    return [TextContent(type="text", text=json.dumps(result, indent=2))]


async def handle_search_collections(arguments: dict) -> list[TextContent]:
    """Handle search_collections tool call.

    Walks the full hierarchy breadth-first, collecting every collection whose
    name contains the query string. Stops expanding a branch only when it has
    no sub-collections left.
    """
    query = arguments.get("query")
    if not query:
        return [TextContent(type="text", text="Error: query is required")]

    query_lower = query.lower()
    matches: list[dict] = []

    async with MaerisClient() as client:
        roots = await client.get_collections()

        # BFS: queue holds (collection_dict, parent_dict | None)
        # Children are fetched one at a time to avoid unreliable batch endpoint behaviour.
        queue: list[tuple[dict, dict | None]] = [(c, None) for c in roots]

        while queue:
            col, parent = queue.pop(0)
            col_id = col["api_collection_id"]
            children = await _get_children(client, col_id)

            if query_lower in col["name"].lower():
                matches.append({
                    "id": col_id,
                    "name": col["name"],
                    "parentId": parent["api_collection_id"] if parent else None,
                    "parentName": parent["name"] if parent else None,
                    "apis": [
                        {
                            "id": a["api_id"],
                            "name": a["name"],
                            "method": a["method"].upper(),
                            "url": a["url"],
                        }
                        for a in children.get("apis", [])
                    ],
                })

            for sub in children.get("api_collections", []):
                queue.append((sub, col))

    return [TextContent(type="text", text=json.dumps(matches, indent=2))]


async def handle_get_collection_tree(arguments: dict) -> list[TextContent]:
    """Handle get_collection_tree tool call.

    Recursively builds a tree of collections up to `depth` levels deep.
    Each node: {id, name, apis: [...], subCollections: [<same shape>]}.
    """
    name = arguments.get("name")
    if not name:
        return [TextContent(type="text", text="Error: name is required")]
    max_depth = int(arguments.get("depth", 4))

    async with MaerisClient() as client:
        match = await _find_collection_by_name(client, name)
        if not match:
            return [TextContent(type="text", text=f"Error: no collection found with name '{name}'")]

        tree = await _build_tree(client, match, current_depth=1, max_depth=max_depth)

    return [TextContent(type="text", text=json.dumps(tree, indent=2))]


def copy_collection_tool() -> Tool:
    return Tool(
        name="copy_collection",
        description=(
            "Deep-copy a collection (including all sub-collections and APIs) under a new name. "
            "Optionally nest the copy inside a target parent collection."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "name": {"type": "string", "description": "Name of the collection to copy."},
                "new_name": {"type": "string", "description": "Name for the new copy."},
                "target_parent": {
                    "type": "string",
                    "description": "Name of the parent collection to place the copy under. Omit to create at root level.",
                },
            },
            "required": ["name", "new_name"],
        },
    )


def collection_stats_tool() -> Tool:
    return Tool(
        name="collection_stats",
        description=(
            "Get statistics for a collection: total APIs, breakdown by HTTP method, "
            "total sub-collections, and per-sub-collection direct API counts."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "name": {"type": "string", "description": "Name of the collection to analyse."},
            },
            "required": ["name"],
        },
    )


async def handle_copy_collection(arguments: dict) -> list[TextContent]:
    name = arguments.get("name")
    new_name = arguments.get("new_name")
    if not name or not new_name:
        return [TextContent(type="text", text="Error: name and new_name are required")]

    target_parent = arguments.get("target_parent")

    async with MaerisClient() as client:
        source = await _find_collection_by_name(client, name)
        if not source:
            return [TextContent(type="text", text=f"Error: no collection found with name '{name}'")]
        source_root_id = source["api_collection_id"]

        parent_id = ""
        if target_parent:
            parent_col = await _find_collection_by_name(client, target_parent)
            if not parent_col:
                return [TextContent(type="text", text=f"Error: no collection found with name '{target_parent}'")]
            parent_id = parent_col["api_collection_id"]

        copy_root_id = await client.create_collection(new_name, parent_id)

        # BFS: (source_col_id, copy_col_id)
        id_map: dict[str, str] = {source_root_id: copy_root_id}
        queue = [(source_root_id, copy_root_id)]
        apis_created = 0
        sub_collections_created = 0
        errors: list[str] = []

        while queue:
            src_id, copy_id = queue.pop(0)
            children = await _get_children(client, src_id)

            for sub in children.get("api_collections", []):
                try:
                    new_sub_id = await client.create_collection(sub["name"], copy_id)
                    sub_collections_created += 1
                    id_map[sub["api_collection_id"]] = new_sub_id
                    queue.append((sub["api_collection_id"], new_sub_id))
                except Exception as exc:
                    errors.append(f"Failed to copy sub-collection '{sub['name']}': {exc}")

            for api in children.get("apis", []):
                try:
                    detail = await client.get_api(api["api_id"])
                    api_data = detail.get("api", detail)
                    param_headers = detail.get("param_headers", [])

                    new_api = MaerisAPI(
                        name=api_data.get("name", api["name"]),
                        type=api_data.get("type") or api_data.get("method", "get"),
                        url=api_data.get("url", ""),
                        payload=api_data.get("payload", ""),
                        verification=api_data.get("verification", ""),
                        parent_collection_id=copy_id,
                    )
                    new_api_id = await client.create_api(new_api)

                    if param_headers:
                        copy_headers = [ph for ph in param_headers if (ph.get("type") or "").upper() == "HEADERS"]
                        copy_params = [ph for ph in param_headers if (ph.get("type") or "").upper() == "PARAMS"]
                        if copy_headers or copy_params:
                            h = [{"field_name": ph["field_name"], "field_value": ph.get("field_value", "")} for ph in copy_headers]
                            p = [{"field_name": ph["field_name"], "field_value": ph.get("field_value", "")} for ph in copy_params]
                            await client.add_param_header(new_api_id, h, p)
                    apis_created += 1
                except Exception as exc:
                    errors.append(f"Failed to copy API '{api.get('name')}': {exc}")

    result = {
        "original": {"id": source_root_id, "name": name},
        "copy": {"id": copy_root_id, "name": new_name},
        "apisCreated": apis_created,
        "subCollectionsCreated": sub_collections_created,
        "errors": errors,
    }
    return [TextContent(type="text", text=json.dumps(result, indent=2))]


async def handle_collection_stats(arguments: dict) -> list[TextContent]:
    name = arguments.get("name")
    if not name:
        return [TextContent(type="text", text="Error: name is required")]

    async with MaerisClient() as client:
        collection = await _find_collection_by_name(client, name)
        if not collection:
            return [TextContent(type="text", text=f"Error: no collection found with name '{name}'")]
        root_id = collection["api_collection_id"]

        total_apis = 0
        by_method: dict[str, int] = {}
        total_sub_collections = 0
        sub_collection_stats: list[dict] = []

        # Get direct children of root first to track per-sub stats
        root_children = await _get_children(client, root_id)

        # Count root-level APIs
        for api in root_children.get("apis", []):
            total_apis += 1
            method = api.get("method", "UNKNOWN").upper()
            by_method[method] = by_method.get(method, 0) + 1

        # BFS across sub-collections
        # queue: (col_id, col_name, is_direct_child_of_root)
        queue = [(sub["api_collection_id"], sub["name"], True) for sub in root_children.get("api_collections", [])]

        while queue:
            col_id, col_name, is_direct = queue.pop(0)
            total_sub_collections += 1
            children = await _get_children(client, col_id)

            direct_api_count = len(children.get("apis", []))
            for api in children.get("apis", []):
                total_apis += 1
                method = api.get("method", "UNKNOWN").upper()
                by_method[method] = by_method.get(method, 0) + 1

            if is_direct:
                sub_collection_stats.append({"name": col_name, "apiCount": direct_api_count})

            for sub in children.get("api_collections", []):
                queue.append((sub["api_collection_id"], sub["name"], False))

    result = {
        "collectionName": name,
        "totalApis": total_apis,
        "byMethod": by_method,
        "totalSubCollections": total_sub_collections,
        "subCollections": sub_collection_stats,
    }
    return [TextContent(type="text", text=json.dumps(result, indent=2))]


def export_collection_tool() -> Tool:
    """Return the tool definition for export_collection."""
    return Tool(
        name="export_collection",
        description=(
            "Export a Maeris collection (including all sub-collections, APIs, headers, and query params) "
            "as a Postman Collection v2.1 JSON document. "
            "Pass the result to import_collection or open it directly in Postman."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "name": {
                    "type": "string",
                    "description": "Name of the root collection to export.",
                },
            },
            "required": ["name"],
        },
    )


def import_collection_tool() -> Tool:
    """Return the tool definition for import_collection."""
    return Tool(
        name="import_collection",
        description=(
            "Import a Postman Collection v2.1 JSON file into Maeris. "
            "Recreates all folders (sub-collections) and requests (APIs) including headers and query params. "
            "Always creates new entries — no conflict checking. "
            "Works with exports from this tool or any real Postman export."
        ),
        inputSchema={
            "type": "object",
            "properties": {
                "file_path": {
                    "type": "string",
                    "description": "Absolute path to the Postman Collection v2.1 JSON file to import.",
                },
                "new_name": {
                    "type": "string",
                    "description": "Override the root collection name from the document.",
                },
                "target_parent": {
                    "type": "string",
                    "description": "Name of an existing collection to nest the import under. Omit to create at root level.",
                },
            },
            "required": ["file_path"],
        },
    )


def _to_postman_item(api_data: dict, param_headers: list) -> dict:
    """Convert a hydrated Maeris API into a Postman v2.1 request item."""
    raw_url = api_data.get("url", "")
    parsed = urlparse(raw_url)

    protocol = parsed.scheme or "https"
    host = parsed.hostname.split(".") if parsed.hostname else []
    path_parts = [p for p in (parsed.path or "").split("/") if p]

    query_params = [
        {"key": ph["field_name"], "value": ph.get("field_value", "")}
        for ph in param_headers
        if (ph.get("type") or "").upper() == "PARAMS"
    ]
    headers = [
        {"key": ph["field_name"], "value": ph.get("field_value", ""), "type": "text"}
        for ph in param_headers
        if (ph.get("type") or "").upper() == "HEADERS"
    ]

    # Build the raw URL with existing query string (or none)
    base_url = urlunparse((parsed.scheme, parsed.netloc, parsed.path, "", "", ""))
    if query_params:
        qs = "&".join(f"{q['key']}={q['value']}" for q in query_params)
        full_raw = f"{base_url}?{qs}"
    else:
        full_raw = raw_url

    payload = api_data.get("payload", "") or ""

    return {
        "name": api_data.get("name", ""),
        "request": {
            "method": (api_data.get("type") or api_data.get("method", "GET")).upper(),
            "header": headers,
            "body": {
                "mode": "raw",
                "raw": payload,
                "options": {"raw": {"language": "json"}},
            },
            "url": {
                "raw": full_raw,
                "protocol": protocol,
                "host": host,
                "path": path_parts,
                "query": query_params,
            },
        },
        "response": [],
    }


async def _export_folder(client: MaerisClient, col_id: str, col_name: str) -> dict:
    """Recursively build a Postman folder node for a Maeris collection."""
    children = await _get_children(client, col_id)
    items = []

    for api in children.get("apis", []):
        try:
            detail = await client.get_api(api["api_id"])
            api_data = detail.get("api", detail)
            ph = detail.get("param_headers", [])
            items.append(_to_postman_item(api_data, ph))
        except Exception as exc:
            items.append({"name": api.get("name", "unknown"), "_error": str(exc)})

    for sub in children.get("api_collections", []):
        items.append(await _export_folder(client, sub["api_collection_id"], sub["name"]))

    return {"name": col_name, "item": items}


async def handle_export_collection(arguments: dict) -> list[TextContent]:
    """Handle export_collection tool call."""
    name = arguments.get("name")
    if not name:
        return [TextContent(type="text", text="Error: name is required")]

    async with MaerisClient() as client:
        match = await _find_collection_by_name(client, name)
        if not match:
            return [TextContent(type="text", text=f"Error: no collection found with name '{name}'")]

        folder = await _export_folder(client, match["api_collection_id"], name)

    document = {
        "info": {
            "name": name,
            "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
        },
        "item": folder["item"],
    }
    return [TextContent(type="text", text=json.dumps(document, indent=2))]


async def _import_folder(
    client: MaerisClient, items: list, parent_col_id: str
) -> tuple[int, int, list[str]]:
    """Recursively create Maeris collections and APIs from a Postman item array."""
    apis_created = 0
    subs_created = 0
    errors: list[str] = []

    for item in items:
        if "item" in item:
            # Folder → sub-collection
            try:
                new_col_id = await client.create_collection(item["name"], parent_col_id)
                subs_created += 1
                a, s, e = await _import_folder(client, item["item"], new_col_id)
                apis_created += a
                subs_created += s
                errors.extend(e)
            except Exception as exc:
                errors.append(f"Failed to create sub-collection '{item.get('name')}': {exc}")
        elif "request" in item:
            # Request → API
            try:
                req = item["request"]
                method = req.get("method", "GET").lower()
                url_obj = req.get("url", {})
                raw_url = url_obj["raw"] if isinstance(url_obj, dict) else (url_obj or "")
                # Strip query string for the stored URL
                parsed = urlparse(raw_url)
                base_url = urlunparse((parsed.scheme, parsed.netloc, parsed.path, "", "", ""))

                payload = req.get("body", {}).get("raw", "") if req.get("body") else ""

                new_api = MaerisAPI(
                    name=item["name"],
                    type=method,
                    url=base_url,
                    payload=payload or "",
                    parent_collection_id=parent_col_id,
                )
                new_api_id = await client.create_api(new_api)

                # Build headers and params lists
                raw_headers = req.get("header", [])
                headers = [
                    {"field_name": h["key"], "field_value": h.get("value", "")}
                    for h in raw_headers
                    if not h.get("disabled")
                ]
                query_list = url_obj.get("query", []) if isinstance(url_obj, dict) else []
                params = [
                    {"field_name": q["key"], "field_value": q.get("value", "")}
                    for q in query_list
                    if not q.get("disabled")
                ]

                if headers or params:
                    await client.add_param_header(new_api_id, headers, params)
                apis_created += 1
            except Exception as exc:
                errors.append(f"Failed to import API '{item.get('name')}': {exc}")

    return apis_created, subs_created, errors


async def handle_import_collection(arguments: dict) -> list[TextContent]:
    """Handle import_collection tool call."""
    file_path = arguments.get("file_path")
    if not file_path:
        return [TextContent(type="text", text="Error: file_path is required")]

    try:
        with open(file_path, "r", encoding="utf-8") as f:
            data = json.load(f)
    except FileNotFoundError:
        return [TextContent(type="text", text=f"Error: file not found: {file_path}")]
    except json.JSONDecodeError as exc:
        return [TextContent(type="text", text=f"Error: invalid JSON in file: {exc}")]

    if not isinstance(data, dict):
        return [TextContent(type="text", text="Error: file must contain a Postman Collection v2.1 JSON object")]

    root_name = arguments.get("new_name") or data.get("info", {}).get("name")
    if not root_name:
        return [TextContent(type="text", text="Error: could not determine collection name; provide new_name or ensure data.info.name is set")]

    target_parent = arguments.get("target_parent")

    async with MaerisClient() as client:
        parent_id = ""
        if target_parent:
            parent_col = await _find_collection_by_name(client, target_parent)
            if not parent_col:
                return [TextContent(type="text", text=f"Error: no collection found with name '{target_parent}'")]
            parent_id = parent_col["api_collection_id"]

        root_col_id = await client.create_collection(root_name, parent_id)
        apis_created, subs_created, errors = await _import_folder(
            client, data.get("item", []), root_col_id
        )

    result = {
        "imported": root_name,
        "rootCollectionId": root_col_id,
        "apisCreated": apis_created,
        "subCollectionsCreated": subs_created,
        "errors": errors,
    }
    return [TextContent(type="text", text=json.dumps(result, indent=2))]


async def _build_tree(client: MaerisClient, col: dict, current_depth: int, max_depth: int) -> dict:
    """Recursively build a collection tree node."""
    col_id = col["api_collection_id"]
    children_map = await client.get_collection_children([col_id])
    children = children_map.get(col_id, {})

    apis = [
        {
            "id": a["api_id"],
            "name": a["name"],
            "method": a["method"].upper(),
            "url": a["url"],
        }
        for a in children.get("apis", [])
    ]

    sub_collections = children.get("api_collections", [])

    if current_depth >= max_depth or not sub_collections:
        return {
            "id": col_id,
            "name": col["name"],
            "apis": apis,
            "subCollections": [
                {"id": s["api_collection_id"], "name": s["name"]}
                for s in sub_collections
            ],
        }

    return {
        "id": col_id,
        "name": col["name"],
        "apis": apis,
        "subCollections": [
            await _build_tree(client, s, current_depth + 1, max_depth)
            for s in sub_collections
        ],
    }
