import { env } from "~/env.mjs";
import { getOrCreateStripeCustomerIdForUser } from "~/server/stripe-webhook-handlers";
import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc";
import { z } from "zod";

export const stripeRouter = createTRPCRouter({
  createCheckoutSession: protectedProcedure
    .input(z.object({ billedAnnually: z.boolean() }))
    .mutation(
      async ({ ctx: { prisma, stripe, session, req, posthog }, input }) => {
        if (
          !stripe ||
          !env.STRIPE_ANNUAL_PRICE_ID ||
          !env.STRIPE_MONTHLY_PRICE_ID
        ) {
          throw new Error("Stripe env variables not set");
        }

        const customerId = await getOrCreateStripeCustomerIdForUser({
          prisma,
          stripe,
          userId: session.user?.id,
        });

        if (!customerId) {
          throw new Error("Could not create customer");
        }

        const baseUrl =
          env.NODE_ENV === "development"
            ? `http://${req.headers.host ?? "localhost:3000"}`
            : `https://${req.headers.host ?? env.NEXTAUTH_URL}`;

        const checkoutSession = await stripe.checkout.sessions.create({
          customer: customerId,
          client_reference_id: session.user?.id,
          payment_method_types: ["card"],
          allow_promotion_codes: true,
          mode: "subscription",
          line_items: [
            {
              price: input.billedAnnually
                ? env.STRIPE_ANNUAL_PRICE_ID
                : env.STRIPE_MONTHLY_PRICE_ID,
              quantity: 1,
            },
          ],
          success_url: `${baseUrl}/videos?checkoutSuccess=true`,
          cancel_url: `${baseUrl}/videos?checkoutCanceled=true`,
          subscription_data: {
            metadata: {
              userId: session.user?.id,
            },
          },
        });

        if (!checkoutSession) {
          throw new Error("Could not create checkout session");
        }

        posthog?.capture({
          distinctId: session.user.id,
          event: "visiting checkout page",
          properties: {
            billingCycle: input.billedAnnually ? "annual" : "monthly",
          },
        });
        void posthog?.shutdownAsync();

        return { checkoutUrl: checkoutSession.url };
      }
    ),
  createBillingPortalSession: protectedProcedure.mutation(
    async ({ ctx: { stripe, session, prisma, req, posthog } }) => {
      if (!stripe) {
        throw new Error("Stripe env variables not set");
      }

      const customerId = await getOrCreateStripeCustomerIdForUser({
        prisma,
        stripe,
        userId: session.user?.id,
      });

      if (!customerId) {
        throw new Error("Could not create customer");
      }

      const baseUrl =
        env.NODE_ENV === "development"
          ? `http://${req.headers.host ?? "localhost:3000"}`
          : `https://${req.headers.host ?? env.NEXTAUTH_URL}`;

      const stripeBillingPortalSession =
        await stripe.billingPortal.sessions.create({
          customer: customerId,
          return_url: `${baseUrl}/videos`,
        });

      if (!stripeBillingPortalSession) {
        throw new Error("Could not create billing portal session");
      }

      posthog?.capture({
        distinctId: session.user.id,
        event: "visiting billing portal page",
        properties: {
          stripeSubscriptionStatus: session.user.stripeSubscriptionStatus,
        },
      });
      void posthog?.shutdownAsync();

      return { billingPortalUrl: stripeBillingPortalSession.url };
    }
  ),
});
