import { z } from 'zod';
import { createCommand, createSubcommand } from '../../../types';
import * as tui from '../../../tui';
import { createQueueAPIClient, getQueueApiOptions } from './util';
import { getCommand } from '../../../command-prefix';
import { ErrorCode } from '../../../errors';
import { createDestination, listDestinations, updateDestination, deleteDestination, DestinationSchema, DestinationAlreadyExistsError, } from '@agentuity/server';
function getConfigTarget(config) {
    if (!config || typeof config !== 'object') {
        return 'N/A';
    }
    if ('url' in config && typeof config.url === 'string') {
        return config.url;
    }
    if ('queue_id' in config && typeof config.queue_id === 'string') {
        return `queue:${config.queue_id}`;
    }
    if ('sandbox_id' in config && typeof config.sandbox_id === 'string') {
        return `sandbox:${config.sandbox_id}`;
    }
    if ('email_address' in config && typeof config.email_address === 'string') {
        return config.email_address;
    }
    return JSON.stringify(config);
}
const DestinationsListResponseSchema = z.object({
    destinations: z.array(z.object({
        id: z.string(),
        name: z.string(),
        description: z.string().nullable().optional(),
        destination_type: z.string(),
        target: z.string(),
        url: z.string().nullable().optional(),
        enabled: z.boolean(),
        created_at: z.string(),
    })),
});
const listDestinationsSubcommand = createSubcommand({
    name: 'list',
    aliases: ['ls'],
    description: 'List destinations for a queue',
    tags: ['read-only', 'fast', 'requires-auth'],
    requires: { auth: true },
    examples: [
        {
            command: getCommand('cloud queue destinations list my-queue'),
            description: 'List queue destinations',
        },
    ],
    schema: {
        args: z.object({
            queue_name: z.string().min(1).describe('Queue name'),
        }),
        response: DestinationsListResponseSchema,
    },
    idempotent: true,
    async handler(ctx) {
        const { args, options } = ctx;
        const client = await createQueueAPIClient(ctx);
        const destinations = await listDestinations(client, args.queue_name, getQueueApiOptions(ctx));
        if (!options.json) {
            if (destinations.length === 0) {
                tui.info('No destinations configured');
            }
            else {
                const tableData = destinations.map((d) => ({
                    ID: d.id,
                    Name: d.name,
                    Type: d.destination_type,
                    Target: getConfigTarget(d.config),
                    Enabled: d.enabled ? 'Yes' : 'No',
                    Created: new Date(d.created_at).toLocaleString(),
                }));
                tui.table(tableData, ['ID', 'Name', 'Type', 'Target', 'Enabled', 'Created']);
            }
        }
        return {
            destinations: destinations.map((d) => {
                const target = getConfigTarget(d.config);
                const url = d.config &&
                    typeof d.config === 'object' &&
                    'url' in d.config &&
                    typeof d.config.url === 'string'
                    ? d.config.url
                    : null;
                return {
                    id: d.id,
                    name: d.name,
                    description: d.description ?? null,
                    destination_type: d.destination_type,
                    target,
                    url,
                    enabled: d.enabled,
                    created_at: d.created_at,
                };
            }),
        };
    },
});
const createDestinationSubcommand = createSubcommand({
    name: 'create',
    description: 'Create a destination for a queue',
    tags: ['mutating', 'creates-resource', 'requires-auth'],
    requires: { auth: true },
    examples: [
        {
            command: getCommand('cloud queue destinations create my-queue --type http --name order-webhooks --url https://example.com/webhook'),
            description: 'Create an HTTP destination',
        },
        {
            command: getCommand('cloud queue destinations create my-queue --type queue --name retry-queue --queueId que_abc123'),
            description: 'Create a queue destination',
        },
    ],
    schema: {
        args: z.object({
            queue_name: z.string().min(1).describe('Queue name'),
        }),
        options: z.object({
            name: z.string().min(1).describe('Destination name'),
            description: z.string().optional().describe('Destination description'),
            type: z
                .enum(['http', 'url', 'webhook', 'queue', 'sandbox', 'email'])
                .default('http')
                .describe('Destination type'),
            // HTTP/Webhook options
            url: z.string().url().optional().describe('Webhook URL (for http/url/webhook types)'),
            method: z.string().optional().describe('HTTP method (default: POST)'),
            timeout: z.coerce.number().optional().describe('Request timeout in milliseconds'),
            // Queue options
            queueId: z.string().optional().describe('Target queue ID (for queue type)'),
            // Sandbox options
            sandboxId: z
                .string()
                .regex(/^sbx_[A-Za-z0-9_-]+$/, 'Sandbox ID must start with "sbx_"')
                .optional()
                .describe('Target sandbox ID (for sandbox type)'),
            // Email options
            email: z.string().email().optional().describe('Target email address (for email type)'),
        }),
        response: DestinationSchema,
    },
    async handler(ctx) {
        const { args, opts, options } = ctx;
        const client = await createQueueAPIClient(ctx);
        // Build config based on destination type
        let config = {};
        switch (opts.type) {
            case 'http':
            case 'webhook':
                if (!opts.url) {
                    tui.fatal('--url is required for http/webhook destinations', ErrorCode.INVALID_ARGUMENT);
                }
                config = {
                    url: opts.url,
                    method: opts.method || 'POST',
                    timeout_ms: opts.timeout ?? 30000,
                };
                break;
            case 'url':
                if (!opts.url) {
                    tui.fatal('--url is required for url destinations', ErrorCode.INVALID_ARGUMENT);
                }
                config = { url: opts.url };
                break;
            case 'queue':
                if (!opts.queueId) {
                    tui.fatal('--queue-id is required for queue destinations', ErrorCode.INVALID_ARGUMENT);
                }
                config = { queue_id: opts.queueId };
                break;
            case 'sandbox':
                if (!opts.sandboxId) {
                    tui.fatal('--sandbox-id is required for sandbox destinations', ErrorCode.INVALID_ARGUMENT);
                }
                config = { sandbox_id: opts.sandboxId };
                break;
            case 'email':
                if (!opts.email) {
                    tui.fatal('--email is required for email destinations', ErrorCode.INVALID_ARGUMENT);
                }
                config = { email_address: opts.email };
                break;
        }
        try {
            const destination = await createDestination(client, args.queue_name, {
                name: opts.name,
                description: opts.description,
                destination_type: opts.type,
                config,
                enabled: true,
            }, getQueueApiOptions(ctx));
            if (!options.json) {
                tui.success(`Created destination: ${destination.id}`);
                console.log(`  Name:   ${destination.name}`);
                console.log(`  Type:   ${destination.destination_type}`);
                console.log(`  Target: ${getConfigTarget(destination.config)}`);
            }
            return destination;
        }
        catch (error) {
            if (error instanceof DestinationAlreadyExistsError) {
                tui.fatal(`A destination already exists for queue "${args.queue_name}".`, ErrorCode.RESOURCE_ALREADY_EXISTS);
            }
            throw error;
        }
    },
});
const updateDestinationSubcommand = createSubcommand({
    name: 'update',
    description: 'Update a destination',
    tags: ['mutating', 'requires-auth'],
    requires: { auth: true },
    examples: [
        {
            command: getCommand('cloud queue destinations update my-queue qdest_abc123 --disabled'),
            description: 'Disable a destination',
        },
    ],
    schema: {
        args: z.object({
            queue_name: z.string().min(1).describe('Queue name'),
            destination_id: z.string().min(1).describe('Destination ID'),
        }),
        options: z.object({
            name: z.string().min(1).optional().describe('Destination name'),
            description: z.string().optional().describe('Destination description'),
            url: z.string().url().optional().describe('Webhook URL'),
            method: z.string().optional().describe('HTTP method'),
            timeout: z.coerce.number().optional().describe('Request timeout in milliseconds'),
            enabled: z.boolean().optional().describe('Enable the destination'),
            disabled: z.boolean().optional().describe('Disable the destination'),
        }),
        response: DestinationSchema,
    },
    async handler(ctx) {
        const { args, opts, options } = ctx;
        const client = await createQueueAPIClient(ctx);
        const updateParams = {};
        if (opts.name !== undefined)
            updateParams.name = opts.name;
        if (opts.description !== undefined)
            updateParams.description = opts.description || null;
        if (opts.url || opts.method || opts.timeout !== undefined) {
            updateParams.config = {};
            if (opts.url)
                updateParams.config.url = opts.url;
            if (opts.method)
                updateParams.config.method = opts.method;
            if (opts.timeout !== undefined)
                updateParams.config.timeout_ms = opts.timeout;
        }
        if (opts.enabled && opts.disabled) {
            tui.fatal('Cannot specify both --enabled and --disabled flags', ErrorCode.INVALID_ARGUMENT);
        }
        if (opts.enabled)
            updateParams.enabled = true;
        if (opts.disabled)
            updateParams.enabled = false;
        const destination = await updateDestination(client, args.queue_name, args.destination_id, updateParams, getQueueApiOptions(ctx));
        if (!options.json) {
            tui.success(`Updated destination: ${destination.id}`);
            console.log(`  Name:    ${destination.name}`);
            console.log(`  Target:  ${getConfigTarget(destination.config)}`);
            console.log(`  Enabled: ${destination.enabled ? 'Yes' : 'No'}`);
        }
        return destination;
    },
});
const DeleteDestinationResponseSchema = z.object({
    success: z.boolean(),
    queue_name: z.string(),
    destination_id: z.string(),
});
const deleteDestinationSubcommand = createSubcommand({
    name: 'delete',
    aliases: ['rm'],
    description: 'Delete a destination from a queue',
    tags: ['mutating', 'deletes-resource', 'requires-auth'],
    requires: { auth: true },
    examples: [
        {
            command: getCommand('cloud queue destinations delete my-queue dest-123'),
            description: 'Delete a destination',
        },
    ],
    schema: {
        args: z.object({
            queue_name: z.string().min(1).describe('Queue name'),
            destination_id: z.string().min(1).describe('Destination ID'),
        }),
        response: DeleteDestinationResponseSchema,
    },
    async handler(ctx) {
        const { args, options } = ctx;
        const client = await createQueueAPIClient(ctx);
        await deleteDestination(client, args.queue_name, args.destination_id, getQueueApiOptions(ctx));
        if (!options.json) {
            tui.success(`Deleted destination: ${args.destination_id}`);
        }
        return {
            success: true,
            queue_name: args.queue_name,
            destination_id: args.destination_id,
        };
    },
});
export const destinationsSubcommand = createCommand({
    name: 'destinations',
    aliases: ['dest'],
    description: 'Manage queue destinations',
    tags: ['requires-auth'],
    requires: { auth: true },
    examples: [
        {
            command: getCommand('cloud queue destinations list my-queue'),
            description: 'List destinations',
        },
        {
            command: getCommand('cloud queue destinations create my-queue --type http --name order-webhooks --url https://example.com/webhook'),
            description: 'Create an HTTP destination',
        },
    ],
    subcommands: [
        listDestinationsSubcommand,
        createDestinationSubcommand,
        updateDestinationSubcommand,
        deleteDestinationSubcommand,
    ],
});
export default destinationsSubcommand;
//# sourceMappingURL=destinations.js.map