import { z } from 'zod';
import { CredentialType } from '@bubblelab/shared-schemas';
// ============================================================================
// DATA SCHEMAS - Salesforce API Response Objects
// ============================================================================
export const SalesforceAccountSchema = z
    .object({
    Id: z.string().describe('Salesforce Account ID (18-character)'),
    Name: z.string().describe('Account name'),
    Type: z.string().nullable().optional().describe('Account type'),
    Industry: z.string().nullable().optional().describe('Industry category'),
    Website: z.string().nullable().optional().describe('Company website URL'),
    Phone: z.string().nullable().optional().describe('Primary phone number'),
    BillingCity: z
        .string()
        .nullable()
        .optional()
        .describe('Billing address city'),
    BillingState: z
        .string()
        .nullable()
        .optional()
        .describe('Billing address state'),
    BillingCountry: z
        .string()
        .nullable()
        .optional()
        .describe('Billing address country'),
    CreatedDate: z
        .string()
        .optional()
        .describe('ISO timestamp of record creation'),
    LastModifiedDate: z
        .string()
        .optional()
        .describe('ISO timestamp of last modification'),
})
    .passthrough()
    .describe('Salesforce Account object');
export const SalesforceContactSchema = z
    .object({
    Id: z.string().describe('Salesforce Contact ID (18-character)'),
    FirstName: z.string().nullable().optional().describe('Contact first name'),
    LastName: z.string().describe('Contact last name'),
    Email: z.string().nullable().optional().describe('Email address'),
    Phone: z.string().nullable().optional().describe('Phone number'),
    Title: z.string().nullable().optional().describe('Job title'),
    AccountId: z
        .string()
        .nullable()
        .optional()
        .describe('Related Account ID'),
    CreatedDate: z
        .string()
        .optional()
        .describe('ISO timestamp of record creation'),
    LastModifiedDate: z
        .string()
        .optional()
        .describe('ISO timestamp of last modification'),
})
    .passthrough()
    .describe('Salesforce Contact object');
export const SalesforceLeadSchema = z
    .object({
    Id: z.string().describe('Salesforce Lead ID (18-character)'),
    FirstName: z.string().nullable().optional().describe('Lead first name'),
    LastName: z.string().describe('Lead last name'),
    Email: z.string().nullable().optional().describe('Email address'),
    Phone: z.string().nullable().optional().describe('Phone number'),
    Company: z.string().describe('Company name'),
    Title: z.string().nullable().optional().describe('Job title'),
    Status: z.string().optional().describe('Lead status'),
    LeadSource: z.string().nullable().optional().describe('Lead source'),
    CreatedDate: z
        .string()
        .optional()
        .describe('ISO timestamp of record creation'),
    LastModifiedDate: z
        .string()
        .optional()
        .describe('ISO timestamp of last modification'),
})
    .passthrough()
    .describe('Salesforce Lead object');
export const SalesforceOpportunitySchema = z
    .object({
    Id: z.string().describe('Salesforce Opportunity ID (18-character)'),
    Name: z.string().describe('Opportunity name'),
    StageName: z.string().describe('Current stage'),
    Amount: z.number().nullable().optional().describe('Deal amount'),
    CloseDate: z.string().describe('Expected close date (YYYY-MM-DD)'),
    Probability: z.number().nullable().optional().describe('Win probability %'),
    AccountId: z
        .string()
        .nullable()
        .optional()
        .describe('Related Account ID'),
    CreatedDate: z
        .string()
        .optional()
        .describe('ISO timestamp of record creation'),
    LastModifiedDate: z
        .string()
        .optional()
        .describe('ISO timestamp of last modification'),
})
    .passthrough()
    .describe('Salesforce Opportunity object');
export const SalesforceUserInfoSchema = z
    .object({
    user_id: z.string().describe('Salesforce User ID'),
    organization_id: z.string().describe('Salesforce Organization ID'),
    username: z.string().describe('Username'),
    display_name: z.string().describe('Display name'),
    email: z.string().describe('Email address'),
    active: z.boolean().describe('Whether user is active'),
    user_type: z.string().describe('User type'),
})
    .describe('Salesforce user identity information');
export const SoqlQueryResultSchema = z
    .object({
    totalSize: z.number().describe('Total number of records matching the query'),
    done: z.boolean().describe('Whether all results have been returned'),
    nextRecordsUrl: z
        .string()
        .optional()
        .describe('URL to fetch next batch of records'),
    records: z.array(z.record(z.unknown())).describe('Query result records'),
})
    .describe('SOQL query result');
// ============================================================================
// CREDENTIALS FIELD - Required for all operations
// ============================================================================
const credentialsField = z
    .record(z.nativeEnum(CredentialType), z.string())
    .optional()
    .describe('Object mapping credential types to values (injected at runtime)');
// ============================================================================
// PARAMETERS SCHEMA - All Salesforce Operations
// ============================================================================
export const SalesforceParamsSchema = z.discriminatedUnion('operation', [
    // Execute SOQL Query
    z.object({
        operation: z
            .literal('query')
            .describe('Execute a SOQL query to retrieve records'),
        query: z
            .string()
            .min(1, 'SOQL query is required')
            .describe('SOQL query string (e.g., "SELECT Id, Name FROM Account LIMIT 10")'),
        credentials: credentialsField,
    }),
    // Get User Info
    z.object({
        operation: z
            .literal('get_user_info')
            .describe('Get information about the authenticated user'),
        credentials: credentialsField,
    }),
    // Describe sObject
    z.object({
        operation: z
            .literal('describe_sobject')
            .describe('Get metadata about an sObject type'),
        sobject_type: z
            .string()
            .min(1, 'sObject type is required')
            .describe('sObject API name (e.g., "Account", "Contact", "Lead")'),
        credentials: credentialsField,
    }),
    // List sObject Types
    z.object({
        operation: z
            .literal('list_sobjects')
            .describe('List all available sObject types in the org'),
        credentials: credentialsField,
    }),
    // Get Record
    z.object({
        operation: z.literal('get_record').describe('Retrieve a specific record by ID'),
        sobject_type: z
            .string()
            .min(1, 'sObject type is required')
            .describe('sObject API name (e.g., "Account", "Contact")'),
        record_id: z
            .string()
            .min(1, 'Record ID is required')
            .describe('Salesforce record ID (15 or 18 character)'),
        fields: z
            .array(z.string())
            .optional()
            .describe('Specific fields to retrieve (omit for all accessible fields)'),
        credentials: credentialsField,
    }),
    // Create Record
    z.object({
        operation: z
            .literal('create_record')
            .describe('Create a new record in Salesforce'),
        sobject_type: z
            .string()
            .min(1, 'sObject type is required')
            .describe('sObject API name (e.g., "Account", "Contact", "Lead")'),
        data: z
            .record(z.unknown())
            .describe('Field values for the new record'),
        credentials: credentialsField,
    }),
    // Update Record
    z.object({
        operation: z
            .literal('update_record')
            .describe('Update an existing record in Salesforce'),
        sobject_type: z
            .string()
            .min(1, 'sObject type is required')
            .describe('sObject API name (e.g., "Account", "Contact")'),
        record_id: z
            .string()
            .min(1, 'Record ID is required')
            .describe('Salesforce record ID (15 or 18 character)'),
        data: z
            .record(z.unknown())
            .describe('Field values to update'),
        credentials: credentialsField,
    }),
    // Delete Record
    z.object({
        operation: z
            .literal('delete_record')
            .describe('Delete a record from Salesforce'),
        sobject_type: z
            .string()
            .min(1, 'sObject type is required')
            .describe('sObject API name (e.g., "Account", "Contact")'),
        record_id: z
            .string()
            .min(1, 'Record ID is required')
            .describe('Salesforce record ID (15 or 18 character)'),
        credentials: credentialsField,
    }),
    // Search Records (SOSL)
    z.object({
        operation: z
            .literal('search')
            .describe('Execute a SOSL search across multiple objects'),
        search_query: z
            .string()
            .min(1, 'Search query is required')
            .describe('SOSL search string (e.g., "FIND {John} IN ALL FIELDS RETURNING Contact(Id, Name)")'),
        credentials: credentialsField,
    }),
    // Create Account
    z.object({
        operation: z.literal('create_account').describe('Create a new Account'),
        name: z.string().min(1, 'Account name is required').describe('Account name'),
        type: z.string().optional().describe('Account type'),
        industry: z.string().optional().describe('Industry category'),
        website: z.string().optional().describe('Company website URL'),
        phone: z.string().optional().describe('Primary phone number'),
        billing_city: z.string().optional().describe('Billing city'),
        billing_state: z.string().optional().describe('Billing state'),
        billing_country: z.string().optional().describe('Billing country'),
        additional_fields: z
            .record(z.unknown())
            .optional()
            .describe('Additional custom fields'),
        credentials: credentialsField,
    }),
    // Create Contact
    z.object({
        operation: z.literal('create_contact').describe('Create a new Contact'),
        first_name: z.string().optional().describe('First name'),
        last_name: z
            .string()
            .min(1, 'Last name is required')
            .describe('Last name'),
        email: z.string().email().optional().describe('Email address'),
        phone: z.string().optional().describe('Phone number'),
        title: z.string().optional().describe('Job title'),
        account_id: z.string().optional().describe('Related Account ID'),
        additional_fields: z
            .record(z.unknown())
            .optional()
            .describe('Additional custom fields'),
        credentials: credentialsField,
    }),
    // Create Lead
    z.object({
        operation: z.literal('create_lead').describe('Create a new Lead'),
        first_name: z.string().optional().describe('First name'),
        last_name: z.string().min(1, 'Last name is required').describe('Last name'),
        company: z.string().min(1, 'Company is required').describe('Company name'),
        email: z.string().email().optional().describe('Email address'),
        phone: z.string().optional().describe('Phone number'),
        title: z.string().optional().describe('Job title'),
        status: z.string().optional().describe('Lead status'),
        lead_source: z.string().optional().describe('Lead source'),
        additional_fields: z
            .record(z.unknown())
            .optional()
            .describe('Additional custom fields'),
        credentials: credentialsField,
    }),
    // Create Opportunity
    z.object({
        operation: z
            .literal('create_opportunity')
            .describe('Create a new Opportunity'),
        name: z
            .string()
            .min(1, 'Opportunity name is required')
            .describe('Opportunity name'),
        stage_name: z
            .string()
            .min(1, 'Stage name is required')
            .describe('Sales stage'),
        close_date: z
            .string()
            .min(1, 'Close date is required')
            .describe('Expected close date (YYYY-MM-DD)'),
        amount: z.number().optional().describe('Deal amount'),
        probability: z.number().min(0).max(100).optional().describe('Win probability'),
        account_id: z.string().optional().describe('Related Account ID'),
        additional_fields: z
            .record(z.unknown())
            .optional()
            .describe('Additional custom fields'),
        credentials: credentialsField,
    }),
    // List Accounts
    z.object({
        operation: z.literal('list_accounts').describe('List Account records'),
        limit: z
            .number()
            .int()
            .min(1)
            .max(2000)
            .optional()
            .default(100)
            .describe('Maximum records to return (1-2000)'),
        fields: z
            .array(z.string())
            .optional()
            .describe('Specific fields to retrieve'),
        where_clause: z
            .string()
            .optional()
            .describe('Optional WHERE clause filter (without WHERE keyword)'),
        order_by: z
            .string()
            .optional()
            .describe('Optional ORDER BY clause (without ORDER BY keyword)'),
        credentials: credentialsField,
    }),
    // List Contacts
    z.object({
        operation: z.literal('list_contacts').describe('List Contact records'),
        limit: z
            .number()
            .int()
            .min(1)
            .max(2000)
            .optional()
            .default(100)
            .describe('Maximum records to return (1-2000)'),
        fields: z
            .array(z.string())
            .optional()
            .describe('Specific fields to retrieve'),
        where_clause: z
            .string()
            .optional()
            .describe('Optional WHERE clause filter (without WHERE keyword)'),
        order_by: z
            .string()
            .optional()
            .describe('Optional ORDER BY clause (without ORDER BY keyword)'),
        account_id: z.string().optional().describe('Filter by Account ID'),
        credentials: credentialsField,
    }),
    // List Leads
    z.object({
        operation: z.literal('list_leads').describe('List Lead records'),
        limit: z
            .number()
            .int()
            .min(1)
            .max(2000)
            .optional()
            .default(100)
            .describe('Maximum records to return (1-2000)'),
        fields: z
            .array(z.string())
            .optional()
            .describe('Specific fields to retrieve'),
        where_clause: z
            .string()
            .optional()
            .describe('Optional WHERE clause filter (without WHERE keyword)'),
        order_by: z
            .string()
            .optional()
            .describe('Optional ORDER BY clause (without ORDER BY keyword)'),
        status: z.string().optional().describe('Filter by lead status'),
        credentials: credentialsField,
    }),
    // List Opportunities
    z.object({
        operation: z
            .literal('list_opportunities')
            .describe('List Opportunity records'),
        limit: z
            .number()
            .int()
            .min(1)
            .max(2000)
            .optional()
            .default(100)
            .describe('Maximum records to return (1-2000)'),
        fields: z
            .array(z.string())
            .optional()
            .describe('Specific fields to retrieve'),
        where_clause: z
            .string()
            .optional()
            .describe('Optional WHERE clause filter (without WHERE keyword)'),
        order_by: z
            .string()
            .optional()
            .describe('Optional ORDER BY clause (without ORDER BY keyword)'),
        account_id: z.string().optional().describe('Filter by Account ID'),
        stage_name: z.string().optional().describe('Filter by stage'),
        credentials: credentialsField,
    }),
]);
// ============================================================================
// RESULT SCHEMA - All Salesforce Operation Results
// ============================================================================
export const SalesforceResultSchema = z.discriminatedUnion('operation', [
    // Query Result
    z.object({
        operation: z.literal('query'),
        success: z.boolean().describe('Whether the operation succeeded'),
        result: SoqlQueryResultSchema.optional().describe('Query results'),
        error: z.string().describe('Error message if operation failed'),
    }),
    // Get User Info Result
    z.object({
        operation: z.literal('get_user_info'),
        success: z.boolean().describe('Whether the operation succeeded'),
        user_info: SalesforceUserInfoSchema.optional().describe('User information'),
        error: z.string().describe('Error message if operation failed'),
    }),
    // Describe sObject Result
    z.object({
        operation: z.literal('describe_sobject'),
        success: z.boolean().describe('Whether the operation succeeded'),
        metadata: z
            .object({
            name: z.string(),
            label: z.string(),
            labelPlural: z.string(),
            fields: z.array(z.object({
                name: z.string(),
                label: z.string(),
                type: z.string(),
                required: z.boolean(),
                createable: z.boolean(),
                updateable: z.boolean(),
                picklistValues: z
                    .array(z.object({ value: z.string(), label: z.string() }))
                    .optional(),
            })),
        })
            .optional()
            .describe('sObject metadata'),
        error: z.string().describe('Error message if operation failed'),
    }),
    // List sObjects Result
    z.object({
        operation: z.literal('list_sobjects'),
        success: z.boolean().describe('Whether the operation succeeded'),
        sobjects: z
            .array(z.object({
            name: z.string(),
            label: z.string(),
            queryable: z.boolean(),
            createable: z.boolean(),
            updateable: z.boolean(),
            deletable: z.boolean(),
        }))
            .optional()
            .describe('List of sObject types'),
        error: z.string().describe('Error message if operation failed'),
    }),
    // Get Record Result
    z.object({
        operation: z.literal('get_record'),
        success: z.boolean().describe('Whether the operation succeeded'),
        record: z
            .record(z.unknown())
            .optional()
            .describe('Retrieved record data'),
        error: z.string().describe('Error message if operation failed'),
    }),
    // Create Record Result
    z.object({
        operation: z.literal('create_record'),
        success: z.boolean().describe('Whether the operation succeeded'),
        id: z.string().optional().describe('ID of the created record'),
        errors: z.array(z.string()).optional().describe('Validation errors'),
        error: z.string().describe('Error message if operation failed'),
    }),
    // Update Record Result
    z.object({
        operation: z.literal('update_record'),
        success: z.boolean().describe('Whether the operation succeeded'),
        error: z.string().describe('Error message if operation failed'),
    }),
    // Delete Record Result
    z.object({
        operation: z.literal('delete_record'),
        success: z.boolean().describe('Whether the operation succeeded'),
        error: z.string().describe('Error message if operation failed'),
    }),
    // Search Result
    z.object({
        operation: z.literal('search'),
        success: z.boolean().describe('Whether the operation succeeded'),
        searchRecords: z
            .array(z.record(z.unknown()))
            .optional()
            .describe('Search results'),
        error: z.string().describe('Error message if operation failed'),
    }),
    // Create Account Result
    z.object({
        operation: z.literal('create_account'),
        success: z.boolean().describe('Whether the operation succeeded'),
        account: SalesforceAccountSchema.optional().describe('Created account'),
        error: z.string().describe('Error message if operation failed'),
    }),
    // Create Contact Result
    z.object({
        operation: z.literal('create_contact'),
        success: z.boolean().describe('Whether the operation succeeded'),
        contact: SalesforceContactSchema.optional().describe('Created contact'),
        error: z.string().describe('Error message if operation failed'),
    }),
    // Create Lead Result
    z.object({
        operation: z.literal('create_lead'),
        success: z.boolean().describe('Whether the operation succeeded'),
        lead: SalesforceLeadSchema.optional().describe('Created lead'),
        error: z.string().describe('Error message if operation failed'),
    }),
    // Create Opportunity Result
    z.object({
        operation: z.literal('create_opportunity'),
        success: z.boolean().describe('Whether the operation succeeded'),
        opportunity: SalesforceOpportunitySchema.optional().describe('Created opportunity'),
        error: z.string().describe('Error message if operation failed'),
    }),
    // List Accounts Result
    z.object({
        operation: z.literal('list_accounts'),
        success: z.boolean().describe('Whether the operation succeeded'),
        accounts: z
            .array(SalesforceAccountSchema)
            .optional()
            .describe('List of accounts'),
        total_size: z.number().optional().describe('Total matching records'),
        error: z.string().describe('Error message if operation failed'),
    }),
    // List Contacts Result
    z.object({
        operation: z.literal('list_contacts'),
        success: z.boolean().describe('Whether the operation succeeded'),
        contacts: z
            .array(SalesforceContactSchema)
            .optional()
            .describe('List of contacts'),
        total_size: z.number().optional().describe('Total matching records'),
        error: z.string().describe('Error message if operation failed'),
    }),
    // List Leads Result
    z.object({
        operation: z.literal('list_leads'),
        success: z.boolean().describe('Whether the operation succeeded'),
        leads: z.array(SalesforceLeadSchema).optional().describe('List of leads'),
        total_size: z.number().optional().describe('Total matching records'),
        error: z.string().describe('Error message if operation failed'),
    }),
    // List Opportunities Result
    z.object({
        operation: z.literal('list_opportunities'),
        success: z.boolean().describe('Whether the operation succeeded'),
        opportunities: z
            .array(SalesforceOpportunitySchema)
            .optional()
            .describe('List of opportunities'),
        total_size: z.number().optional().describe('Total matching records'),
        error: z.string().describe('Error message if operation failed'),
    }),
]);
//# sourceMappingURL=salesforce.schema.js.map