import { Resource } from "../resource.js";
import { logger } from "../util/logger.js";
import { createStripeClient, handleStripeDeleteError, isStripeConflictError, } from "./client.js";
/**
 * Create and manage Stripe coupons for discounts
 *
 * @example
 * // Create a percentage-based coupon
 * const percentageCoupon = await Coupon("summer-sale", {
 *   id: "SUMMER25",
 *   duration: "once",
 *   percentOff: 25,
 *   name: "Summer Sale 25% Off",
 *   maxRedemptions: 1000,
 *   metadata: {
 *     campaign: "summer_2024",
 *     type: "seasonal"
 *   }
 * });
 *
 * @example
 * // Create a fixed amount coupon
 * const fixedAmountCoupon = await Coupon("new-customer", {
 *   id: "WELCOME10",
 *   duration: "once",
 *   amountOff: 1000,
 *   currency: "usd",
 *   name: "Welcome $10 Off",
 *   metadata: {
 *     type: "welcome",
 *     target: "new_customers"
 *   }
 * });
 *
 * @example
 * // Create a repeating coupon for subscriptions
 * const subscriptionCoupon = await Coupon("loyal-customer", {
 *   id: "LOYAL15",
 *   duration: "repeating",
 *   durationInMonths: 6,
 *   percentOff: 15,
 *   name: "Loyal Customer 15% Off",
 *   metadata: {
 *     type: "loyalty",
 *     tier: "premium"
 *   }
 * });
 */
export const Coupon = Resource("stripe::Coupon", async function (_id, props) {
    const adopt = props.adopt ?? this.scope.adopt;
    const stripe = await createStripeClient({ apiKey: props.apiKey });
    if (this.phase === "delete") {
        try {
            if (this.output?.id) {
                await stripe.coupons.del(this.output.id);
            }
        }
        catch (error) {
            handleStripeDeleteError(error, "Coupon", this.output?.id);
        }
        return this.destroy();
    }
    try {
        let coupon;
        if (this.phase === "update" && this.output?.id) {
            coupon = await stripe.coupons.update(this.output.id, {
                name: props.name,
                metadata: props.metadata,
            });
        }
        else {
            const createParams = {
                duration: props.duration,
                name: props.name,
                metadata: props.metadata,
            };
            if (props.id) {
                createParams.id = props.id;
            }
            if (props.amountOff !== undefined) {
                createParams.amount_off = props.amountOff;
            }
            if (props.currency) {
                createParams.currency = props.currency;
            }
            if (props.durationInMonths !== undefined) {
                createParams.duration_in_months = props.durationInMonths;
            }
            if (props.maxRedemptions !== undefined) {
                createParams.max_redemptions = props.maxRedemptions;
            }
            if (props.percentOff !== undefined) {
                createParams.percent_off = props.percentOff;
            }
            if (props.redeemBy !== undefined) {
                createParams.redeem_by = props.redeemBy;
            }
            try {
                try {
                    coupon = await stripe.coupons.create(createParams);
                }
                catch (error) {
                    if (isStripeConflictError(error) && adopt) {
                        if (props.id) {
                            const existingCoupon = await stripe.coupons.retrieve(props.id);
                            const updateParams = {
                                metadata: props.metadata,
                                name: props.name,
                            };
                            coupon = await stripe.coupons.update(existingCoupon.id, updateParams);
                        }
                        else {
                            throw error;
                        }
                    }
                    else {
                        throw error;
                    }
                }
            }
            catch (error) {
                if (isStripeConflictError(error) && adopt) {
                    if (props.id) {
                        const existingCoupon = await stripe.coupons.retrieve(props.id);
                        const updateParams = {
                            metadata: props.metadata,
                            name: props.name,
                        };
                        coupon = await stripe.coupons.update(existingCoupon.id, updateParams);
                    }
                    else {
                        throw error;
                    }
                }
                else {
                    throw error;
                }
            }
        }
        return {
            id: coupon.id,
            object: coupon.object,
            duration: coupon.duration,
            amountOff: coupon.amount_off || undefined,
            currency: coupon.currency || undefined,
            durationInMonths: coupon.duration_in_months || undefined,
            maxRedemptions: coupon.max_redemptions || undefined,
            name: coupon.name || undefined,
            percentOff: coupon.percent_off || undefined,
            redeemBy: coupon.redeem_by || undefined,
            timesRedeemed: coupon.times_redeemed || undefined,
            valid: coupon.valid,
            metadata: coupon.metadata || undefined,
            created: coupon.created,
            livemode: coupon.livemode,
        };
    }
    catch (error) {
        logger.error("Error creating/updating coupon:", error);
        throw error;
    }
});
//# sourceMappingURL=coupon.js.map