"use server";

import {auth} from "@/auth";
import {prisma} from "@/lib/db/prisma";
import {getTenantDb} from "@/lib/db/tenant";
import {revalidatePath} from "next/cache";

export type ActionResult = {success: boolean; error?: string; id?: string};

export async function createInvoiceForBooking(bookingId: string, tenantId: string): Promise<ActionResult> {
  const session = await auth();
  if (!session?.user?.id) return {success: false, error: "Not authenticated"};

  try {
    const db = getTenantDb(tenantId);
    const booking = await db.booking.findFirst({
      where: {id: bookingId},
      include: {tenant: true}
    });

    if (!booking) return {success: false, error: "Booking not found"};

    // Check if invoice already exists
    const existing = await db.invoice.findFirst({where: {bookingId}});
    if (existing) return {success: true, id: existing.id};

    const year = new Date().getFullYear();
    const random = Math.random().toString(36).substring(2, 6).toUpperCase();
    const prefix = booking.tenant.invoicePrefix ?? "INV";
    const invoiceNumber = `${prefix}-${year}-${random}`;

    const invoice = await db.invoice.create({
      data: {
        tenantId,
        bookingId,
        invoiceNumber,
        status: "ISSUED",
        issueDate: new Date(),
        dueDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
        subtotal: booking.subtotal,
        discountAmount: booking.discountAmount,
        taxAmount: booking.taxAmount,
        totalAmount: booking.totalAmount,
        paidAmount: booking.paidAmount,
        currency: booking.currency
      }
    });

    revalidatePath(`/company/${booking.tenant.slug}/invoices`);
    return {success: true, id: invoice.id};
  } catch {
    return {success: false, error: "Failed to create invoice"};
  }
}

export async function registerPayment(formData: FormData): Promise<ActionResult> {
  const session = await auth();
  if (!session?.user?.id) return {success: false, error: "Not authenticated"};

  const tenantId = formData.get("tenantId") as string;
  const bookingId = formData.get("bookingId") as string | null;
  const invoiceId = formData.get("invoiceId") as string | null;
  const amount = parseFloat(formData.get("amount") as string);
  const method = formData.get("method") as string;
  const providerReference = formData.get("reference") as string | null;
  const currency = formData.get("currency") as string;
  const tenantSlug = formData.get("tenantSlug") as string;

  if (!tenantId || !amount || !method || !currency) {
    return {success: false, error: "Missing required fields"};
  }

  try {
    const db = getTenantDb(tenantId);

    const payment = await db.paymentTransaction.create({
      data: {
        tenantId,
        bookingId: bookingId ?? undefined,
        invoiceId: invoiceId ?? undefined,
        customerUserId: session.user.id,
        status: "PAID",
        method: method as never,
        amount,
        currency: currency as never,
        providerReference: providerReference ?? null,
        paidAt: new Date()
      }
    });

    // Update booking paidAmount if applicable
    if (bookingId) {
      const booking = await db.booking.findFirst({where: {id: bookingId}});
      if (booking) {
        const newPaid = Number(booking.paidAmount) + amount;
        const remaining = Math.max(0, Number(booking.totalAmount) - newPaid);
        await prisma.booking.update({
          where: {id: bookingId},
          data: {paidAmount: newPaid, remainingAmount: remaining}
        });
      }
    }

    // Update invoice paidAmount if applicable
    if (invoiceId) {
      const invoice = await db.invoice.findFirst({where: {id: invoiceId}});
      if (invoice) {
        const newPaid = Number(invoice.paidAmount) + amount;
        const newStatus = newPaid >= Number(invoice.totalAmount) ? "PAID" : "PARTIALLY_PAID";
        await prisma.invoice.update({
          where: {id: invoiceId},
          data: {paidAmount: newPaid, status: newStatus}
        });
      }
    }

    revalidatePath(`/company/${tenantSlug}/payments`);
    revalidatePath(`/company/${tenantSlug}/invoices`);
    return {success: true, id: payment.id};
  } catch {
    return {success: false, error: "Failed to register payment"};
  }
}
