import { H as HttpError } from "./http-error-RJXCPZV2.js";
import { p as prisma } from "./index-Cw1zbw54.js";
import Stripe from "stripe";
import { z } from "zod";
const stripeOAuthTokenSchema = z.object({
  access_token: z.string().optional(),
  scope: z.string().optional(),
  livemode: z.boolean().optional(),
  token_type: z.literal("bearer").optional(),
  refresh_token: z.string().optional(),
  stripe_user_id: z.string().optional(),
  stripe_publishable_key: z.string().optional()
});
stripeOAuthTokenSchema.extend({
  default_currency: z.string()
});
const stripePrivateKey = process.env.STRIPE_PRIVATE_KEY || "";
const stripe = new Stripe(stripePrivateKey, {
  apiVersion: "2020-08-27"
});
const stripe$1 = stripe;
async function getStripeCustomerIdFromUserId(userId) {
  const user = await prisma.user.findUnique({
    where: {
      id: userId
    },
    select: {
      email: true,
      name: true,
      metadata: true
    }
  });
  if (!user?.email)
    throw new HttpError({ statusCode: 404, message: "User email not found" });
  const customerId = await getStripeCustomerId(user);
  return customerId;
}
async function getStripeCustomerId(user) {
  let customerId = null;
  if (user?.metadata && typeof user.metadata === "object" && "stripeCustomerId" in user.metadata) {
    customerId = (user?.metadata).stripeCustomerId;
  } else {
    const customersResponse = await stripe$1.customers.list({
      email: user.email,
      limit: 1
    });
    if (customersResponse.data[0]?.id) {
      customerId = customersResponse.data[0].id;
    } else {
      const customer = await stripe$1.customers.create({ email: user.email });
      customerId = customer.id;
    }
    await prisma.user.update({
      where: {
        email: user.email
      },
      data: {
        metadata: {
          ...user.metadata,
          stripeCustomerId: customerId
        }
      }
    });
  }
  return customerId;
}
async function retrieveOrCreateStripeCustomerByEmail(stripeAccountId, email, phoneNumber) {
  const customer = await stripe$1.customers.list(
    {
      email,
      limit: 1
    },
    {
      stripeAccount: stripeAccountId
    }
  );
  if (customer.data[0]?.id) {
    return customer.data[0];
  } else {
    const newCustomer = await stripe$1.customers.create(
      { email, phone: phoneNumber ?? void 0 },
      {
        stripeAccount: stripeAccountId
      }
    );
    return newCustomer;
  }
}
class StripeBillingService {
  constructor() {
    this.stripe = new Stripe(process.env.STRIPE_PRIVATE_KEY, {
      apiVersion: "2020-08-27"
    });
  }
  async createCustomer(args) {
    const { email, metadata } = args;
    const customer = await this.stripe.customers.create({
      email,
      metadata: {
        email,
        ...metadata
      }
    });
    return { stripeCustomerId: customer.id };
  }
  async createPaymentIntent(args) {
    const { customerId, amount, metadata } = args;
    const paymentIntent = await this.stripe.paymentIntents.create({
      customer: customerId,
      amount,
      currency: "usd",
      automatic_payment_methods: {
        enabled: true
      },
      metadata
    });
    return {
      id: paymentIntent.id,
      client_secret: paymentIntent.client_secret
    };
  }
  async createOneTimeCheckout(args) {
    const { priceId, quantity, successUrl, cancelUrl, metadata } = args;
    const session = await this.stripe.checkout.sessions.create({
      line_items: [{ price: priceId, quantity }],
      mode: "payment",
      success_url: successUrl,
      cancel_url: cancelUrl,
      metadata,
      invoice_creation: {
        enabled: true
      }
    });
    return {
      checkoutUrl: session.url,
      sessionId: session.id
    };
  }
  async createSubscriptionCheckout(args) {
    const {
      customerId,
      successUrl,
      cancelUrl,
      priceId,
      quantity,
      metadata,
      mode = "subscription",
      allowPromotionCodes = true,
      customerUpdate,
      automaticTax,
      discounts,
      subscriptionData
    } = args;
    const session = await this.stripe.checkout.sessions.create({
      customer: customerId,
      success_url: successUrl,
      cancel_url: cancelUrl,
      mode,
      metadata,
      line_items: [
        {
          price: priceId,
          quantity
        }
      ],
      allow_promotion_codes: allowPromotionCodes,
      customer_update: customerUpdate,
      automatic_tax: automaticTax,
      discounts,
      subscription_data: subscriptionData
    });
    return {
      checkoutUrl: session.url,
      sessionId: session.id
    };
  }
  async createPrice(args) {
    const { amount, currency, interval, productId, nickname, metadata } = args;
    const price = await this.stripe.prices.create({
      nickname,
      unit_amount: amount,
      currency,
      recurring: {
        interval
      },
      product: productId,
      metadata
    });
    return {
      priceId: price.id
    };
  }
  async handleSubscriptionCreation(subscriptionId) {
    throw new Error("Method not implemented.");
  }
  async handleSubscriptionCancel(subscriptionId) {
    await this.stripe.subscriptions.cancel(subscriptionId);
  }
  async handleSubscriptionUpdate(args) {
    const { subscriptionId, subscriptionItemId, membershipCount } = args;
    const subscription = await this.stripe.subscriptions.retrieve(subscriptionId);
    const subscriptionQuantity = subscription.items.data.find(
      (sub) => sub.id === subscriptionItemId
    )?.quantity;
    if (!subscriptionQuantity)
      throw new Error("Subscription not found");
    await this.stripe.subscriptions.update(subscriptionId, {
      items: [{ quantity: membershipCount, id: subscriptionItemId }]
    });
  }
  async handleEndTrial(subscriptionId) {
    const subscription = await this.stripe.subscriptions.retrieve(subscriptionId);
    if (subscription.status !== "trialing") {
      return;
    }
    await this.stripe.subscriptions.update(subscriptionId, {
      trial_end: "now"
    });
  }
  async checkoutSessionIsPaid(paymentId) {
    const checkoutSession = await this.stripe.checkout.sessions.retrieve(paymentId);
    return checkoutSession.payment_status === "paid";
  }
  async getSubscriptionStatus(subscriptionId) {
    const subscription = await this.stripe.subscriptions.retrieve(subscriptionId);
    if (!subscription || !subscription.status)
      return null;
    return subscription.status;
  }
  async getCheckoutSession(checkoutSessionId) {
    const checkoutSession = await this.stripe.checkout.sessions.retrieve(checkoutSessionId);
    return checkoutSession;
  }
  async getCustomer(customerId) {
    const customer = await this.stripe.customers.retrieve(customerId);
    return customer;
  }
  async getSubscriptions(customerId) {
    const subscriptions = await this.stripe.subscriptions.list({ customer: customerId });
    return subscriptions.data;
  }
  async updateCustomer(args) {
    const { customerId, email, userId } = args;
    const metadata = {};
    if (email)
      metadata.email = email;
    if (userId)
      metadata.userId = userId;
    await this.stripe.customers.update(customerId, { metadata });
  }
  async getPrice(priceId) {
    const price = await this.stripe.prices.retrieve(priceId);
    return price;
  }
}
export {
  StripeBillingService as S,
  getStripeCustomerIdFromUserId as g,
  retrieveOrCreateStripeCustomerByEmail as r,
  stripe$1 as s
};
