import type { Prisma } from "@/generated/prisma/client";
import { db } from "@/lib/db";

type AsaasEvent = { id: string; event: string; payment?: { id: string; subscription?: string; value?: number; netValue?: number; billingType?: string; dueDate?: string; paymentDate?: string; clientPaymentDate?: string; invoiceUrl?: string; status?: string }; subscription?: { id: string; status?: string } };

const paymentStatus = (event: string) => event === "PAYMENT_RECEIVED" ? "RECEIVED" : event === "PAYMENT_CONFIRMED" ? "CONFIRMED" : event === "PAYMENT_OVERDUE" ? "OVERDUE" : event.includes("REFUND") || event.includes("CHARGEBACK") ? "REFUNDED" : event === "PAYMENT_DELETED" ? "CANCELLED" : "PENDING";

export async function processAsaasEvent(event: AsaasEvent) {
  if (!event.id || !event.event) throw new Error("Evento Asaas inválido");
  return db.$transaction(async (tx) => {
    const duplicate = await tx.billingWebhookEvent.findUnique({ where: { provider_externalId: { provider: "ASAAS", externalId: event.id } } });
    if (duplicate) return { duplicate: true };
    const externalSubscriptionId = event.payment?.subscription ?? event.subscription?.id;
    const subscription = externalSubscriptionId ? await tx.subscription.findUnique({ where: { externalSubscriptionId } }) : null;
    await tx.billingWebhookEvent.create({ data: { provider: "ASAAS", externalId: event.id, eventType: event.event, payload: event as unknown as Prisma.InputJsonValue } });
    if (!subscription) return { ignored: true };

    if (event.payment?.id) {
      await tx.payment.upsert({ where: { provider_externalId: { provider: "ASAAS", externalId: event.payment.id } }, update: { status: paymentStatus(event.event), netAmountCents: event.payment.netValue == null ? undefined : Math.round(event.payment.netValue * 100), paidAt: event.payment.paymentDate || event.payment.clientPaymentDate ? new Date(event.payment.paymentDate ?? event.payment.clientPaymentDate!) : undefined, invoiceUrl: event.payment.invoiceUrl }, create: { subscriptionId: subscription.id, provider: "ASAAS", externalId: event.payment.id, status: paymentStatus(event.event), amountCents: Math.round((event.payment.value ?? subscription.priceCents / 100) * 100), netAmountCents: event.payment.netValue == null ? null : Math.round(event.payment.netValue * 100), billingType: event.payment.billingType, dueAt: event.payment.dueDate ? new Date(`${event.payment.dueDate}T12:00:00Z`) : null, paidAt: event.payment.paymentDate || event.payment.clientPaymentDate ? new Date(event.payment.paymentDate ?? event.payment.clientPaymentDate!) : null, invoiceUrl: event.payment.invoiceUrl } });
    }

    if (["PAYMENT_CONFIRMED", "PAYMENT_RECEIVED"].includes(event.event)) await Promise.all([tx.subscription.update({ where: { id: subscription.id }, data: { status: "ACTIVE" } }), tx.tenant.update({ where: { id: subscription.tenantId }, data: { status: "ACTIVE" } })]);
    if (event.event === "PAYMENT_OVERDUE") await tx.subscription.update({ where: { id: subscription.id }, data: { status: "PAST_DUE" } });
    if (["SUBSCRIPTION_INACTIVATED", "SUBSCRIPTION_DELETED"].includes(event.event)) await tx.subscription.update({ where: { id: subscription.id }, data: { status: "CANCELLED", cancelledAt: new Date() } });
    return { processed: true };
  });
}
