import { buildApiPrompt, } from "./prompt-builder.js";
export const VALID_TAGS = [
    // Control flow
    "loop",
    "conditional",
    "trycatch",
    "nested-control-flow",
    // Integrations w/ special guidance
    "snowflake",
    "databricks",
    // Patterns
    "scope-access",
    "variable-access",
    "error-handling",
    "validation",
    "data-transformation",
    "batch-processing",
    "global-context",
    "multi-integration",
    "data-science",
    "sql-query",
    "aggregation",
    // Error types (for negative examples)
    "error-scope-violation",
    "error-execution-order",
];
export const POSITIVE_EXAMPLES = [
    {
        id: "getUsersByStatusApi",
        metadata: {
            tags: ["conditional", "validation", "sql-query"],
            complexity: "simple",
            category: "positive",
            estimatedTokens: 450,
        },
        inputContext: {
            pageEntities: [{ name: "statusFilter", type: "Variable" }],
            availableIntegrations: [
                {
                    name: "PostgresDB",
                    id: "<postgres-integration-id>",
                    type: "PostgreSQL",
                },
            ],
            integrationMetadata: [
                {
                    integrationId: "<postgres-integration-id>",
                    metadata: {
                        databaseSchemaMetadata: {
                            tables: [
                                {
                                    type: "TABLE",
                                    name: "users",
                                    schema: "public",
                                    columns: [
                                        { name: "id", type: "int4" },
                                        { name: "email", type: "varchar" },
                                        { name: "full_name", type: "varchar" },
                                        { name: "status", type: "varchar" },
                                        { name: "created_at", type: "timestamp" },
                                        { name: "last_login", type: "timestamp" },
                                    ],
                                },
                            ],
                        },
                    },
                },
            ],
        },
        userPrompt: "Create an API that fetches users filtered by their account status. The API should accept a status filter from the statusFilter variable and validate it against allowed values (active, inactive, pending). If an invalid status is provided, throw an error. Query the PostgreSQL database to fetch user details including id, email, full_name, status, created_at, and last_login. Sort results by creation date (newest first). Return a formatted response with the user list, count, applied filter, and timestamp.",
        code: `import {
  Api,
  PostgreSQL,
  Conditional,
  Throw,
  JavaScript,
} from "@superblocksteam/library";

export default new Api("getUsersByStatusApi", [
  new Conditional("validate_status_input", {
    if: {
      when: ({ statusFilter }) => {
        const validStatuses = ['active', 'inactive', 'pending'];
        return statusFilter && !validStatuses.includes(statusFilter);
      },
      then: [
        new Throw("invalid_status", {
          error: "Status must be one of: active, inactive, pending"
        })
      ]
    }
  }),
  new JavaScript("get_validated_status", {
    fn: ({ statusFilter }) => {
      const validStatuses = ['active', 'inactive', 'pending'];
      return validStatuses.includes(statusFilter) ? statusFilter : 'active';
    }
  }),
  new PostgreSQL("fetch_users", "<postgres-integration-id>", {
    statement: ({ get_validated_status }) => \`
      SELECT
        id,
        email,
        full_name,
        status,
        created_at,
        last_login
      FROM users
      WHERE status = '\${get_validated_status.output}'
      ORDER BY created_at DESC
      LIMIT 100
    \`
  }),
  new JavaScript("format_response", {
    fn: ({ fetch_users, get_validated_status }) => ({
      users: fetch_users.output || [],
      count: (fetch_users.output || []).length,
      filterApplied: get_validated_status.output,
      timestamp: new Date().toISOString()
    })
  })
]);`,
    },
    {
        id: "getOrderSummaryApi",
        metadata: {
            tags: ["data-transformation", "sql-query", "aggregation"],
            complexity: "intermediate",
            category: "positive",
            estimatedTokens: 520,
        },
        userPrompt: "Create an API that generates comprehensive order analytics. The API should: 1) Fetch the most recent orders from the orders table including id, customer_id, total_amount, status, item_count, and created_at. 2) Calculate aggregate statistics including total orders, total revenue, average order value, total items sold, and a breakdown by order status. 3) Identify the top 10 customers by total spending, showing their customer ID, order count, and total amount spent. 4) Return a formatted response with the statistics, top customers list, and a sample of the 5 most recent orders along with a generation timestamp.",
        code: `import {
  Api,
  PostgreSQL,
  JavaScript,
} from "@superblocksteam/library";

export default new Api("getOrderSummaryApi", [
  new PostgreSQL("fetch_recent_orders", "<postgres-integration-id>", {
    statement: () => \`
      SELECT
        id,
        customer_id,
        total_amount,
        status,
        item_count,
        created_at
      FROM orders
      ORDER BY created_at DESC
      LIMIT 100
    \`
  }),
  new JavaScript("calculate_statistics", {
    fn: ({ fetch_recent_orders }) => {
      const orders = fetch_recent_orders.output || [];

      const stats = {
        totalOrders: orders.length,
        totalRevenue: 0,
        averageOrderValue: 0,
        totalItems: 0,
        statusBreakdown: {}
      };

      orders.forEach(order => {
        stats.totalRevenue += order.total_amount || 0;
        stats.totalItems += order.item_count || 0;

        const status = order.status || 'unknown';
        stats.statusBreakdown[status] = (stats.statusBreakdown[status] || 0) + 1;
      });

      if (stats.totalOrders > 0) {
        stats.averageOrderValue = stats.totalRevenue / stats.totalOrders;
      }

      return stats;
    }
  }),
  new JavaScript("identify_top_customers", {
    fn: ({ fetch_recent_orders }) => {
      const orders = fetch_recent_orders.output || [];
      const customerTotals: Record<string, { customerId: string; orderCount: number; totalSpent: number }> = {};

      orders.forEach(order => {
        const customerId = order.customer_id;
        if (!customerTotals[customerId]) {
          customerTotals[customerId] = { customerId, orderCount: 0, totalSpent: 0 };
        }
        customerTotals[customerId].orderCount += 1;
        customerTotals[customerId].totalSpent += order.total_amount || 0;
      });

      return Object.values(customerTotals)
        .sort((a, b) => b.totalSpent - a.totalSpent)
        .slice(0, 10);
    }
  }),
  new JavaScript("format_final_response", {
    fn: ({ calculate_statistics, identify_top_customers, fetch_recent_orders }) => ({
      statistics: calculate_statistics.output,
      topCustomers: identify_top_customers.output,
      sampleOrders: (fetch_recent_orders.output || []).slice(0, 5),
      generatedAt: new Date().toISOString()
    })
  })
]);`,
    },
    {
        id: "processOrderBatchApi",
        metadata: {
            tags: ["loop", "conditional", "batch-processing", "nested-control-flow"],
            complexity: "intermediate",
            category: "positive",
            estimatedTokens: 680,
        },
        userPrompt: "Create an API that processes pending orders in batch. The API should: 1) Fetch up to 100 pending orders from the orders table, sorted by creation date (oldest first). 2) Loop through each order and determine the processing type based on order amount - orders over $1000 get premium processing with 1% fee and priority 1, others get standard processing with 2% fee and priority 2. 3) For each order, update the database to set status to 'processing', save the processing type, fee, and priority, and update the timestamp. 4) Return a summary showing total orders processed, successful updates, and processing timestamp. This will be used by the order fulfillment team to automatically triage and process incoming orders.",
        code: `import {
  Api,
  PostgreSQL,
  Loop,
  Conditional,
  JavaScript,
} from "@superblocksteam/library";

export default new Api("processOrderBatchApi", [
  new PostgreSQL("fetch_pending_orders", "<postgres-integration-id>", {
    statement: () => \`
      SELECT
        id,
        customer_id,
        total_amount,
        items_count,
        created_at
      FROM orders
      WHERE status = 'pending'
      ORDER BY created_at ASC
      LIMIT 100
    \`
  }),
  new Loop("process_each_order", {
    over: ({ fetch_pending_orders }) => fetch_pending_orders.output,
    variables: { item: "order", index: "idx" },
    blocks: [
      new Conditional("determine_processing_type", {
        if: {
          when: ({ order }) => order.value.total_amount > 1000,
          then: [
            new JavaScript("calculate_premium_fee", {
              fn: ({ order }) => ({
                processing_type: 'premium',
                priority: 1,
                fee: order.value.total_amount * 0.01
              })
            })
          ]
        },
        else: [
          new JavaScript("calculate_standard_fee", {
            fn: ({ order }) => ({
              processing_type: 'standard',
              priority: 2,
              fee: order.value.total_amount * 0.02
            })
          })
        ]
      }),
      new PostgreSQL("update_order", "<postgres-integration-id>", {
        statement: ({ order, determine_processing_type }) => \`
          UPDATE orders
          SET
            status = 'processing',
            processing_type = '\${determine_processing_type.output.processing_type}',
            processing_fee = \${determine_processing_type.output.fee},
            priority = \${determine_processing_type.output.priority},
            updated_at = NOW()
          WHERE id = \${order.value.id}
        \`
      })
    ]
  }),
  new JavaScript("summarize_results", {
    fn: ({ process_each_order, fetch_pending_orders }) => {
      const updateResults = process_each_order.output || [];
      const originalOrders = fetch_pending_orders.output || [];

      return {
        totalProcessed: originalOrders.length,
        successfulUpdates: updateResults.length, // Loop returns array of results from each iteration
        processedAt: new Date().toISOString()
      };
    }
  })
]);`,
    },
    {
        id: "getEnrichedCustomerDataApi",
        metadata: {
            tags: [
                "trycatch",
                "error-handling",
                "conditional",
                "validation",
                "multi-integration",
            ],
            complexity: "intermediate",
            category: "positive",
            estimatedTokens: 720,
        },
        inputContext: {
            pageEntities: [{ name: "customerIdVar", type: "Variable" }],
            availableIntegrations: [
                {
                    name: "PostgresDB",
                    id: "<postgres-integration-id>",
                    type: "PostgreSQL",
                },
                {
                    name: "ProfileEnrichmentAPI",
                    id: "<openapi-integration-id>",
                    type: "OpenApi",
                },
            ],
            integrationMetadata: [
                {
                    integrationId: "<postgres-integration-id>",
                    metadata: {
                        databaseSchemaMetadata: {
                            tables: [
                                {
                                    type: "TABLE",
                                    name: "customers",
                                    schema: "public",
                                    columns: [
                                        { name: "id", type: "int4" },
                                        { name: "email", type: "varchar" },
                                        { name: "full_name", type: "varchar" },
                                        { name: "account_type", type: "varchar" },
                                        { name: "created_at", type: "timestamp" },
                                    ],
                                },
                            ],
                        },
                    },
                },
            ],
        },
        userPrompt: "Create an API that enriches customer data from an external service. The API should: 1) Validate that the customerIdVar contains a valid positive number, throwing an error if invalid. 2) Fetch basic customer information (id, email, full_name, account_type, created_at) from the PostgreSQL customers table. 3) Attempt to enrich the customer data by calling an external profile enrichment API using the OpenAPI integration - this should fetch social score, verification status, and risk level. 4) If the external API fails, gracefully fall back to default enrichment data with social_score: 0, verified: false, and risk_level: 'unknown', and include the error message. 5) Merge the basic customer data with the enrichment data and return a combined profile including the enrichment source and success status. This will be used to display enhanced customer profiles in the CRM dashboard.",
        code: `import {
  Api,
  PostgreSQL,
  OpenApi,
  TryCatch,
  Conditional,
  Throw,
  JavaScript,
} from "@superblocksteam/library";

export default new Api("getEnrichedCustomerDataApi", [
  new Conditional("validate_customer_id", {
    if: {
      when: ({ customerIdVar }) => {
        const id = parseInt(customerIdVar);
        return isNaN(id) || id <= 0;
      },
      then: [
        new Throw("invalid_customer_id", {
          error: "Customer ID must be a positive number"
        })
      ]
    }
  }),
  new PostgreSQL("fetch_customer_basic", "<postgres-integration-id>", {
    statement: ({ customerIdVar }) => \`
      SELECT
        id,
        email,
        full_name,
        account_type,
        created_at
      FROM customers
      WHERE id = \${parseInt(customerIdVar)}
      LIMIT 1
    \`
  }),
  new TryCatch("fetch_external_enrichment", {
    variables: { error: "enrichmentError" },
    try: [
      new OpenApi("call_enrichment_api", "<openapi-integration-id>", {
        method: "GET",
        url: ({ fetch_customer_basic }) => {
          const customer = (fetch_customer_basic.output || [])[0];
          return \`/profile/\${customer?.id || 0}\`;
        },
        headers: [
          { key: "Authorization", value: "Bearer sk_live_abc123xyz" }
        ]
      }, {
        path: "/profile/{id}"
      }),
      new JavaScript("format_enriched_data", {
        fn: ({ call_enrichment_api }) => ({
          success: true,
          data: call_enrichment_api.output || {},
          source: 'external_api'
        })
      })
    ],
    catch: [
      new JavaScript("provide_fallback_enrichment", {
        fn: ({ enrichmentError }) => ({
          success: false,
          data: {
            social_score: 0,
            verified: false,
            risk_level: 'unknown'
          },
          source: 'fallback',
          error: enrichmentError.value?.message || 'External API unavailable'
        })
      })
    ]
  }),
  new JavaScript("merge_customer_data", {
    fn: ({ fetch_customer_basic, fetch_external_enrichment }) => {
      const customer = (fetch_customer_basic.output || [])[0] || {};
      const enrichment = fetch_external_enrichment.output || {};

      return {
        id: customer.id,
        email: customer.email,
        fullName: customer.full_name,
        accountType: customer.account_type,
        enrichmentData: enrichment.data || {},
        enrichmentSource: enrichment.source,
        enrichmentSuccess: enrichment.success || false
      };
    }
  })
]);`,
    },
    {
        id: "getCrossPlatformAnalyticsApi",
        metadata: {
            tags: [
                "snowflake",
                "global-context",
                "data-transformation",
                "multi-integration",
            ],
            complexity: "intermediate",
            category: "positive",
            estimatedTokens: 650,
        },
        inputContext: {
            availableIntegrations: [
                {
                    name: "PostgresDB",
                    id: "<postgres-integration-id>",
                    type: "PostgreSQL",
                },
                {
                    name: "SnowflakeWarehouse",
                    id: "<snowflake-integration-id>",
                    type: "Snowflake",
                },
            ],
            integrationMetadata: [
                {
                    integrationId: "<postgres-integration-id>",
                    metadata: {
                        databaseSchemaMetadata: {
                            tables: [
                                {
                                    type: "TABLE",
                                    name: "transactions",
                                    schema: "public",
                                    columns: [
                                        { name: "transaction_id", type: "int4" },
                                        { name: "user_id", type: "int4" },
                                        { name: "amount", type: "numeric" },
                                        { name: "category", type: "varchar" },
                                        { name: "created_at", type: "timestamp" },
                                    ],
                                },
                                {
                                    type: "TABLE",
                                    name: "users",
                                    schema: "public",
                                    columns: [
                                        { name: "id", type: "int4" },
                                        { name: "email", type: "varchar" },
                                    ],
                                },
                            ],
                        },
                    },
                },
                {
                    integrationId: "<snowflake-integration-id>",
                    metadata: {
                        databaseSchemaMetadata: {
                            tables: [
                                {
                                    type: "TABLE",
                                    name: "USER_METRICS",
                                    schema: "PUBLIC",
                                    columns: [
                                        { name: "USER_ID", type: "NUMBER" },
                                        { name: "USER_EMAIL", type: "VARCHAR" },
                                        { name: "PAGE_VIEWS", type: "NUMBER" },
                                        { name: "SESSION_COUNT", type: "NUMBER" },
                                        { name: "LAST_ACTIVE_DATE", type: "TIMESTAMP_NTZ" },
                                        { name: "ENGAGEMENT_SCORE", type: "FLOAT" },
                                    ],
                                },
                            ],
                        },
                    },
                },
            ],
        },
        userPrompt: "Create an API that generates cross-platform analytics for the current logged-in user. The API should: 1) Fetch the user's transaction history from the PostgreSQL transactions table using Global.user.email to identify the user - include transaction_id, amount, category, and created_at, limited to the most recent transactions sorted by date descending. 2) Fetch the user's engagement metrics from the Snowflake analytics warehouse USER_METRICS table (also using Global.user.email) - get USER_ID, PAGE_VIEWS, SESSION_COUNT, LAST_ACTIVE_DATE, and ENGAGEMENT_SCORE, taking only the most recent record. 3) Calculate spending breakdown by category, showing category name, total amount, and transaction count, sorted by total amount descending. 4) Merge all the data into a comprehensive response showing user info from Global, transaction summary (total transactions, total spent, breakdown by category), and engagement metrics (page views, sessions, last active date, engagement score), along with a generation timestamp. This will power the unified user analytics dashboard.",
        code: `import {
  Api,
  PostgreSQL,
  Snowflake,
  JavaScript,
  Global,
} from "@superblocksteam/library";

export default new Api("getCrossPlatformAnalyticsApi", [
  new PostgreSQL("fetch_user_transactions", "<postgres-integration-id>", {
    statement: () => \`
      SELECT
        transaction_id,
        amount,
        category,
        created_at
      FROM transactions
      WHERE user_id = (
        SELECT id FROM users WHERE email = '\${Global.user.email}' LIMIT 1
      )
      ORDER BY created_at DESC
      LIMIT 100
    \`
  }),
  new Snowflake("fetch_user_analytics", "<snowflake-integration-id>", {
    statement: () => \`
      SELECT
        USER_ID,
        PAGE_VIEWS,
        SESSION_COUNT,
        LAST_ACTIVE_DATE,
        ENGAGEMENT_SCORE
      FROM ANALYTICS.PUBLIC.USER_METRICS
      WHERE USER_EMAIL = '\${Global.user.email}'
      ORDER BY LAST_ACTIVE_DATE DESC
      LIMIT 1
    \`
  }),
  new JavaScript("calculate_spending_by_category", {
    fn: ({ fetch_user_transactions }) => {
      const transactions = fetch_user_transactions.output || [];
      const categoryTotals: Record<string, number> = {};

      transactions.forEach(txn => {
        const category = txn.category || 'uncategorized';
        categoryTotals[category] = (categoryTotals[category] || 0) + (txn.amount || 0);
      });

      return Object.entries(categoryTotals).map(([category, total]) => ({
        category,
        total,
        transactionCount: transactions.filter(t => t.category === category).length
      })).sort((a, b) => b.total - a.total);
    }
  }),
  new JavaScript("merge_all_data", {
    fn: ({ fetch_user_transactions, fetch_user_analytics, calculate_spending_by_category }) => {
      const analytics = (fetch_user_analytics.output || [])[0] || {};
      const transactions = fetch_user_transactions.output || [];

      return {
        user: {
          email: Global.user.email,
          name: Global.user.name
        },
        transactionSummary: {
          totalTransactions: transactions.length,
          totalSpent: transactions.reduce((sum, t) => sum + (t.amount || 0), 0),
          byCategory: calculate_spending_by_category.output
        },
        engagementMetrics: {
          pageViews: analytics.PAGE_VIEWS || 0,
          sessions: analytics.SESSION_COUNT || 0,
          lastActive: analytics.LAST_ACTIVE_DATE || null,
          engagementScore: analytics.ENGAGEMENT_SCORE || 0
        },
        generatedAt: new Date().toISOString()
      };
    }
  })
]);`,
    },
    {
        id: "analyzeCustomerSegmentsApi",
        metadata: {
            tags: ["data-transformation", "data-science"],
            complexity: "intermediate",
            category: "positive",
            estimatedTokens: 600,
        },
        userPrompt: "Create an API that performs RFM (Recency, Frequency, Monetary) customer segmentation analysis. The API should: 1) Fetch customer metrics from the customer_metrics table including customer_id, total_purchases, average_order_value, days_since_last_purchase, and total_spent, limited to the top customers by total spending. 2) Use Python with pandas and numpy to perform RFM analysis - calculate recency, frequency, and monetary scores using quartile-based scoring (1-4), combine the scores, and assign customers to segments: 'Champions' (score >= 10), 'Loyal Customers' (score >= 8), 'Potential Loyalists' (score >= 6), 'At Risk' (score >= 4), or 'Lost' (score < 4). 3) Summarize the results by segment showing count of customers, total revenue, and average order value for each segment. Return the segment summary, total customers analyzed, and analysis timestamp. This will be used by the marketing team to target customer segments with appropriate campaigns.",
        code: `import {
  Api,
  PostgreSQL,
  Python,
  JavaScript,
} from "@superblocksteam/library";

export default new Api("analyzeCustomerSegmentsApi", [
  new PostgreSQL("fetch_customer_metrics", "<postgres-integration-id>", {
    statement: () => \`
      SELECT
        customer_id,
        total_purchases,
        average_order_value,
        days_since_last_purchase,
        total_spent
      FROM customer_metrics
      ORDER BY total_spent DESC
      LIMIT 100
    \`
  }),
  new Python("calculate_segments", {
    fn: \`
import pandas as pd
import numpy as np

# Access block output via Global
customers = Global['fetch_customer_metrics']['output']

# Convert to DataFrame
df = pd.DataFrame(customers)

# Calculate customer segments using RFM analysis
df['recency_score'] = pd.qcut(df['days_since_last_purchase'], q=4, labels=[4,3,2,1], duplicates='drop')
df['frequency_score'] = pd.qcut(df['total_purchases'], q=4, labels=[1,2,3,4], duplicates='drop')
df['monetary_score'] = pd.qcut(df['total_spent'], q=4, labels=[1,2,3,4], duplicates='drop')

# Combine scores
df['rfm_score'] = (df['recency_score'].astype(int) +
                   df['frequency_score'].astype(int) +
                   df['monetary_score'].astype(int))

# Assign segments
def assign_segment(score):
    if score >= 10:
        return 'Champions'
    elif score >= 8:
        return 'Loyal Customers'
    elif score >= 6:
        return 'Potential Loyalists'
    elif score >= 4:
        return 'At Risk'
    else:
        return 'Lost'

df['segment'] = df['rfm_score'].apply(assign_segment)

# Return as list of dicts
df.to_dict('records')
    \`
  }),
  new JavaScript("summarize_segments", {
    fn: ({ calculate_segments }) => {
      const segmented = calculate_segments.output || [];
      const summary = {};

      segmented.forEach(customer => {
        const segment = customer.segment || 'Unknown';
        if (!summary[segment]) {
          summary[segment] = {
            count: 0,
            totalRevenue: 0,
            avgOrderValue: 0
          };
        }
        summary[segment].count += 1;
        summary[segment].totalRevenue += customer.total_spent || 0;
      });

      // Calculate averages
      Object.keys(summary).forEach(segment => {
        if (summary[segment].count > 0) {
          summary[segment].avgOrderValue = summary[segment].totalRevenue / summary[segment].count;
        }
      });

      return {
        segmentSummary: summary,
        totalCustomers: segmented.length,
        analyzedAt: new Date().toISOString()
      };
    }
  })
]);`,
    },
    {
        id: "processInventoryUpdatesApi",
        metadata: {
            tags: [
                "loop",
                "conditional",
                "nested-control-flow",
                "scope-access",
                "batch-processing",
            ],
            complexity: "complex",
            category: "positive",
            estimatedTokens: 850,
        },
        userPrompt: "Create an API that processes inventory updates with complex validation and batch operations. The API should: 1) Fetch pending inventory updates from the inventory_queue table. 2) Loop through each inventory update, and within each iteration: validate if the product exists by checking a product_status flag, and if valid: (a) check if it's a bulk operation (quantity > 100), if so calculate a bulk discount of 5%, otherwise use standard pricing, (b) update the inventory table with the new quantity and price. 3) After all updates, summarize the results by operation type (bulk vs standard), showing count, total quantity, and average price for each type. This demonstrates proper scope access across double-nested control flow (Loop > Conditional > Conditional).",
        code: `import {
  Api,
  PostgreSQL,
  Loop,
  Conditional,
  JavaScript,
} from "@superblocksteam/library";

export default new Api("processInventoryUpdatesApi", [
  new PostgreSQL("fetch_pending_updates", "<postgres-integration-id>", {
    statement: () => \`
      SELECT
        id,
        product_id,
        quantity_change,
        unit_price,
        product_status,
        operation_type
      FROM inventory_queue
      WHERE status = 'pending'
      ORDER BY created_at ASC
      LIMIT 100
    \`
  }),
  new Loop("process_each_update", {
    over: ({ fetch_pending_updates }) => fetch_pending_updates.output,
    variables: { item: "update", index: "updateIdx" },
    blocks: [
      // First level: Validate product status
      new Conditional("validate_product", {
        if: {
          when: ({ update }) => update.value.product_status === 'active',
          then: [
            // Second level (nested inside first Conditional): Check for bulk operation
            new Conditional("determine_pricing", {
              if: {
                when: ({ update }) => update.value.quantity_change > 100,
                then: [
                  new JavaScript("calculate_bulk_pricing", {
                    fn: ({ update, updateIdx }) => ({
                      operation_type: 'bulk',
                      quantity: update.value.quantity_change,
                      unit_price: update.value.unit_price,
                      final_price: update.value.unit_price * 0.95, // 5% bulk discount
                      index: updateIdx.value
                    })
                  })
                ]
              },
              else: [
                new JavaScript("calculate_standard_pricing", {
                  fn: ({ update, updateIdx }) => ({
                    operation_type: 'standard',
                    quantity: update.value.quantity_change,
                    unit_price: update.value.unit_price,
                    final_price: update.value.unit_price,
                    index: updateIdx.value
                  })
                })
              ]
            }),
            // This block can access:
            // ✅ determine_pricing.output (parent Conditional output)
            // ✅ update, updateIdx (Loop variables from ancestor)
            // ✅ fetch_pending_updates (top-level sibling)
            // ❌ CANNOT access calculate_bulk_pricing or calculate_standard_pricing directly
            new PostgreSQL("update_inventory", "<postgres-integration-id>", {
              statement: ({ update, determine_pricing }) => \`
                UPDATE inventory
                SET
                  quantity = quantity + \${update.value.quantity_change},
                  unit_price = \${determine_pricing.output.final_price},
                  last_updated = NOW()
                WHERE product_id = \${update.value.product_id}
              \`
            })
          ]
        }
      })
    ]
  }),
  // This block can access:
  // ✅ process_each_update.output (previous sibling)
  // ✅ fetch_pending_updates (previous sibling)
  // ❌ CANNOT access validate_product, determine_pricing, calculate_bulk_pricing, etc. (inside Loop scope)
  new JavaScript("summarize_by_operation_type", {
    fn: ({ process_each_update, fetch_pending_updates }) => {
      const updates = fetch_pending_updates.output || [];
      const results = process_each_update.output || [];

      const summary = {
        bulk: { count: 0, totalQuantity: 0, avgPrice: 0, prices: [] },
        standard: { count: 0, totalQuantity: 0, avgPrice: 0, prices: [] }
      };

      // Note: In a real scenario, you'd need to reconstruct operation type from results
      // This is simplified for demonstration
      updates.forEach(update => {
        const isBulk = update.quantity_change > 100;
        const type = isBulk ? 'bulk' : 'standard';
        const finalPrice = isBulk ? update.unit_price * 0.95 : update.unit_price;

        summary[type].count += 1;
        summary[type].totalQuantity += update.quantity_change;
        summary[type].prices.push(finalPrice);
      });

      // Calculate averages
      ['bulk', 'standard'].forEach(type => {
        if (summary[type].prices.length > 0) {
          summary[type].avgPrice = summary[type].prices.reduce((a, b) => a + b, 0) / summary[type].prices.length;
        }
        delete summary[type].prices; // Remove helper array
      });

      return {
        summary,
        totalProcessed: updates.length,
        processedAt: new Date().toISOString()
      };
    }
  })
]);`,
    },
    {
        id: "searchProductsApi",
        metadata: {
            tags: ["validation", "sql-query", "data-transformation"],
            complexity: "simple",
            category: "positive",
            estimatedTokens: 380,
        },
        inputContext: {
            availableIntegrations: [
                {
                    name: "ProductDB",
                    id: "<postgres-product-db>",
                    type: "PostgreSQL",
                },
            ],
            integrationMetadata: [
                {
                    integrationId: "<postgres-product-db>",
                    metadata: {
                        databaseSchemaMetadata: {
                            tables: [
                                {
                                    type: "TABLE",
                                    name: "products",
                                    schema: "public",
                                    columns: [
                                        { name: "id", type: "int4" },
                                        { name: "name", type: "varchar" },
                                        { name: "price", type: "numeric" },
                                        { name: "category", type: "varchar" },
                                        { name: "stock", type: "int4" },
                                    ],
                                },
                            ],
                        },
                    },
                },
            ],
        },
        userPrompt: "Create a simple product search API that accepts search parameters. The API should accept searchTerm (for product name), minPrice, and maxPrice as inputs. Build a dynamic SQL query based on provided parameters - if searchTerm is provided, filter by product name (case-insensitive), if price range is provided, filter by price. Return matching products with their details.",
        code: `import {
  Api,
  JavaScript,
  PostgreSQL,
} from "@superblocksteam/library";

export default new Api("searchProductsApi", [
  // Build dynamic SQL based on input parameters
  new JavaScript("build_query", {
    fn: ({ searchTerm, minPrice, maxPrice }) => {
      // These parameters are automatically detected as API inputs
      let query = "SELECT id, name, price, category, stock FROM products";
      const conditions = [];

      // Add search term filter if provided
      if (searchTerm && searchTerm.trim()) {
        conditions.push(\`LOWER(name) LIKE LOWER('%\${searchTerm}%')\`);
      }

      // Add price filters if provided
      if (minPrice !== undefined && minPrice !== null) {
        conditions.push(\`price >= \${minPrice}\`);
      }
      if (maxPrice !== undefined && maxPrice !== null) {
        conditions.push(\`price <= \${maxPrice}\`);
      }

      // Combine conditions
      if (conditions.length > 0) {
        query += " WHERE " + conditions.join(" AND ");
      }

      query += " ORDER BY name ASC LIMIT 100";
      return query;
    }
  }),

  // Execute the dynamically built query
  new PostgreSQL("search_products", "<postgres-product-db>", {
    statement: ({ build_query }) => build_query.output
  }),

  // Format the response
  new JavaScript("format_response", {
    fn: ({ search_products, searchTerm, minPrice, maxPrice }) => ({
      products: search_products.output || [],
      count: (search_products.output || []).length,
      filters: {
        searchTerm: searchTerm || null,
        minPrice: minPrice || null,
        maxPrice: maxPrice || null
      }
    })
  })
]);

/*
 * How this API is called from the frontend:
 *
 * import { useApi } from "@superblocksteam/library";
 *
 * function ProductSearch() {
 *   const { run: runSearch } = useApi("searchProductsApi");
 *
 *   const handleSearch = async () => {
 *     const response = await runSearch({
 *       searchTerm: "laptop",
 *       minPrice: 500,
 *       maxPrice: 2000
 *     });
 *
 *     // The API returns the output of the last block directly
 *     const products = response?.products || [];
 *     const count = response?.count || 0;
 *   };
 * }
 *
 * The system automatically generates TypeScript types:
 *
 * interface SearchProductsApiInput {
 *   searchTerm?: any;
 *   minPrice?: any;
 *   maxPrice?: any;
 * }
 */`,
    },
];
export const NEGATIVE_EXAMPLES = [
    {
        id: "negative-scope-violation-sibling",
        metadata: {
            tags: ["error-scope-violation", "loop"],
            complexity: "simple",
            category: "negative",
            estimatedTokens: 300,
        },
        scenario: "Attempting to access blocks inside control flow from outside (sibling scope violation)",
        incorrectCode: `import { Api, Loop, JavaScript } from "@superblocksteam/library";

export default new Api("badScopeApi", [
  new JavaScript("fetch_data", {
    fn: () => [{ id: 1, value: 100 }, { id: 2, value: 200 }]
  }),
  new Loop("process_items", {
    over: ({ fetch_data }) => fetch_data.output,
    variables: { item: "current", index: "i" },
    blocks: [
      new JavaScript("transform_item", {
        fn: ({ current }) => ({ transformed: current.value.value * 2 })
      }),
      new JavaScript("validate_item", {
        fn: ({ transform_item }) => ({ valid: transform_item.output.transformed > 0 })
      })
    ]
  }),
  // ❌ ERROR: Cannot access blocks inside Loop from outside
  new JavaScript("bad_summary", {
    fn: ({ transform_item, validate_item }) => {
      // ❌ transform_item and validate_item are NOT in scope here!
      // They are nested inside process_items Loop
      return {
        transformed: transform_item.output, // ❌ WILL FAIL
        valid: validate_item.output          // ❌ WILL FAIL
      };
    }
  })
]);`,
        correctAlternative: `// ✅ CORRECT: Access the Loop's output, not its internal blocks
new JavaScript("correct_summary", {
  fn: ({ process_items, fetch_data }) => {
    // ✅ Can access process_items.output (equals last block's output in Loop)
    // ✅ Can access fetch_data (previous sibling)
    return {
      loopResults: process_items.output,
      itemCount: fetch_data.output.length
    };
  }
})`,
    },
    {
        id: "negative-error-scope-violation-branches",
        metadata: {
            tags: ["error-scope-violation", "conditional"],
            complexity: "simple",
            category: "negative",
            estimatedTokens: 280,
        },
        scenario: "Attempting to access blocks from different Conditional branches",
        incorrectCode: `import { Api, Conditional, JavaScript } from "@superblocksteam/library";

export default new Api("badConditionalScopeApi", [
  new JavaScript("get_user_role", {
    fn: ({ userRoleVar }) => userRoleVar  // API inputs don't need .value
  }),
  new Conditional("process_by_role", {
    if: {
      when: ({ get_user_role }) => get_user_role.output === "admin",
      then: [
        new JavaScript("admin_processing", {
          fn: () => ({ type: "admin", permissions: ["read", "write", "delete"] })
        })
      ]
    },
    elif: [{
      when: ({ get_user_role }) => get_user_role.output === "user",
      then: [
        new JavaScript("user_processing", {
          fn: () => ({ type: "user", permissions: ["read"] })
        })
      ]
    }],
    else: [
      new JavaScript("guest_processing", {
        fn: () => ({ type: "guest", permissions: [] })
      })
    ]
  }),
  // ❌ ERROR: Cannot access blocks from specific branches
  new JavaScript("bad_merge", {
    fn: ({ admin_processing, user_processing, guest_processing }) => {
      // ❌ Only ONE of these branches executed, so 2 of these 3 will be undefined/not in scope
      // You cannot access blocks from branches that didn't execute
      return {
        adminData: admin_processing.output,   // ❌ Only exists if admin branch ran
        userData: user_processing.output,     // ❌ Only exists if user branch ran
        guestData: guest_processing.output    // ❌ Only exists if else branch ran
      };
    }
  })
]);`,
        correctAlternative: `// ✅ CORRECT: Access the Conditional's output (from whichever branch executed)
new JavaScript("correct_merge", {
  fn: ({ process_by_role, get_user_role }) => {
    // ✅ Can access process_by_role.output (output from the executed branch)
    // ✅ Can access get_user_role (previous sibling)
    return {
      role: get_user_role.output,
      processedData: process_by_role.output
    };
  }
})`,
    },
    {
        id: "negative-variable-access",
        metadata: {
            tags: ["error-scope-violation", "variable-access", "loop"],
            complexity: "simple",
            category: "negative",
            estimatedTokens: 320,
        },
        scenario: "Incorrect variable access patterns (missing .value or .output)",
        incorrectCode: `import { Api, Loop, JavaScript, PostgreSQL } from "@superblocksteam/library";

export default new Api("badVariableAccessApi", [
  new JavaScript("get_orders", {
    fn: () => [{ id: 1, total: 100 }, { id: 2, total: 200 }]
  }),
  new Loop("process_orders", {
    over: ({ get_orders }) => get_orders.output,
    variables: { item: "order", index: "idx" },
    blocks: [
      new JavaScript("bad_access", {
        fn: ({ order, idx, get_orders }) => ({
          // ❌ Loop variables need .value
          orderId: order.id,              // ❌ Should be order.value.id
          index: idx,                     // ❌ Should be idx.value

          // ❌ Block outputs need .output
          totalOrders: get_orders.length  // ❌ Should be get_orders.output.length
        })
      }),
      new PostgreSQL("bad_query", "<postgres-integration-id>", {
        statement: ({ order }) => \`
          -- ❌ Missing .value for Loop variable
          SELECT * FROM order_items WHERE order_id = \${order.id}
          -- ✅ Should be: WHERE order_id = \${order.value.id}
        \`
      })
    ]
  }),
  new JavaScript("another_bad_access", {
    fn: ({ get_orders, process_orders }) => ({
      // ❌ Missing .output for block outputs
      orders: get_orders,           // ❌ Should be get_orders.output
      results: process_orders       // ❌ Should be process_orders.output
    })
  })
]);`,
        correctAlternative: `// ✅ CORRECT: Proper use of .value and .output
new Loop("process_orders", {
  over: ({ get_orders }) => get_orders.output,
  variables: { item: "order", index: "idx" },
  blocks: [
    new JavaScript("correct_access", {
      fn: ({ order, idx, get_orders }) => ({
        // ✅ Loop variables use .value
        orderId: order.value.id,
        index: idx.value,

        // ✅ Block outputs use .output
        totalOrders: get_orders.output.length
      })
    })
  ]
}),
new JavaScript("correct_summary", {
  fn: ({ get_orders, process_orders }) => ({
    // ✅ Block outputs use .output
    orders: get_orders.output,
    results: process_orders.output
  })
})`,
    },
    {
        id: "negative-forward-reference",
        metadata: {
            tags: ["error-scope-violation", "error-execution-order"],
            complexity: "simple",
            category: "negative",
            estimatedTokens: 250,
        },
        scenario: "Attempting to access blocks that execute later (forward reference)",
        incorrectCode: `import { Api, JavaScript, PostgreSQL } from "@superblocksteam/library";

export default new Api("badOrderingApi", [
  new JavaScript("bad_early_access", {
    fn: ({ fetch_users }) => {
      // ❌ fetch_users hasn't executed yet - it comes AFTER this block
      return fetch_users.output.map(u => u.id); // ❌ WILL FAIL
    }
  }),
  new PostgreSQL("fetch_users", "<postgres-integration-id>", {
    statement: () => \`SELECT id, name FROM users LIMIT 100\`
  }),
  new JavaScript("correct_late_access", {
    fn: ({ fetch_users }) => {
      // ✅ This works - fetch_users executed before this block
      return fetch_users.output.map(u => u.id);
    }
  })
]);`,
        explanation: "Blocks can ONLY access outputs from blocks that have already executed (previous siblings, ancestors). They cannot access blocks that come after them in the execution order.",
    },
    {
        id: "negative-deep-nesting",
        metadata: {
            tags: [
                "error-scope-violation",
                "nested-control-flow",
                "loop",
                "conditional",
            ],
            complexity: "simple",
            category: "negative",
            estimatedTokens: 280,
        },
        scenario: "Deeply nested scope violation (trying to access grandchild blocks)",
        incorrectCode: `import { Api, Loop, Conditional, JavaScript } from "@superblocksteam/library";

export default new Api("badDeepNestingApi", [
  new JavaScript("fetch_data", {
    fn: () => [{ id: 1, status: 'active' }, { id: 2, status: 'inactive' }]
  }),
  new Loop("process_items", {
    over: ({ fetch_data }) => fetch_data.output,
    variables: { item: "item", index: "i" },
    blocks: [
      new Conditional("check_status", {
        if: {
          when: ({ item }) => item.value.status === 'active',
          then: [
            new JavaScript("process_active", {
              fn: ({ item }) => ({ processed: true, id: item.value.id })
            })
          ]
        }
      })
    ]
  }),
  // ❌ ERROR: Cannot access blocks nested inside Loop > Conditional
  new JavaScript("bad_access_grandchild", {
    fn: ({ process_active }) => {
      // ❌ process_active is nested TWO levels deep (inside Loop, then inside Conditional)
      // It is NOT accessible from here
      return process_active.output; // ❌ WILL FAIL
    }
  })
]);`,
        correctAlternative: `// ✅ CORRECT: Access only the Loop's output
new JavaScript("correct_access", {
  fn: ({ process_items }) => {
    // ✅ process_items.output contains results from the last block of each iteration
    return {
      results: process_items.output,
      count: (process_items.output || []).length
    };
  }
})`,
    },
];
/**
 * Format a positive example as XML for LLM consumption
 */
export function formatPositiveExample(example) {
    // Build the input using the same helper that builds runtime prompts
    const input = buildApiPrompt({
        apiName: example.id,
        userPrompt: example.userPrompt,
        availableIntegrations: example.inputContext?.availableIntegrations,
        integrationMetadata: example.inputContext?.integrationMetadata,
        isEdit: false,
    });
    return `<example>
<input>
${input}
</input>
<output>
${example.code}
</output>
</example>`;
}
/**
 * Format a negative example as XML for LLM consumption
 */
export function formatNegativeExample(example) {
    let formatted = `<negative_example>
<scenario>${example.scenario}</scenario>
<incorrect_code>
${example.incorrectCode}
</incorrect_code>`;
    if (example.correctAlternative) {
        formatted += `
<correct_alternative>
${example.correctAlternative}
</correct_alternative>`;
    }
    if (example.explanation) {
        formatted += `
<explanation>
${example.explanation}
</explanation>`;
    }
    formatted += `
</negative_example>`;
    return formatted;
}
/**
 * Get all example metadata for selection purposes
 */
export function getAllExampleMetadata() {
    const positive = POSITIVE_EXAMPLES.map((ex) => ({
        id: ex.id,
        ...ex.metadata,
    }));
    const negative = NEGATIVE_EXAMPLES.map((ex) => ({
        id: ex.id,
        ...ex.metadata,
    }));
    return [...positive, ...negative];
}
/**
 * Get examples by IDs and format as XML
 */
export function formatExamplesByIds(ids) {
    if (ids.length === 0) {
        return "";
    }
    const idSet = new Set(ids);
    const examples = [];
    // Add positive examples
    for (const example of POSITIVE_EXAMPLES) {
        if (idSet.has(example.id)) {
            examples.push(formatPositiveExample(example));
        }
    }
    // Add negative examples
    for (const example of NEGATIVE_EXAMPLES) {
        if (idSet.has(example.id)) {
            examples.push(formatNegativeExample(example));
        }
    }
    if (examples.length === 0) {
        return "";
    }
    // Separate positive and negative
    const hasPositive = POSITIVE_EXAMPLES.some((ex) => idSet.has(ex.id));
    const hasNegative = NEGATIVE_EXAMPLES.some((ex) => idSet.has(ex.id));
    if (hasPositive && !hasNegative) {
        return `<examples>\n${examples.join("\n\n")}\n</examples>`;
    }
    else if (hasNegative && !hasPositive) {
        return `<negative_examples>\nThese examples demonstrate INCORRECT scope access patterns that will cause API failures. Do NOT follow these patterns.\n\n${examples.join("\n\n")}\n</negative_examples>`;
    }
    else {
        // Both positive and negative
        const positiveFormatted = POSITIVE_EXAMPLES.filter((ex) => idSet.has(ex.id))
            .map(formatPositiveExample)
            .join("\n\n");
        const negativeFormatted = NEGATIVE_EXAMPLES.filter((ex) => idSet.has(ex.id))
            .map(formatNegativeExample)
            .join("\n\n");
        return `<examples>\n${positiveFormatted}\n</examples>\n\n<negative_examples>\nThese examples demonstrate INCORRECT scope access patterns that will cause API failures. Do NOT follow these patterns.\n\n${negativeFormatted}\n</negative_examples>`;
    }
}
//# sourceMappingURL=examples.js.map