import { Resource } from "../resource.js";
import { logger } from "../util/logger.js";
import { createStripeClient, handleStripeDeleteError, isStripeConflictError, } from "./client.js";
/**
 * Create and manage Stripe webhook endpoints
 *
 * @example
 * // Create a basic webhook for payment events
 * const paymentWebhook = await WebhookEndpoint("payment-webhook", {
 *   url: "https://api.example.com/stripe/payments",
 *   enabledEvents: [
 *     "payment_intent.succeeded",
 *     "payment_intent.payment_failed"
 *   ],
 *   description: "Webhook for payment notifications"
 * });
 *
 * @example
 * // Create a webhook for subscription management
 * const subscriptionWebhook = await WebhookEndpoint("subscription-webhook", {
 *   url: "https://api.example.com/stripe/subscriptions",
 *   enabledEvents: [
 *     "customer.subscription.created",
 *     "customer.subscription.updated",
 *     "customer.subscription.deleted",
 *     "invoice.payment_succeeded",
 *     "invoice.payment_failed"
 *   ],
 *   description: "Webhook for subscription lifecycle events"
 * });
 *
 * @example
 * // Create a webhook for Connect platform events
 * const connectWebhook = await WebhookEndpoint("connect-webhook", {
 *   url: "https://api.example.com/stripe/connect",
 *   enabledEvents: [
 *     "account.updated",
 *     "account.application.deauthorized",
 *     "payout.created",
 *     "payout.failed"
 *   ],
 *   connect: true,
 *   metadata: {
 *     platform: "connect",
 *     environment: "production"
 *   }
 * });
 */
export const WebhookEndpoint = Resource("stripe::WebhookEndpoint", async function (_id, props) {
    const adopt = props.adopt ?? this.scope.adopt;
    const stripe = await createStripeClient({ apiKey: props.apiKey });
    if (this.phase === "delete") {
        try {
            // Get the webhook ID from the stored output
            if (this.phase === "delete" && this.output?.id) {
                await stripe.webhookEndpoints.del(this.output.id);
            }
        }
        catch (error) {
            handleStripeDeleteError(error, "WebhookEndpoint", this.output?.id);
        }
        return this.destroy();
    }
    try {
        let webhook;
        if (this.phase === "update" && this.output?.id) {
            // Update existing webhook
            const updateParams = {
                url: props.url,
                enabled_events: props.enabledEvents,
                description: props.description,
                disabled: props.active === false,
                metadata: props.metadata,
            };
            webhook = await stripe.webhookEndpoints.update(this.output.id, updateParams);
        }
        else {
            // Create new webhook
            const createParams = {
                url: props.url,
                enabled_events: props.enabledEvents,
                description: props.description,
                metadata: props.metadata,
            };
            try {
                try {
                    webhook = await stripe.webhookEndpoints.create(createParams);
                }
                catch (error) {
                    if (isStripeConflictError(error) && adopt) {
                        const existingWebhooks = await stripe.webhookEndpoints.list({
                            limit: 100,
                        });
                        const existingWebhook = existingWebhooks.data.find((w) => w.url === props.url);
                        if (existingWebhook) {
                            const updateParams = {
                                url: props.url,
                                enabled_events: props.enabledEvents,
                                description: props.description,
                                metadata: props.metadata,
                            };
                            webhook = await stripe.webhookEndpoints.update(existingWebhook.id, updateParams);
                        }
                        else {
                            throw error;
                        }
                    }
                    else {
                        throw error;
                    }
                }
            }
            catch (error) {
                if (isStripeConflictError(error) && adopt) {
                    const existingWebhooks = await stripe.webhookEndpoints.list({
                        limit: 100,
                    });
                    const existingWebhook = existingWebhooks.data.find((w) => w.url === props.url);
                    if (existingWebhook) {
                        const updateParams = {
                            url: props.url,
                            enabled_events: props.enabledEvents,
                            description: props.description,
                            metadata: props.metadata,
                        };
                        webhook = await stripe.webhookEndpoints.update(existingWebhook.id, updateParams);
                    }
                    else {
                        throw error;
                    }
                }
                else {
                    throw error;
                }
            }
            // For connect parameter, need to handle it separately if it exists
            if (props.connect !== undefined) {
                // Note: connect is specified at creation time and cannot be updated
                logger.log("Note: 'connect' parameter will be applied at creation time only");
            }
        }
        // Store the secret if available
        let secret = "";
        if (webhook.secret) {
            secret = webhook.secret;
        }
        else if (this.phase === "update" && this.output?.secret) {
            secret = this.output.secret;
        }
        return {
            id: webhook.id,
            url: webhook.url,
            enabledEvents: webhook.enabled_events,
            description: webhook.description || undefined,
            active: webhook.status === "enabled",
            apiVersion: webhook.api_version || undefined,
            // connect: !!webhook.connect,
            metadata: webhook.metadata || undefined,
            secret: secret,
            application: webhook.application || undefined,
            createdAt: webhook.created,
            livemode: webhook.livemode,
            updatedAt: webhook.created, // Using created timestamp as updated
            status: webhook.status,
        };
    }
    catch (error) {
        logger.error("Error creating/updating webhook:", error);
        throw error;
    }
});
//# sourceMappingURL=webhook.js.map