import { z } from 'zod';
import type { AirtableClient } from '../clients/airtable.js';
import { BaseIdSchema, WebhookIdSchema } from '../types/index.js';

/**
 * Webhooks Tools
 * 
 * Tools for managing webhooks in Airtable bases.
 * Webhooks allow you to receive real-time notifications when data changes.
 */

export function getTools(client: AirtableClient) {
  return [
    // ========================================================================
    // List Webhooks
    // ========================================================================
    {
      name: 'airtable_list_webhooks',
      description:
        'List all webhooks configured for a base. Returns webhook IDs, expiration times, and specifications.',
      inputSchema: z.object({
        baseId: BaseIdSchema.describe('The ID of the base (starts with app).'),
      }),
      execute: async (args: { baseId: string }) => {
        const webhooks = await client.listWebhooks(args.baseId as any);
        return {
          webhooks: webhooks.map((w) => ({
            id: w.id,
            expirationTime: w.expirationTime,
            hasSpecification: !!w.specification,
          })),
          count: webhooks.length,
        };
      },
    },

    // ========================================================================
    // Create Webhook
    // ========================================================================
    {
      name: 'airtable_create_webhook',
      description:
        'Create a new webhook to receive notifications about data changes. Specify what data types to watch (tableData, tableFields, tableMetadata) and optional filters.',
      inputSchema: z.object({
        baseId: BaseIdSchema.describe('The ID of the base (starts with app).'),
        notificationUrl: z
          .string()
          .url()
          .describe('HTTPS URL where webhook payloads will be sent.'),
        dataTypes: z
          .array(z.enum(['tableData', 'tableFields', 'tableMetadata']))
          .min(1)
          .describe(
            'Types of changes to watch: tableData (record changes), tableFields (field schema changes), tableMetadata (table metadata changes).'
          ),
        tableIds: z
          .array(z.string())
          .optional()
          .describe(
            'Optional: Specific table IDs to watch. Omit to watch all tables.'
          ),
        watchDataInFieldIds: z
          .array(z.string())
          .optional()
          .describe('Optional: Specific field IDs to watch for data changes.'),
        includeCellValuesInFieldIds: z
          .union([z.array(z.string()), z.literal('all')])
          .optional()
          .describe(
            'Field IDs to include cell values for in webhook payloads, or "all" for all fields.'
          ),
        includePreviousCellValues: z
          .boolean()
          .optional()
          .describe('Include previous cell values in change notifications.'),
      }),
      execute: async (args: {
        baseId: string;
        notificationUrl: string;
        dataTypes: Array<'tableData' | 'tableFields' | 'tableMetadata'>;
        tableIds?: string[];
        watchDataInFieldIds?: string[];
        includeCellValuesInFieldIds?: string[] | 'all';
        includePreviousCellValues?: boolean;
      }) => {
        const specification = {
          options: {
            filters: {
              dataTypes: args.dataTypes,
              ...(args.watchDataInFieldIds && {
                watchDataInFieldIds: args.watchDataInFieldIds,
              }),
              ...(args.tableIds && { recordChangeScope: args.tableIds.join(',') }),
            },
            ...(args.includeCellValuesInFieldIds ||
            args.includePreviousCellValues !== undefined
              ? {
                  includes: {
                    ...(args.includeCellValuesInFieldIds && {
                      includeCellValuesInFieldIds: args.includeCellValuesInFieldIds,
                    }),
                    ...(args.includePreviousCellValues !== undefined && {
                      includePreviousCellValues: args.includePreviousCellValues,
                    }),
                  },
                }
              : {}),
          },
        };

        const webhook = await client.createWebhook(
          args.baseId as any,
          args.notificationUrl,
          specification
        );
        return webhook;
      },
    },

    // ========================================================================
    // Delete Webhook
    // ========================================================================
    {
      name: 'airtable_delete_webhook',
      description:
        'Delete a webhook. Once deleted, no further notifications will be sent.',
      inputSchema: z.object({
        baseId: BaseIdSchema.describe('The ID of the base (starts with app).'),
        webhookId: WebhookIdSchema.describe('The ID of the webhook to delete.'),
      }),
      execute: async (args: { baseId: string; webhookId: string }) => {
        await client.deleteWebhook(args.baseId as any, args.webhookId as any);
        return {
          success: true,
          webhookId: args.webhookId,
          message: 'Webhook deleted successfully',
        };
      },
    },

    // ========================================================================
    // Refresh Webhook
    // ========================================================================
    {
      name: 'airtable_refresh_webhook',
      description:
        'Refresh a webhook to extend its expiration time. Webhooks expire after 7 days if not refreshed.',
      inputSchema: z.object({
        baseId: BaseIdSchema.describe('The ID of the base (starts with app).'),
        webhookId: WebhookIdSchema.describe('The ID of the webhook to refresh.'),
      }),
      execute: async (args: { baseId: string; webhookId: string }) => {
        const webhook = await client.refreshWebhook(
          args.baseId as any,
          args.webhookId as any
        );
        return {
          webhook,
          expirationTime: webhook.expirationTime,
          message: 'Webhook refreshed successfully',
        };
      },
    },

    // ========================================================================
    // List Webhook Payloads (Note)
    // ========================================================================
    {
      name: 'airtable_list_webhook_payloads',
      description:
        'Note: Airtable sends webhook payloads to your notificationUrl. There is no API endpoint to retrieve historical payloads. This tool returns information about how to handle payloads.',
      inputSchema: z.object({
        info: z
          .boolean()
          .optional()
          .describe('Set to true to get information about webhook payloads.'),
      }),
      execute: async () => {
        return {
          note: 'Airtable does not provide an API to list webhook payloads.',
          documentation:
            'Webhook payloads are sent as POST requests to your notificationUrl.',
          payloadStructure: {
            baseTransactionNumber: 'Incremental counter for ordering changes',
            timestamp: 'ISO 8601 timestamp of the change',
            actionMetadata: {
              source: 'Source of the change (e.g., user, automation)',
            },
            changedTablesById: {
              '[tableId]': {
                createdRecordsById: 'Newly created records',
                changedRecordsById: 'Modified records',
                destroyedRecordIds: 'Deleted record IDs',
                createdFieldsById: 'Newly created fields',
                changedFieldsById: 'Modified fields',
                destroyedFieldIds: 'Deleted field IDs',
                changedViewsById: 'Modified views',
                createdViewsById: 'Newly created views',
                destroyedViewIds: 'Deleted view IDs',
              },
            },
          },
          recommendation:
            'Store webhook payloads in your application database and process them sequentially using baseTransactionNumber for ordering.',
        };
      },
    },

    // ========================================================================
    // Enable Webhook Notifications (Convenience)
    // ========================================================================
    {
      name: 'airtable_enable_webhook_notifications',
      description:
        'Convenience tool to quickly enable webhook notifications for all record changes in a base.',
      inputSchema: z.object({
        baseId: BaseIdSchema.describe('The ID of the base (starts with app).'),
        notificationUrl: z
          .string()
          .url()
          .describe('HTTPS URL where webhook payloads will be sent.'),
        tableIds: z
          .array(z.string())
          .optional()
          .describe('Optional: Specific tables to watch. Omit for all tables.'),
      }),
      execute: async (args: {
        baseId: string;
        notificationUrl: string;
        tableIds?: string[];
      }) => {
        const specification = {
          options: {
            filters: {
              dataTypes: ['tableData'] as const,
              ...(args.tableIds && { recordChangeScope: args.tableIds.join(',') }),
            },
            includes: {
              includeCellValuesInFieldIds: 'all' as const,
              includePreviousCellValues: true,
            },
          },
        };

        const webhook = await client.createWebhook(
          args.baseId as any,
          args.notificationUrl,
          specification
        );
        return {
          webhook,
          message: 'Webhook created for all record changes',
          expirationTime: webhook.expirationTime,
        };
      },
    },
  ];
}
