import { action } from "../_generated/server";
import { v } from "convex/values";
import { api } from "../_generated/api";

/**
 * Handle incoming Stripe webhook event
 * Verifies signature, processes event, and calls appropriate mutations
 * Phase 4: Billing
 *
 * Note: Stripe SDK doesn't run in Convex runtime. This action dispatches
 * to the appropriate mutations based on event type. Actual Stripe signature
 * verification and SDK calls stay in Next.js API routes.
 */
export const handleStripeEvent = action({
  args: {
    eventType: v.string(),
    eventData: v.any(),
  },
  handler: async (ctx, args) => {
    const { eventType, eventData } = args;

    switch (eventType) {
      case "customer.subscription.created": {
        const sub = eventData.object;
        await ctx.runMutation(api.billing.mutations.createSubscription, {
          userId: sub.metadata?.userId ?? "",
          stripeCustomerId: sub.customer,
          stripeSubscriptionId: sub.id,
          stripePriceId: sub.items?.data?.[0]?.price?.id ?? "",
          tierId: sub.metadata?.tierId ?? "free",
          status: sub.status,
          billingPeriod:
            sub.items?.data?.[0]?.price?.recurring?.interval ?? "month",
          currentPeriodEnd: sub.current_period_end * 1000,
          trialEndsAt: sub.trial_end ? sub.trial_end * 1000 : undefined,
        });
        break;
      }

      case "customer.subscription.updated": {
        const sub = eventData.object;
        // Look up the subscription by stripeSubscriptionId to get the Convex ID
        // For now, record the event in billing history
        await ctx.runMutation(api.billing.mutations.recordPayment, {
          customerId: sub.customer,
          subscriptionId: sub.id,
          event: eventType,
          amount: 0,
          currency: sub.currency ?? "usd",
          metadata: { stripeSubscriptionId: sub.id, status: sub.status },
        });
        break;
      }

      case "customer.subscription.deleted": {
        // Record cancellation event
        const sub = eventData.object;
        await ctx.runMutation(api.billing.mutations.recordPayment, {
          customerId: sub.customer,
          subscriptionId: sub.id,
          event: eventType,
          amount: 0,
          currency: sub.currency ?? "usd",
          metadata: { stripeSubscriptionId: sub.id, cancelledAt: Date.now() },
        });
        break;
      }

      case "invoice.payment_succeeded": {
        const invoice = eventData.object;
        await ctx.runMutation(api.billing.mutations.recordPayment, {
          customerId: invoice.customer,
          subscriptionId: invoice.subscription ?? undefined,
          invoiceId: invoice.id,
          event: eventType,
          amount: invoice.amount_paid ?? 0,
          currency: invoice.currency ?? "usd",
        });
        break;
      }

      case "invoice.payment_failed": {
        const invoice = eventData.object;
        await ctx.runMutation(api.billing.mutations.recordPayment, {
          customerId: invoice.customer,
          subscriptionId: invoice.subscription ?? undefined,
          invoiceId: invoice.id,
          event: eventType,
          amount: invoice.amount_due ?? 0,
          currency: invoice.currency ?? "usd",
          metadata: { attempt: invoice.attempt_count },
        });
        break;
      }

      case "charge.refunded": {
        const charge = eventData.object;
        const refund = charge.refunds?.data?.[0];
        if (refund) {
          await ctx.runMutation(api.billing.mutations.processRefund, {
            stripeRefundId: refund.id,
            stripePaymentIntentId: charge.payment_intent ?? undefined,
            customerId: charge.customer ?? "",
            amount: refund.amount,
            currency: refund.currency ?? "usd",
            reason: refund.reason ?? undefined,
          });
        }
        break;
      }

      default: {
        // Record unhandled events in billing history for audit
        await ctx.runMutation(api.billing.mutations.recordPayment, {
          customerId: eventData.object?.customer ?? "unknown",
          event: eventType,
          amount: 0,
          currency: "usd",
          metadata: { unhandled: true },
        });
        break;
      }
    }

    return { processed: true, eventType };
  },
});
