"""Products Handler - manages WooCommerce products and related entities"""

import asyncio
import json
import re
from typing import Any

from plugins.wordpress.client import WordPressClient


def _count_words(html_content: str) -> int:
    """Strip HTML tags and count words."""
    text = re.sub(r"<[^>]+>", " ", html_content)
    text = re.sub(r"\s+", " ", text).strip()
    return len(text.split()) if text else 0


def _strip_html(html_content: str, max_chars: int = 500) -> str:
    """Strip HTML tags and return first max_chars characters."""
    text = re.sub(r"<[^>]+>", " ", html_content)
    text = re.sub(r"\s+", " ", text).strip()
    if len(text) > max_chars:
        return text[:max_chars] + "..."
    return text


def normalize_id_list(value: Any, field_name: str = "item") -> list[dict[str, Any]]:
    """
    Convert various formats of category/tag IDs to WooCommerce API format.

    Phase K.2.1: Support multiple input formats for better UX
    Phase K.2.2: Also support name-based format for tags

    Supported formats:
        - 62 → [{"id": 62}]
        - "62" → [{"id": 62}]
        - [62, 63] → [{"id": 62}, {"id": 63}]
        - "62,63" → [{"id": 62}, {"id": 63}]
        - [{"id": 62}] → [{"id": 62}] (no change)
        - [{"name": "Tag Name"}] → [{"name": "Tag Name"}] (for tags - WooCommerce creates if not exists)
        - "Tag1, Tag2" (non-numeric) → [{"name": "Tag1"}, {"name": "Tag2"}]

    Args:
        value: Input value in any supported format
        field_name: Name of field for error messages

    Returns:
        List of dicts in WooCommerce format: [{"id": int}, ...] or [{"name": str}, ...]
    """
    if value is None:
        return []

    result = []

    # Case 1: Already in correct format [{"id": x}] or [{"name": x}]
    if isinstance(value, list):
        for item in value:
            if isinstance(item, dict):
                if "id" in item:
                    # ID format - convert to int
                    result.append({"id": int(item["id"])})
                elif "name" in item:
                    # Name format - keep as string (WooCommerce will create/find tag)
                    result.append({"name": str(item["name"])})
            elif isinstance(item, (int, float)):
                # List of integers
                result.append({"id": int(item)})
            elif isinstance(item, str):
                item_stripped = item.strip()
                if item_stripped.isdigit():
                    # List of string integers
                    result.append({"id": int(item_stripped)})
                elif item_stripped:
                    # List of string names (for tags)
                    result.append({"name": item_stripped})
        return result

    # Case 2: Single integer
    if isinstance(value, (int, float)):
        return [{"id": int(value)}]

    # Case 3: String (could be "62" or "62,63" or "Tag1, Tag2")
    if isinstance(value, str):
        value = value.strip()
        if not value:
            return []
        # Handle comma-separated
        if "," in value:
            for part in value.split(","):
                part = part.strip()
                if part.isdigit():
                    result.append({"id": int(part)})
                elif part:
                    # Non-numeric - treat as name
                    result.append({"name": part})
            return result
        # Single value
        if value.isdigit():
            return [{"id": int(value)}]
        else:
            # Non-numeric single value - treat as name
            return [{"name": value}]

    return result


def get_tool_specifications() -> list[dict[str, Any]]:
    """Return tool specifications for ToolGenerator"""
    return [
        # === PRODUCTS ===
        {
            "name": "list_products",
            "method_name": "list_products",
            "description": "List WooCommerce products. Returns paginated list with pricing, stock status, and categories. Supports filtering by category, stock status, and search.",
            "schema": {
                "type": "object",
                "properties": {
                    "per_page": {
                        "type": "integer",
                        "description": "Number of products per page (1-100)",
                        "default": 10,
                        "minimum": 1,
                        "maximum": 100,
                    },
                    "page": {
                        "type": "integer",
                        "description": "Page number",
                        "default": 1,
                        "minimum": 1,
                    },
                    "status": {
                        "type": "string",
                        "description": "Filter by product status. Use 'publish' to see only live products with prices. Default 'any' includes drafts.",
                        "enum": ["draft", "pending", "private", "publish", "any"],
                        "default": "any",
                    },
                    "category": {
                        "anyOf": [{"type": "integer"}, {"type": "null"}],
                        "description": "Filter by category ID",
                    },
                    "stock_status": {
                        "anyOf": [
                            {"type": "string", "enum": ["instock", "outofstock", "onbackorder"]},
                            {"type": "null"},
                        ],
                        "description": "Filter by stock status (optional)",
                    },
                    "search": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Search term to filter products",
                    },
                    "search_terms": {
                        "anyOf": [{"type": "array", "items": {"type": "string"}}, {"type": "null"}],
                        "description": "Multiple search terms to search in parallel. Results are deduplicated. Overrides 'search' if both provided.",
                    },
                    "include_content": {
                        "type": "boolean",
                        "description": "Include description summary (first 500 chars) and word count in results. Default false to save tokens.",
                        "default": False,
                    },
                },
            },
            "scope": "read",
        },
        {
            "name": "get_product",
            "method_name": "get_product",
            "description": "Get detailed information about a specific WooCommerce product by ID. Returns complete product data including pricing, inventory, images, categories, tags, and attributes.",
            "schema": {
                "type": "object",
                "properties": {
                    "product_id": {
                        "type": "integer",
                        "description": "Product ID to retrieve",
                        "minimum": 1,
                    },
                    "fields": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Comma-separated list of fields to return (e.g., 'id,name,price,status'). Returns all fields if not specified. Use to reduce response size and token usage.",
                    },
                },
                "required": ["product_id"],
            },
            "scope": "read",
        },
        {
            "name": "create_product",
            "method_name": "create_product",
            "description": "Create a new WooCommerce product. Supports simple and variable products with pricing, inventory, categories, tags, and descriptions.",
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string", "description": "Product name/title", "minLength": 1},
                    "type": {
                        "type": "string",
                        "description": "Product type",
                        "enum": ["simple", "grouped", "external", "variable"],
                        "default": "simple",
                    },
                    "regular_price": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Product regular price (e.g., '19.99')",
                    },
                    "sale_price": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Product sale price (e.g., '14.99')",
                    },
                    "description": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Product full description (HTML allowed)",
                    },
                    "short_description": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Product short description/summary",
                    },
                    "status": {
                        "type": "string",
                        "description": "Product status",
                        "enum": ["draft", "pending", "private", "publish"],
                        "default": "draft",
                    },
                    "categories": {
                        "anyOf": [
                            {"type": "array", "items": {"type": "integer"}},
                            {"type": "null"},
                        ],
                        "description": "Category IDs to assign to product",
                    },
                    "tags": {
                        "anyOf": [
                            {"type": "array", "items": {"type": "integer"}},
                            {"type": "null"},
                        ],
                        "description": "Tag IDs to assign to product",
                    },
                    "stock_quantity": {
                        "anyOf": [{"type": "integer"}, {"type": "null"}],
                        "description": "Stock quantity (requires manage_stock to be true)",
                    },
                    "manage_stock": {
                        "type": "boolean",
                        "description": "Enable stock management",
                        "default": False,
                    },
                    "stock_status": {
                        "type": "string",
                        "description": "Stock status",
                        "enum": ["instock", "outofstock", "onbackorder"],
                        "default": "instock",
                    },
                    "attributes": {
                        "anyOf": [
                            {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "id": {
                                            "type": "integer",
                                            "minimum": 1,
                                            "description": (
                                                "Optional. Pass the global attribute "
                                                "id from list_product_attributes to "
                                                "link this product to an existing "
                                                "global attribute (e.g. pa_color). "
                                                "Omit (or set 0) to create an inline "
                                                "custom attribute on this product only."
                                            ),
                                        },
                                        "name": {"type": "string"},
                                        "options": {"type": "array", "items": {"type": "string"}},
                                        "visible": {"type": "boolean"},
                                        "variation": {"type": "boolean"},
                                    },
                                },
                            },
                            {"type": "null"},
                        ],
                        "description": (
                            "Product attributes for variable products. "
                            'Custom (per-product): [{"name": "Color", "options": ["Red", "Blue"], "variation": true}]. '
                            'Global (linked, recommended): [{"id": 1, "options": ["Red", "Blue"], "variation": true}] — '
                            "use list_product_attributes to find existing ids."
                        ),
                    },
                },
                "required": ["name"],
            },
            "scope": "write",
        },
        {
            "name": "update_product",
            "method_name": "update_product",
            "description": "Update an existing WooCommerce product. Can update any field including name, slug (permalink), pricing, inventory, status, categories, tags, and more.",
            "schema": {
                "type": "object",
                "properties": {
                    "product_id": {
                        "type": "integer",
                        "description": "Product ID to update",
                        "minimum": 1,
                    },
                    "name": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Product name/title",
                    },
                    "slug": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Product slug (SEO-friendly URL path, e.g., 'my-product')",
                    },
                    "regular_price": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Product regular price",
                    },
                    "sale_price": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Product sale price",
                    },
                    "description": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Product full description",
                    },
                    "short_description": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Product short description",
                    },
                    "status": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Product status",
                        "enum": ["draft", "pending", "private", "publish"],
                    },
                    "categories": {
                        "anyOf": [
                            {"type": "array", "items": {"type": "integer"}},
                            {"type": "null"},
                        ],
                        "description": "Category IDs to assign to product",
                    },
                    "tags": {
                        "anyOf": [
                            {"type": "array", "items": {"type": "integer"}},
                            {"type": "null"},
                        ],
                        "description": "Tag IDs to assign to product",
                    },
                    "stock_quantity": {
                        "anyOf": [{"type": "integer"}, {"type": "null"}],
                        "description": "Stock quantity",
                    },
                    "stock_status": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Stock status",
                        "enum": ["instock", "outofstock", "onbackorder"],
                    },
                    "featured": {
                        "anyOf": [{"type": "boolean"}, {"type": "null"}],
                        "description": "Featured product flag",
                    },
                    "weight": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Product weight",
                    },
                },
                "required": ["product_id"],
            },
            "scope": "write",
        },
        {
            "name": "delete_product",
            "method_name": "delete_product",
            "description": "Delete or trash a WooCommerce product. Can permanently delete or move to trash for later restoration.",
            "schema": {
                "type": "object",
                "properties": {
                    "product_id": {
                        "type": "integer",
                        "description": "Product ID to delete",
                        "minimum": 1,
                    },
                    "force": {
                        "type": "boolean",
                        "description": "Permanently delete (true) or move to trash (false)",
                        "default": False,
                    },
                },
                "required": ["product_id"],
            },
            "scope": "write",
        },
        # === PRODUCT CATEGORIES ===
        {
            "name": "list_product_categories",
            "method_name": "list_product_categories",
            "description": "List WooCommerce product categories. Returns hierarchical category structure with product counts and parent relationships.",
            "schema": {
                "type": "object",
                "properties": {
                    "per_page": {
                        "type": "integer",
                        "description": "Number of categories per page (1-100)",
                        "default": 10,
                        "minimum": 1,
                        "maximum": 100,
                    },
                    "page": {
                        "type": "integer",
                        "description": "Page number",
                        "default": 1,
                        "minimum": 1,
                    },
                    "hide_empty": {
                        "type": "boolean",
                        "description": "Hide categories with no products",
                        "default": False,
                    },
                },
            },
            "scope": "read",
        },
        {
            "name": "create_product_category",
            "method_name": "create_product_category",
            "description": "Create a new WooCommerce product category. Supports hierarchical categories with parent-child relationships.",
            "schema": {
                "type": "object",
                "properties": {
                    "name": {"type": "string", "description": "Category name", "minLength": 1},
                    "description": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Category description",
                    },
                    "parent": {
                        "anyOf": [{"type": "integer"}, {"type": "null"}],
                        "description": "Parent category ID for hierarchical structure",
                    },
                },
                "required": ["name"],
            },
            "scope": "write",
        },
        # === PRODUCT TAGS ===
        {
            "name": "list_product_tags",
            "method_name": "list_product_tags",
            "description": "List WooCommerce product tags. Returns all product tags with usage counts.",
            "schema": {
                "type": "object",
                "properties": {
                    "per_page": {
                        "type": "integer",
                        "description": "Number of tags per page (1-100)",
                        "default": 10,
                        "minimum": 1,
                        "maximum": 100,
                    },
                    "page": {
                        "type": "integer",
                        "description": "Page number",
                        "default": 1,
                        "minimum": 1,
                    },
                    "hide_empty": {
                        "type": "boolean",
                        "description": "Hide tags with no products",
                        "default": False,
                    },
                },
            },
            "scope": "read",
        },
        # === PRODUCT ATTRIBUTES ===
        {
            "name": "list_product_attributes",
            "method_name": "list_product_attributes",
            "description": "List all global WooCommerce product attributes. Attributes are used for product variations (e.g., Size, Color).",
            "schema": {"type": "object", "properties": {}},
            "scope": "read",
        },
        {
            "name": "create_product_attribute",
            "method_name": "create_product_attribute",
            "description": "Create a new global product attribute for use in variable products. Attributes define variation options like Size or Color.",
            "schema": {
                "type": "object",
                "properties": {
                    "name": {
                        "type": "string",
                        "description": "Attribute name (e.g., 'Size', 'Color')",
                        "minLength": 1,
                    },
                    "slug": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Attribute slug (auto-generated if not provided)",
                    },
                    "type": {
                        "type": "string",
                        "description": "Attribute type",
                        "enum": ["select", "text"],
                        "default": "select",
                    },
                    "order_by": {
                        "type": "string",
                        "description": "Default sort order",
                        "enum": ["menu_order", "name", "name_num", "id"],
                        "default": "menu_order",
                    },
                    "has_archives": {
                        "type": "boolean",
                        "description": "Enable archives for this attribute",
                        "default": False,
                    },
                },
                "required": ["name"],
            },
            "scope": "write",
        },
        # === PRODUCT VARIATIONS ===
        {
            "name": "list_product_variations",
            "method_name": "list_product_variations",
            "description": "List all variations of a variable product. Returns pricing, stock, and attribute combinations for each variation.",
            "schema": {
                "type": "object",
                "properties": {
                    "product_id": {
                        "type": "integer",
                        "description": "Variable product ID",
                        "minimum": 1,
                    },
                    "per_page": {
                        "type": "integer",
                        "description": "Number of variations per page (1-100)",
                        "default": 10,
                        "minimum": 1,
                        "maximum": 100,
                    },
                    "page": {
                        "type": "integer",
                        "description": "Page number",
                        "default": 1,
                        "minimum": 1,
                    },
                },
                "required": ["product_id"],
            },
            "scope": "read",
        },
        {
            "name": "create_product_variation",
            "method_name": "create_product_variation",
            "description": "Create a new variation for a variable product. Defines a specific combination of attributes with its own pricing and inventory.",
            "schema": {
                "type": "object",
                "properties": {
                    "product_id": {
                        "type": "integer",
                        "description": "Parent variable product ID",
                        "minimum": 1,
                    },
                    "attributes": {
                        "type": "array",
                        "description": 'Attribute combinations for this variation (e.g., [{"name": "Size", "option": "Large"}])',
                        "items": {
                            "type": "object",
                            "properties": {
                                "name": {"type": "string"},
                                "option": {"type": "string"},
                            },
                        },
                    },
                    "regular_price": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Variation regular price",
                    },
                    "sale_price": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Variation sale price",
                    },
                    "stock_quantity": {
                        "anyOf": [{"type": "integer"}, {"type": "null"}],
                        "description": "Stock quantity for this variation",
                    },
                    "stock_status": {
                        "type": "string",
                        "description": "Stock status",
                        "enum": ["instock", "outofstock", "onbackorder"],
                        "default": "instock",
                    },
                    "manage_stock": {
                        "type": "boolean",
                        "description": "Enable stock management for this variation",
                        "default": False,
                    },
                    "sku": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Stock Keeping Unit (SKU) for this variation",
                    },
                    "description": {
                        "anyOf": [{"type": "string"}, {"type": "null"}],
                        "description": "Variation description",
                    },
                    "image": {
                        "anyOf": [{"type": "object"}, {"type": "null"}],
                        "description": 'Variation image (e.g., {"id": 123})',
                    },
                },
                "required": ["product_id", "attributes"],
            },
            "scope": "write",
        },
    ]


class ProductsHandler:
    """Handle WooCommerce product-related operations"""

    def __init__(self, client: WordPressClient):
        """
        Initialize products handler.

        Args:
            client: WordPress API client instance
        """
        self.client = client

    # === PRODUCTS ===

    async def list_products(
        self,
        per_page: int = 10,
        page: int = 1,
        status: str = "any",
        category: int | None = None,
        stock_status: str | None = None,
        search: str | None = None,
        search_terms: list[str] | None = None,
        include_content: bool = False,
    ) -> str:
        """
        List WooCommerce products.

        Args:
            per_page: Number of products per page (1-100)
            page: Page number
            status: Product status filter
            category: Filter by category ID
            stock_status: Filter by stock status (instock, outofstock, onbackorder)
            search: Search term to filter products
            search_terms: Multiple search terms for parallel search with deduplication
            include_content: Include description summary and word count in results

        Returns:
            JSON string with products list
        """
        try:
            # Build query parameters
            params = {"per_page": per_page, "page": page, "status": status}

            # Add optional filters
            if category is not None:
                params["category"] = category
            if stock_status:
                params["stock_status"] = stock_status

            # Multi-search: parallel API calls with deduplication
            if search_terms and len(search_terms) > 0:

                async def _search_single(term: str) -> list:
                    p = {**params, "search": term}
                    return await self.client.get("products", params=p, use_woocommerce=True)

                batches = await asyncio.gather(
                    *[_search_single(term) for term in search_terms], return_exceptions=True
                )
                seen_ids: set = set()
                products: list = []
                for batch in batches:
                    if isinstance(batch, Exception):
                        continue
                    for product in batch:
                        if product["id"] not in seen_ids:
                            seen_ids.add(product["id"])
                            products.append(product)
            else:
                if search:
                    params["search"] = search
                products = await self.client.get("products", params=params, use_woocommerce=True)

            # Format response
            def _format_product(p: dict) -> dict:
                item = {
                    "id": p["id"],
                    "name": p["name"],
                    "slug": p["slug"],
                    "type": p["type"],
                    "status": p["status"],
                    "price": p["price"],
                    "regular_price": p["regular_price"],
                    "sale_price": p.get("sale_price", ""),
                    "stock_status": p["stock_status"],
                    "stock_quantity": p.get("stock_quantity"),
                    "categories": [
                        {"id": cat["id"], "name": cat["name"]} for cat in p.get("categories", [])
                    ],
                    "images": [
                        {"id": img["id"], "src": img["src"], "alt": img.get("alt", "")}
                        for img in p.get("images", [])[:1]  # Just first image
                    ],
                    "permalink": p["permalink"],
                }
                if include_content:
                    desc_html = p.get("description", "")
                    item["content_summary"] = _strip_html(desc_html, 500)
                    item["word_count"] = _count_words(desc_html)
                return item

            result = {
                "total": len(products),
                "page": page,
                "per_page": per_page,
                "products": [_format_product(p) for p in products],
            }

            return json.dumps(result, indent=2)
        except Exception as e:
            return json.dumps(
                {"error": str(e), "message": f"Failed to list products: {str(e)}"}, indent=2
            )

    async def get_product(self, product_id: int, fields: str | None = None) -> str:
        """
        Get detailed information about a specific product.

        Args:
            product_id: Product ID to retrieve
            fields: Comma-separated list of fields to return (e.g., 'id,name,price,status')

        Returns:
            JSON string with product data
        """
        try:
            product = await self.client.get(f"products/{product_id}", use_woocommerce=True)

            full_result = {
                "id": product["id"],
                "name": product["name"],
                "slug": product["slug"],
                "type": product["type"],
                "status": product["status"],
                "description": product.get("description", ""),
                "short_description": product.get("short_description", ""),
                "price": product["price"],
                "regular_price": product["regular_price"],
                "sale_price": product.get("sale_price", ""),
                "stock_status": product["stock_status"],
                "stock_quantity": product.get("stock_quantity"),
                "manage_stock": product.get("manage_stock", False),
                "categories": [
                    {"id": cat["id"], "name": cat["name"], "slug": cat["slug"]}
                    for cat in product.get("categories", [])
                ],
                "tags": [
                    {"id": tag["id"], "name": tag["name"], "slug": tag["slug"]}
                    for tag in product.get("tags", [])
                ],
                "images": [
                    {"id": img["id"], "src": img["src"], "alt": img.get("alt", "")}
                    for img in product.get("images", [])
                ],
                "permalink": product["permalink"],
                # Phase K.2.3: Include attributes for variable products
                "attributes": [
                    {
                        "id": attr.get("id"),
                        "name": attr.get("name"),
                        "slug": attr.get("slug"),
                        "position": attr.get("position"),
                        "visible": attr.get("visible"),
                        "variation": attr.get("variation"),
                        "options": attr.get("options", []),
                    }
                    for attr in product.get("attributes", [])
                ],
                "word_count": _count_words(product.get("description", "")),
            }

            # Filter to requested fields only
            if fields:
                requested = {f.strip().lower() for f in fields.split(",")}
                requested.add("id")  # Always include id
                result = {k: v for k, v in full_result.items() if k in requested}
            else:
                result = full_result

            return json.dumps(result, indent=2)
        except Exception as e:
            return json.dumps(
                {"error": str(e), "message": f"Failed to get product {product_id}: {str(e)}"},
                indent=2,
            )

    async def create_product(
        self,
        name: str,
        type: str = "simple",
        regular_price: str | None = None,
        sale_price: str | None = None,
        description: str | None = None,
        short_description: str | None = None,
        status: str = "draft",
        categories: list[int] | None = None,
        tags: list[int] | None = None,
        stock_quantity: int | None = None,
        manage_stock: bool = False,
        stock_status: str = "instock",
        attributes: list[dict[str, Any]] | None = None,
    ) -> str:
        """
        Create a new WooCommerce product.

        Args:
            name: Product name/title
            type: Product type (simple, grouped, external, variable)
            regular_price: Product regular price
            sale_price: Product sale price
            description: Product full description
            short_description: Product short description
            status: Product status
            categories: Category IDs to assign
            tags: Tag IDs to assign
            stock_quantity: Stock quantity
            manage_stock: Enable stock management
            stock_status: Stock status
            attributes: Product attributes for variable products

        Returns:
            JSON string with created product data
        """
        try:
            # Build product data
            data = {"name": name, "type": type, "status": status}

            # Phase K.2.2: Variable products have different stock handling
            # Stock comes from variations, not the parent product
            if type != "variable":
                data["stock_status"] = stock_status
                data["manage_stock"] = manage_stock
                if regular_price:
                    data["regular_price"] = regular_price
                if sale_price:
                    data["sale_price"] = sale_price
                if stock_quantity is not None and manage_stock:
                    data["stock_quantity"] = stock_quantity

            if description:
                data["description"] = description
            if short_description:
                data["short_description"] = short_description
            # Phase K.2.1: Use normalize_id_list for flexible format support
            if categories:
                normalized_cats = normalize_id_list(categories, "categories")
                if normalized_cats:
                    data["categories"] = normalized_cats
            if tags:
                normalized_tags = normalize_id_list(tags, "tags")
                if normalized_tags:
                    data["tags"] = normalized_tags
            # Phase K.2.1/K.2.2/K.2.3: Add attributes for variable products
            # WooCommerce requires proper attribute format:
            # - For global attributes: use "id" (integer) - this is preferred
            # - For custom attributes: use "name" (string)
            # - Never use both "id" and "name" together
            # - "options" must be an array of strings
            # - For variable products: "variation" must be true
            if attributes:
                processed_attrs = []
                for attr in attributes:
                    if isinstance(attr, dict):
                        attr_clean = {}
                        # Use id for global attributes, name for custom
                        if "id" in attr:
                            attr_clean["id"] = int(attr["id"])
                        elif "name" in attr:
                            attr_clean["name"] = str(attr["name"])
                        else:
                            continue  # Skip invalid attributes

                        # Ensure options is a list of strings
                        if "options" in attr:
                            opts = attr["options"]
                            if isinstance(opts, list):
                                attr_clean["options"] = [str(o) for o in opts]
                            elif isinstance(opts, str):
                                attr_clean["options"] = [opts]

                        # For variable products, always set variation=true
                        if type == "variable":
                            attr_clean["variation"] = True
                            attr_clean["visible"] = True
                        else:
                            if "variation" in attr:
                                attr_clean["variation"] = bool(attr["variation"])
                            if "visible" in attr:
                                attr_clean["visible"] = bool(attr["visible"])

                        processed_attrs.append(attr_clean)
                    else:
                        # String attribute name - create as custom attribute
                        processed_attrs.append(
                            {
                                "name": str(attr),
                                "variation": type == "variable",
                                "visible": True,
                            }
                        )

                if processed_attrs:
                    data["attributes"] = processed_attrs

            product = await self.client.post("products", json_data=data, use_woocommerce=True)

            # Phase K.2.4: Two-step approach for variable products
            # WooCommerce sometimes converts variable to simple on creation
            # If this happens, immediately update to set type=variable
            if type == "variable" and product["type"] != "variable":
                # Try to update the product type to variable
                update_data = {"type": "variable"}
                try:
                    product = await self.client.put(
                        f"products/{product['id']}", json_data=update_data, use_woocommerce=True
                    )
                except Exception:
                    pass  # If update fails, continue with original product

            result = {
                "id": product["id"],
                "name": product["name"],
                "type": product["type"],
                "status": product["status"],
                "price": product.get("price", ""),
                "permalink": product["permalink"],
                "message": f"Product '{name}' created successfully with ID {product['id']}",
            }

            # Phase K.2.2: Include attributes in response for variable products
            if type == "variable":
                result["attributes"] = product.get("attributes", [])
                # Warn if type still couldn't be set to variable
                if product["type"] != "variable":
                    result["warning"] = (
                        f"Product was created as '{product['type']}' instead of 'variable'. "
                        "This may happen if attributes are missing or have invalid format. "
                        "Ensure attributes have 'id' (global attribute ID) and 'options' array."
                    )

            return json.dumps(result, indent=2)
        except Exception as e:
            return json.dumps(
                {"error": str(e), "message": f"Failed to create product: {str(e)}"}, indent=2
            )

    async def update_product(
        self,
        product_id: int,
        name: str | None = None,
        slug: str | None = None,
        regular_price: str | None = None,
        sale_price: str | None = None,
        description: str | None = None,
        short_description: str | None = None,
        status: str | None = None,
        categories: list[int] | None = None,
        tags: list[int] | None = None,
        stock_quantity: int | None = None,
        stock_status: str | None = None,
        featured: bool | None = None,
        weight: str | None = None,
    ) -> str:
        """
        Update an existing WooCommerce product.

        Args:
            product_id: Product ID to update
            name: Product name
            slug: Product slug (SEO-friendly URL path)
            regular_price: Product regular price
            sale_price: Product sale price
            description: Product description
            short_description: Product short description
            status: Product status
            categories: Category IDs to assign
            tags: Tag IDs to assign
            stock_quantity: Stock quantity
            stock_status: Stock status
            featured: Featured product flag
            weight: Product weight

        Returns:
            JSON string with updated product data
        """
        try:
            # Build data dict with only provided values
            data = {}
            if name is not None:
                data["name"] = name
            if slug is not None:
                data["slug"] = slug
            if regular_price is not None:
                data["regular_price"] = regular_price
            if sale_price is not None:
                data["sale_price"] = sale_price
            if description is not None:
                data["description"] = description
            if short_description is not None:
                data["short_description"] = short_description
            if status is not None:
                data["status"] = status
            # Phase K.2.1: Use normalize_id_list for flexible format support
            if categories is not None:
                normalized_cats = normalize_id_list(categories, "categories")
                if normalized_cats:
                    data["categories"] = normalized_cats
            if tags is not None:
                normalized_tags = normalize_id_list(tags, "tags")
                if normalized_tags:
                    data["tags"] = normalized_tags
            if stock_quantity is not None:
                data["stock_quantity"] = stock_quantity
            if stock_status is not None:
                data["stock_status"] = stock_status
            if featured is not None:
                data["featured"] = featured
            if weight is not None:
                data["weight"] = weight

            product = await self.client.put(
                f"products/{product_id}", json_data=data, use_woocommerce=True
            )

            result = {
                "id": product["id"],
                "name": product["name"],
                "slug": product.get("slug", ""),
                "status": product["status"],
                "price": product.get("price", ""),
                "permalink": product.get("permalink", ""),
                "message": f"Product {product_id} updated successfully",
            }

            return json.dumps(result, indent=2)
        except Exception as e:
            return json.dumps(
                {"error": str(e), "message": f"Failed to update product {product_id}: {str(e)}"},
                indent=2,
            )

    async def delete_product(self, product_id: int, force: bool = False) -> str:
        """
        Delete or trash a WooCommerce product.

        Args:
            product_id: Product ID to delete
            force: Permanently delete (True) or move to trash (False)

        Returns:
            JSON string with deletion result
        """
        try:
            params = {"force": "true" if force else "false"}
            result = await self.client.delete(
                f"products/{product_id}", params=params, use_woocommerce=True
            )

            message = f"Product {product_id} {'permanently deleted' if force else 'moved to trash'}"
            return json.dumps({"success": True, "message": message, "result": result}, indent=2)
        except Exception as e:
            return json.dumps(
                {"error": str(e), "message": f"Failed to delete product {product_id}: {str(e)}"},
                indent=2,
            )

    # === PRODUCT CATEGORIES ===

    async def list_product_categories(
        self, per_page: int = 10, page: int = 1, hide_empty: bool = False
    ) -> str:
        """
        List WooCommerce product categories.

        Args:
            per_page: Number of categories per page (1-100)
            page: Page number
            hide_empty: Hide categories with no products

        Returns:
            JSON string with categories list
        """
        try:
            params = {
                "per_page": per_page,
                "page": page,
                "hide_empty": "true" if hide_empty else "false",
            }

            categories = await self.client.get(
                "products/categories", params=params, use_woocommerce=True
            )

            result = {
                "total": len(categories),
                "page": page,
                "categories": [
                    {
                        "id": cat["id"],
                        "name": cat["name"],
                        "slug": cat["slug"],
                        "description": cat.get("description", ""),
                        "count": cat.get("count", 0),
                        "parent": cat.get("parent", 0),
                    }
                    for cat in categories
                ],
            }

            return json.dumps(result, indent=2)
        except Exception as e:
            return json.dumps(
                {"error": str(e), "message": f"Failed to list product categories: {str(e)}"},
                indent=2,
            )

    async def create_product_category(
        self, name: str, description: str | None = None, parent: int | None = None
    ) -> str:
        """
        Create a new WooCommerce product category.

        Args:
            name: Category name
            description: Category description
            parent: Parent category ID for hierarchical structure

        Returns:
            JSON string with created category data
        """
        try:
            data = {"name": name}
            if description:
                data["description"] = description
            if parent:
                data["parent"] = parent

            category = await self.client.post(
                "products/categories", json_data=data, use_woocommerce=True
            )

            result = {
                "id": category["id"],
                "name": category["name"],
                "slug": category["slug"],
                "message": f"Product category '{name}' created successfully with ID {category['id']}",
            }

            return json.dumps(result, indent=2)
        except Exception as e:
            return json.dumps(
                {"error": str(e), "message": f"Failed to create product category: {str(e)}"},
                indent=2,
            )

    # === PRODUCT TAGS ===

    async def list_product_tags(
        self, per_page: int = 10, page: int = 1, hide_empty: bool = False
    ) -> str:
        """
        List WooCommerce product tags.

        Args:
            per_page: Number of tags per page (1-100)
            page: Page number
            hide_empty: Hide tags with no products

        Returns:
            JSON string with tags list
        """
        try:
            params = {
                "per_page": per_page,
                "page": page,
                "hide_empty": "true" if hide_empty else "false",
            }

            tags = await self.client.get("products/tags", params=params, use_woocommerce=True)

            result = {
                "total": len(tags),
                "page": page,
                "tags": [
                    {
                        "id": tag["id"],
                        "name": tag["name"],
                        "slug": tag["slug"],
                        "description": tag.get("description", ""),
                        "count": tag.get("count", 0),
                    }
                    for tag in tags
                ],
            }

            return json.dumps(result, indent=2)
        except Exception as e:
            return json.dumps(
                {"error": str(e), "message": f"Failed to list product tags: {str(e)}"}, indent=2
            )

    # === PRODUCT ATTRIBUTES ===

    async def list_product_attributes(self) -> str:
        """
        List all global product attributes.

        Returns:
            JSON string with attributes list
        """
        try:
            attributes = await self.client.get("products/attributes", use_woocommerce=True)

            result = {
                "total": len(attributes),
                "attributes": [
                    {
                        "id": attr["id"],
                        "name": attr["name"],
                        "slug": attr["slug"],
                        "type": attr.get("type", "select"),
                        "order_by": attr.get("order_by", "menu_order"),
                        "has_archives": attr.get("has_archives", False),
                    }
                    for attr in attributes
                ],
            }

            return json.dumps(result, indent=2)
        except Exception as e:
            return json.dumps(
                {"error": str(e), "message": f"Failed to list product attributes: {str(e)}"},
                indent=2,
            )

    async def create_product_attribute(
        self,
        name: str,
        slug: str | None = None,
        type: str = "select",
        order_by: str = "menu_order",
        has_archives: bool = False,
    ) -> str:
        """
        Create a new global product attribute.

        Args:
            name: Attribute name (e.g., 'Size', 'Color')
            slug: Attribute slug (auto-generated if not provided)
            type: Attribute type (select or text)
            order_by: Default sort order
            has_archives: Enable archives for this attribute

        Returns:
            JSON string with created attribute data
        """
        try:
            data = {"name": name, "type": type, "order_by": order_by, "has_archives": has_archives}
            if slug:
                data["slug"] = slug

            attribute = await self.client.post(
                "products/attributes", json_data=data, use_woocommerce=True
            )

            result = {
                "id": attribute["id"],
                "name": attribute["name"],
                "slug": attribute["slug"],
                "message": f"Product attribute '{name}' created successfully with ID {attribute['id']}",
            }

            return json.dumps(result, indent=2)
        except Exception as e:
            return json.dumps(
                {"error": str(e), "message": f"Failed to create product attribute: {str(e)}"},
                indent=2,
            )

    # === PRODUCT VARIATIONS ===

    async def list_product_variations(
        self, product_id: int, per_page: int = 10, page: int = 1
    ) -> str:
        """
        List variations of a variable product.

        Args:
            product_id: Variable product ID
            per_page: Number of variations per page (1-100)
            page: Page number

        Returns:
            JSON string with variations list
        """
        try:
            params = {"per_page": per_page, "page": page}

            variations = await self.client.get(
                f"products/{product_id}/variations", params=params, use_woocommerce=True
            )

            result = {
                "product_id": product_id,
                "total": len(variations),
                "page": page,
                "variations": [
                    {
                        "id": var["id"],
                        "sku": var.get("sku", ""),
                        "regular_price": var.get("regular_price", ""),
                        "sale_price": var.get("sale_price", ""),
                        "stock_status": var.get("stock_status", "instock"),
                        "stock_quantity": var.get("stock_quantity"),
                        "attributes": var.get("attributes", []),
                        "image": var.get("image"),
                        "permalink": var.get("permalink"),
                    }
                    for var in variations
                ],
            }

            return json.dumps(result, indent=2)
        except Exception as e:
            return json.dumps(
                {"error": str(e), "message": f"Failed to list product variations: {str(e)}"},
                indent=2,
            )

    async def create_product_variation(
        self,
        product_id: int,
        attributes: list[dict[str, Any]],
        regular_price: str | None = None,
        sale_price: str | None = None,
        stock_quantity: int | None = None,
        stock_status: str = "instock",
        manage_stock: bool = False,
        sku: str | None = None,
        description: str | None = None,
        image: dict[str, int] | None = None,
    ) -> str:
        """
        Create a new variation for a variable product.

        Args:
            product_id: Parent variable product ID
            attributes: Attribute combinations (e.g., [{"name": "Size", "option": "Large"}])
            regular_price: Variation regular price
            sale_price: Variation sale price
            stock_quantity: Stock quantity
            stock_status: Stock status
            manage_stock: Enable stock management
            sku: Stock Keeping Unit
            description: Variation description
            image: Variation image (e.g., {"id": 123})

        Returns:
            JSON string with created variation data
        """
        try:
            # Phase K.2.2: Normalize attributes for variations
            # Ensure attributes have proper format for WooCommerce API
            normalized_attrs = []
            if attributes:
                for attr in attributes:
                    if isinstance(attr, dict):
                        # Ensure both name and option are strings and trimmed
                        attr_item = {}
                        if "id" in attr:
                            attr_item["id"] = int(attr["id"])
                        if "name" in attr:
                            attr_item["name"] = str(attr["name"]).strip()
                        if "option" in attr:
                            attr_item["option"] = str(attr["option"]).strip()
                        if attr_item:
                            normalized_attrs.append(attr_item)

            data = {
                "attributes": normalized_attrs,
                "stock_status": stock_status,
                "manage_stock": manage_stock,
            }

            # Add optional fields
            if regular_price:
                data["regular_price"] = regular_price
            if sale_price:
                data["sale_price"] = sale_price
            if stock_quantity is not None:
                data["stock_quantity"] = stock_quantity
            if sku:
                data["sku"] = sku
            if description:
                data["description"] = description
            if image:
                data["image"] = image

            variation = await self.client.post(
                f"products/{product_id}/variations", json_data=data, use_woocommerce=True
            )

            result = {
                "variation_id": variation["id"],
                "product_id": product_id,
                "attributes": variation["attributes"],
                "regular_price": variation.get("regular_price"),
                "sale_price": variation.get("sale_price"),
                "message": f"Product variation created successfully with ID {variation['id']}",
            }

            # Phase K.2.2: Add warning if attributes were sent but came back empty
            if normalized_attrs and not variation.get("attributes"):
                result["warning"] = (
                    "Attributes were sent but not saved. This usually means: "
                    "1) The parent product doesn't have these attributes defined with 'variation: true', or "
                    "2) The attribute names/options don't match exactly (case-sensitive). "
                    "Make sure to first define attributes on the parent variable product."
                )

            return json.dumps(result, indent=2)
        except Exception as e:
            return json.dumps(
                {
                    "error": str(e),
                    "message": f"Failed to create product variation: {str(e)}",
                    "hint": "For variation attributes to work, ensure: 1) Parent product has type='variable', "
                    "2) Parent product has attributes with 'variation: true', "
                    "3) Attribute names and options match exactly",
                },
                indent=2,
            )
