"""Endpoint registry with sample payloads for D365 CSU APIs."""

from __future__ import annotations

from typing import Any

# Each entry: (entity, operation, method, path, description, role, sample_body)
_ENDPOINTS: list[dict[str, Any]] = [
    # ── Customers ────────────────────────────────────────────────────
    {
        "entity": "Customers",
        "operation": "Search",
        "method": "POST",
        "path": "Customers/Search",
        "description": "Search customers by keyword.",
        "role": "Employee",
        "sample_body": {
            "CustomerSearchCriteria": {
                "Keyword": "contoso",
                "SearchOnlyCurrentCompany": True,
            },
            "QueryResultSettings": {"Paging": {"Top": 10, "Skip": 0}},
        },
    },
    {
        "entity": "Customers",
        "operation": "CreateEntity",
        "method": "POST",
        "path": "Customers/CreateEntity",
        "description": "Create a new customer.",
        "role": "Employee",
        "sample_body": {
            "entity": {
                "AccountNumber": "",
                "CustomerTypeValue": 1,
                "FirstName": "John",
                "LastName": "Doe",
                "Email": "john.doe@example.com",
                "Phone": "555-0100",
                "Addresses": [
                    {
                        "Street": "123 Main St",
                        "City": "Redmond",
                        "State": "WA",
                        "ZipCode": "98052",
                        "ThreeLetterISORegionName": "USA",
                        "AddressTypeValue": 6,
                    }
                ],
            }
        },
    },
    {
        "entity": "Customers",
        "operation": "UpdateEntity",
        "method": "POST",
        "path": "Customers('{account_number}')/UpdateEntity",
        "description": "Update an existing customer by account number.",
        "role": "Employee",
        "sample_body": {
            "updatedEntity": {
                "AccountNumber": "C0001",
                "FirstName": "Jane",
                "LastName": "Doe",
                "Email": "jane.doe@example.com",
            }
        },
    },
    {
        "entity": "Customers",
        "operation": "GetOrderHistory",
        "method": "POST",
        "path": "Customers('{account_number}')/GetOrderHistory",
        "description": "Get order history for a customer.",
        "role": "Employee",
        "sample_body": {
            "QueryResultSettings": {"Paging": {"Top": 20, "Skip": 0}},
        },
    },
    # ── Products ─────────────────────────────────────────────────────
    {
        "entity": "Products",
        "operation": "Search",
        "method": "POST",
        "path": "Products/Search",
        "description": "Search the product catalog by keyword.",
        "role": "Application",
        "sample_body": {
            "productSearchCriteria": {
                "SearchCondition": "laptop",
                "Context": {"ChannelId": 0, "CatalogId": 0},
            },
            "QueryResultSettings": {"Paging": {"Top": 10, "Skip": 0}},
        },
    },
    {
        "entity": "Products",
        "operation": "GetById",
        "method": "GET",
        "path": "Products({product_id})",
        "description": "Get a single product by record ID.",
        "role": "Application",
        "sample_body": None,
    },
    {
        "entity": "Products",
        "operation": "GetPrice",
        "method": "POST",
        "path": "Products({product_id})/GetPrice",
        "description": "Get the active price for a product.",
        "role": "Application",
        "sample_body": {
            "QueryResultSettings": {"Paging": {"Top": 1, "Skip": 0}},
        },
    },
    {
        "entity": "Products",
        "operation": "GetDimensionValues",
        "method": "POST",
        "path": "Products({product_id})/GetDimensionValues",
        "description": "Get available dimension values (size, color, etc.) for a product.",
        "role": "Application",
        "sample_body": {
            "dimensionType": 1,
            "QueryResultSettings": {"Paging": {"Top": 50, "Skip": 0}},
        },
    },
    # ── Carts ────────────────────────────────────────────────────────
    {
        "entity": "Carts",
        "operation": "Create",
        "method": "POST",
        "path": "Carts/CreateEmptyCart",
        "description": "Create an empty cart.",
        "role": "Employee",
        "sample_body": {},
    },
    {
        "entity": "Carts",
        "operation": "GetById",
        "method": "GET",
        "path": "Carts('{cart_id}')",
        "description": "Get cart by ID.",
        "role": "Employee",
        "sample_body": None,
    },
    {
        "entity": "Carts",
        "operation": "AddCartLines",
        "method": "POST",
        "path": "Carts('{cart_id}')/AddCartLines",
        "description": "Add line items to a cart.",
        "role": "Employee",
        "sample_body": {
            "cartLines": [
                {
                    "ProductId": 68719478036,
                    "Quantity": 1,
                    "UnitOfMeasureSymbol": "ea",
                }
            ]
        },
    },
    {
        "entity": "Carts",
        "operation": "RemoveCartLines",
        "method": "POST",
        "path": "Carts('{cart_id}')/RemoveCartLines",
        "description": "Remove line items from a cart.",
        "role": "Employee",
        "sample_body": {
            "lineIds": ["line-id-1"],
        },
    },
    {
        "entity": "Carts",
        "operation": "Checkout",
        "method": "POST",
        "path": "Carts('{cart_id}')/Checkout",
        "description": "Checkout a cart to create a sales order.",
        "role": "Employee",
        "sample_body": {
            "receiptEmail": "customer@example.com",
            "tokenizedPaymentCard": None,
            "receiptNumberSequence": None,
            "cartTenderLines": [],
        },
    },
    # ── Sales Orders ─────────────────────────────────────────────────
    {
        "entity": "SalesOrders",
        "operation": "Search",
        "method": "POST",
        "path": "SalesOrders/Search",
        "description": "Search sales orders by criteria.",
        "role": "Employee",
        "sample_body": {
            "orderSearchCriteria": {
                "CustomerAccountNumber": "C0001",
                "SearchType": 0,
            },
            "QueryResultSettings": {"Paging": {"Top": 10, "Skip": 0}},
        },
    },
    {
        "entity": "SalesOrders",
        "operation": "GetById",
        "method": "GET",
        "path": "SalesOrders('{order_id}')",
        "description": "Get a sales order by ID.",
        "role": "Employee",
        "sample_body": None,
    },
    # ── Categories ───────────────────────────────────────────────────
    {
        "entity": "Categories",
        "operation": "GetChannelNavigationHierarchy",
        "method": "POST",
        "path": "Categories/GetChannelNavigationHierarchy",
        "description": "Get the channel navigation category hierarchy.",
        "role": "Application",
        "sample_body": {
            "QueryResultSettings": {"Paging": {"Top": 100, "Skip": 0}},
        },
    },
    {
        "entity": "Categories",
        "operation": "GetById",
        "method": "GET",
        "path": "Categories({category_id})",
        "description": "Get a category by record ID.",
        "role": "Application",
        "sample_body": None,
    },
    # ── OrgUnits (Stores) ────────────────────────────────────────────
    {
        "entity": "OrgUnits",
        "operation": "Search",
        "method": "POST",
        "path": "OrgUnits/Search",
        "description": "Search for stores / org units.",
        "role": "Application",
        "sample_body": {
            "OrgUnitSearchCriteria": {},
            "QueryResultSettings": {"Paging": {"Top": 50, "Skip": 0}},
        },
    },
    {
        "entity": "OrgUnits",
        "operation": "GetById",
        "method": "GET",
        "path": "OrgUnits({org_unit_number})",
        "description": "Get a specific org unit / store.",
        "role": "Application",
        "sample_body": None,
    },
    {
        "entity": "OrgUnits",
        "operation": "GetTillLayout",
        "method": "POST",
        "path": "OrgUnits/GetTillLayout",
        "description": "Get the till / POS layout for the current org unit.",
        "role": "Employee",
        "sample_body": {},
    },
]


def list_endpoints(entity: str | None = None) -> list[dict[str, Any]]:
    """Return endpoint registry, optionally filtered by entity name.

    Args:
        entity: Filter by entity name (case-insensitive). None returns all.
    """
    if entity is None:
        return list(_ENDPOINTS)
    entity_lower = entity.lower()
    return [ep for ep in _ENDPOINTS if ep["entity"].lower() == entity_lower]


def get_sample_payload(entity: str, operation: str) -> dict[str, Any] | None:
    """Return the sample request body for a given entity + operation.

    Args:
        entity: Entity name (e.g. "Customers").
        operation: Operation name (e.g. "Search").

    Returns:
        Sample body dict, or None if the endpoint uses GET / has no body.

    Raises:
        KeyError: If the entity/operation combination is not found.
    """
    entity_lower = entity.lower()
    operation_lower = operation.lower()
    for ep in _ENDPOINTS:
        if ep["entity"].lower() == entity_lower and ep["operation"].lower() == operation_lower:
            return ep["sample_body"]
    raise KeyError(f"No endpoint found for entity={entity!r}, operation={operation!r}")


def list_entities() -> list[str]:
    """Return sorted unique entity names."""
    return sorted({ep["entity"] for ep in _ENDPOINTS})
