import { Resource } from "../resource.js";
import { logger } from "../util/logger.js";
import { createStripeClient, handleStripeDeleteError, isStripeConflictError, } from "./client.js";
/**
 * Create and manage Stripe promotion codes for coupons
 *
 * @example
 * // Create a basic promotion code
 * const basicPromoCode = await PromotionCode("summer-promo", {
 *   coupon: "SUMMER25",
 *   code: "SAVE25NOW",
 *   active: true,
 *   metadata: {
 *     campaign: "summer_sale",
 *     channel: "email"
 *   }
 * });
 *
 * @example
 * // Create a customer-specific promotion code
 * const customerPromoCode = await PromotionCode("vip-discount", {
 *   coupon: "VIP15",
 *   code: "VIP15OFF",
 *   customer: "cus_xyz123",
 *   maxRedemptions: 1,
 *   expiresAt: Math.floor(Date.now() / 1000) + 86400 * 30,
 *   metadata: {
 *     type: "vip_exclusive",
 *     tier: "gold"
 *   }
 * });
 *
 * @example
 * // Create a promotion code with restrictions
 * const restrictedPromoCode = await PromotionCode("first-time-buyer", {
 *   coupon: "WELCOME10",
 *   code: "FIRSTTIME10",
 *   restrictions: {
 *     firstTimeTransaction: true,
 *     minimumAmount: 5000,
 *     minimumAmountCurrency: "usd"
 *   },
 *   maxRedemptions: 1000,
 *   metadata: {
 *     campaign: "new_customer_acquisition",
 *     minimum_order: "50_usd"
 *   }
 * });
 */
export const PromotionCode = Resource("stripe::PromotionCode", 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.promotionCodes.update(this.output.id, { active: false });
            }
        }
        catch (error) {
            handleStripeDeleteError(error, "PromotionCode", this.output?.id);
        }
        return this.destroy();
    }
    try {
        let promotionCode;
        if (this.phase === "update" && this.output?.id) {
            const updateParams = {
                active: props.active,
                metadata: props.metadata,
            };
            promotionCode = await stripe.promotionCodes.update(this.output.id, updateParams);
        }
        else {
            const createParams = {
                coupon: props.coupon,
                code: props.code,
                active: props.active,
                customer: props.customer,
                expires_at: props.expiresAt,
                max_redemptions: props.maxRedemptions,
                metadata: props.metadata,
            };
            if (props.restrictions) {
                createParams.restrictions = {
                    first_time_transaction: props.restrictions.firstTimeTransaction,
                    minimum_amount: props.restrictions.minimumAmount,
                    minimum_amount_currency: props.restrictions.minimumAmountCurrency,
                };
            }
            try {
                promotionCode = await stripe.promotionCodes.create(createParams);
            }
            catch (error) {
                if (isStripeConflictError(error) && adopt) {
                    if (props.code) {
                        const existingPromotionCodes = await stripe.promotionCodes.list({
                            code: props.code,
                            limit: 1,
                        });
                        if (existingPromotionCodes.data.length > 0) {
                            const existingPromotionCode = existingPromotionCodes.data[0];
                            const updateParams = {
                                active: props.active,
                                metadata: props.metadata,
                            };
                            promotionCode = await stripe.promotionCodes.update(existingPromotionCode.id, updateParams);
                        }
                        else {
                            throw error;
                        }
                    }
                    else {
                        throw error;
                    }
                }
                else {
                    throw error;
                }
            }
        }
        return {
            id: promotionCode.id,
            object: promotionCode.object,
            coupon: typeof promotionCode.coupon === "string"
                ? promotionCode.coupon
                : promotionCode.coupon.id,
            code: promotionCode.code,
            active: promotionCode.active,
            customer: typeof promotionCode.customer === "string"
                ? promotionCode.customer
                : promotionCode.customer?.id,
            expiresAt: promotionCode.expires_at || undefined,
            maxRedemptions: promotionCode.max_redemptions || undefined,
            metadata: promotionCode.metadata || undefined,
            restrictions: promotionCode.restrictions
                ? {
                    firstTimeTransaction: promotionCode.restrictions.first_time_transaction || undefined,
                    minimumAmount: promotionCode.restrictions.minimum_amount || undefined,
                    minimumAmountCurrency: promotionCode.restrictions.minimum_amount_currency || undefined,
                }
                : undefined,
            created: promotionCode.created,
            livemode: promotionCode.livemode,
            timesRedeemed: promotionCode.times_redeemed,
        };
    }
    catch (error) {
        logger.error("Error creating/updating promotion code:", error);
        throw error;
    }
});
//# sourceMappingURL=promotion-code.js.map