/**
 * Documentation for the queryMapped operation
 */

/**
 * Returns documentation for the queryMapped operation
 * @return {string} markdown documentation
 */
export function queryMappedDocs(): string {
  return `
# QueryMapped Operation

## General Description

The \`queryMapped\` operation retrieves related entities for a specific entity based on a reference property.

## Detailed Description

This operation is specifically designed for querying related entities through a reference property. It's particularly useful for retrieving entities in many-to-many or one-to-many relationships. Unlike the standard query operation, queryMapped requires an entityId (the parent entity) and a mapColName (the reference property name) to determine which related entities to retrieve.

## Input Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| queryParams | object | Yes | The query parameters object that defines the search criteria and result options. |
| token | string | No | Authentication token for your request. If not provided, the system will use the default API key from environment variables. |
| tenantCode | string | No | Tenant code to specify which tenant's data to access. If not provided, the system will extract it from the token or use the default tenant code from environment variables. |

### QueryParams Object Structure

Same as the standard query operation, with these additional/required parameters:

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| entDefName | string | Yes* | Name of the entity definition to query. Required if entDefId is not provided. Getter/setter for entityDef.name. |
| entDefId | string | Yes* | ID of the entity definition to query. Required if entDefName is not provided. Getter/setter for entityDef.id. |
| entityDef | object | No | Entity definition object with id and/or name properties. |
| entityId | string | Yes | Property for entity ID of the parent entity whose related entities you want to retrieve. |
| mapColName | string | Yes | Name of the reference property that defines the relationship. |
| propertyName | string | No | Alternative to mapColName, also specifies the reference property name. |
| refColName | string | No | Getter/setter for mapColName. |
| selectCols | array | No | Array of SelectCol objects defining columns to select in the query. If not provided, all columns are selected. |
| filters | array | No | Array of Filter objects to filter the related entities. |
| startIndex | number | No | Pagination start index (0-based). |
| count | number | No | Number of records to return. |
| sortCols | array | No | Array of SortCol objects for sorting specifications. |
| includes | array | No | Array of IncludeQuery objects for additional related entities to include in the results. |
| calcTotalCount | boolean | No | Whether to calculate the total count of matching records. |
| searchText | string | No | Search term for automatic searching across all searchable fields. |
| queryType | number | No | Type of query using QueryType enum (Single=0, List=1, Search=2, AutoComplete=3, Full=4, FullWithSingleRefs=5, FullNonPersonal=6). |

## Response

### Success Response

\`\`\`json
{
    "success": true,
    "entities": [
        // Array of related entities
        {
            "id": "string",
            "property1": "value1",
            "property2": "value2",
            // ...
        }
    ],
    "totalCount": 42,  // Present only if calcTotalCount is true
    "message": "string",  // Optional message
    "status": 200  // Optional status code
}
\`\`\`

### Error Response

\`\`\`json
{
    "success": false,
    "error": "Error message describing what went wrong"
}
\`\`\`

## Example Usage

### Basic Mapped Query

\`\`\`typescript
// Get all order items for a specific order
const result = await queryMapped({
  queryParams: {
    entDefName: "Order",
    entityId: "order-123",
    mapColName: "items"
  }
});

if (result.success) {
  const orderItems = result.entities;
  console.log(\`Order has \${orderItems.length} items\`);
  orderItems.forEach(item => {
    console.log(\`- \${item.quantity} x \${item.productName} (\${item.unitPrice})\`);
  });
} else {
  console.error("Error:", result.error);
}
\`\`\`

### Filtered Mapped Query

\`\`\`typescript
// Get active users in a specific group
const result = await queryMapped({
  queryParams: {
    entityDef: {
      name: "Group"
    },
    entityId: "group-456",
    mapColName: "members",
    filters: [
      {
        col: { name: "status" },
        val: { value: "active" },
        function: 0 // QueryFunction.Equals (default)
      }
    ],
    sortCols: [
      {
        col: { name: "lastName" },
        sortType: "asc"
      }
    ]
  }
});

if (result.success) {
  const activeMembers = result.entities;
  console.log(\`Group has \${activeMembers.length} active members\`);
}
\`\`\`

### Mapped Query with Nested Includes

\`\`\`typescript
// Get products in a category with their suppliers
const result = await queryMapped({
  queryParams: {
    entDefName: "Category",
    entityId: "category-789",
    mapColName: "products",
    includes: [
      {
        propertyName: "supplier",
        includes: [
          {
            propertyName: "address",
            count: 1, // take only one address
            filters: [
              {
                col: { name: "isDefault" },
                val: { value: true },
                function: 0 // QueryFunction.Equals
              }
            ]
          }
        ]
      }
    ]
  }
});

if (result.success) {
  const products = result.entities;
  products.forEach(product => {
    if (product.supplier) {
      console.log(\`\${product.name} supplied by \${product.supplier.name}\`);
      if (product.supplier.address) {
        console.log(\`  Supplier address: \${product.supplier.address.city}, \${product.supplier.address.country}\`);
      }
    }
  });
}
\`\`\`

### Mapped Query with Aggregation

\`\`\`typescript
// Get count of orders by status for a specific customer
const result = await queryMapped({
  queryParams: {
    entDefName: "Customer",
    entityId: "customer-123",
    mapColName: "orders",
    selectCols: [
      {
        name: "status",
        groupBy: true
      },
      {
        name: "id",
        aggregateFunction: 3, // AggregateFunction.Count
        selectAsTitle: "orderCount"
      }
    ]
  }
});

if (result.success) {
  const orderStats = result.entities;
  orderStats.forEach(stat => {
    console.log(\`\${stat.status}: \${stat.orderCount} orders\`);
  });
}
\`\`\`

## Additional Information

- The queryMapped operation is specifically designed for retrieving related entities through a reference property.
- It requires both the parent entity ID (entityId) and the reference property name (mapColName).
- The operation follows the reference defined in the entity definition to retrieve the related entities.
- This operation is particularly useful for:
  - Retrieving items in a many-to-one relationship (e.g., order items for an order)
  - Retrieving entities in a many-to-many relationship (e.g., users in a group)
  - Retrieving any related entities where the reference property is defined as multiple
- The operation supports all the filtering, sorting, pagination, and analytical capabilities of the standard query operation.
- For standard entity queries without relationship mapping, use the query operation instead.
- Access permissions are enforced based on the provided token.
- Does not work with reference properties that are defined as single.
- All SelectCol, Filter, SortCol, and IncludeQuery objects follow the same structure as the standard query operation.
- Use QueryFunction enum values (0-27) for filter functions.
- Use AggregateFunction enum values (0-6) for analytical queries.
- Use DateModifier enum values (0-11) for time-based grouping.
- Alternatively, you can use query operation on reference entity definition with filter, or query operation on same entity definition with include.
  - Example:
    - entity: Order
    - reference property: items
    - query on OrderItem with filter order_id = 'order-123'
    - query on Order with include items and filter id = 'order-123'
    - queryMapped on Order with mapColName = 'items' and entityId = 'order-123'
`;
}

/**
 * Returns a brief summary of the queryMapped operation.
 * @return {string} A short description of the function.
 */
export function queryMappedSummary(): string {
  return `
**Purpose**: Retrieves related entities through a reference property.

**When to use**:
- Accessing items in many-to-one relationships
- Retrieving members in many-to-many relationships
- Filtering/sorting related collections

**Inputs**:
- queryParams: Object with entityId, mapColName, filters, sorting {entDefName/entDefId: string, entityId: string, mapColName: string, selectCols?: [...,{name: string, aggregateFunction?: number, groupBy?: boolean}], filters?: [...,{col: {name: string}, val: {value: any}, function?: number}], sortCols?: [...,{col: {name: string}, sortType?: string}], startIndex?: number, count?: number, calcTotalCount?: boolean, searchText?: string, queryType?: number}
- token (optional)
- tenantCode (optional)

**Returns**: Related entities matching criteria.
`;
}

export default queryMappedDocs; 