"use server";

import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";
import { paymentService } from "@/server/services/payment.service";
import { bookingService } from "@/server/services/booking.service";
import { refundService } from "@/server/services/refund.service";
import { absoluteUrl } from "@/lib/site";
import { revalidatePath } from "next/cache";

export type StartMidtransResponse =
  | { error: string }
  | {
      success: true;
      snapToken: string;
      snapJsUrl: string;
      clientKey: string;
      orderId: string;
    };

/**
 * Mulai pembayaran online via Midtrans untuk trip tertentu. Resolve booking
 * dari (tripId, userId) supaya client tidak perlu tahu bookingId.
 */
export async function startMidtransPaymentAction(
  tripId: string
): Promise<StartMidtransResponse> {
  const session = await getServerSession(authOptions);
  if (!session?.user) {
    return { error: "Kamu harus login terlebih dahulu" };
  }

  try {
    const booking = await bookingService.getByTripAndUser(
      tripId,
      session.user.id
    );
    if (!booking || booking.status === "CANCELLED") {
      return { error: "Kamu tidak terdaftar di trip ini" };
    }

    const result = await paymentService.startMidtransPayment(
      booking.id,
      session.user.id,
      { finishUrl: absoluteUrl(`/trips/${tripId}/payment`) }
    );
    return {
      success: true,
      snapToken: result.snapToken,
      snapJsUrl: result.snapJsUrl,
      clientKey: result.clientKey,
      orderId: result.orderId,
    };
  } catch (err) {
    return { error: (err as Error).message };
  }
}

/**
 * Admin variant reconcile — skip ownership check, dipakai dari panel admin
 * `/admin/bookings/[id]` saat investigasi.
 */
export async function adminReconcileMidtransAction(orderId: string) {
  const session = await getServerSession(authOptions);
  if (!session?.user) {
    return { error: "Kamu harus login terlebih dahulu" };
  }
  const { isAdminEmail } = await import("@/lib/admin");
  if (!isAdminEmail(session.user.email)) {
    return { error: "Hanya admin yang bisa melakukan aksi ini" };
  }
  if (!orderId || typeof orderId !== "string") {
    return { error: "order_id tidak valid" };
  }

  try {
    const result = await paymentService.adminReconcile(orderId);
    if (!result.ok) {
      if (result.reason === "not_found") {
        return { error: "Order tidak ditemukan di sistem" };
      }
      return { error: "Status pembayaran tidak cocok dengan tagihan" };
    }
    const { auditLog } = await import("@/server/services/audit-log.service");
    await auditLog.record({
      admin: { id: session.user.id, email: session.user.email },
      action: "PAYMENT_RECONCILE",
      entityType: "Payment",
      entityId: orderId,
      payload: { outcome: result.status },
    });
    return { success: true as const, status: result.status };
  } catch (err) {
    return { error: (err as Error).message };
  }
}

/**
 * Tarik status terkini dari Midtrans untuk satu order, lalu sinkron ke DB.
 * Dipakai oleh payment page saat user kembali dari Snap (redirect bawa
 * `?order_id=...`), dan oleh `MidtransPayButton` di callback `onSuccess`/
 * `onPending`/`onClose` agar UI ter-update tanpa menunggu webhook.
 */
export async function reconcileMidtransPaymentAction(orderId: string) {
  const session = await getServerSession(authOptions);
  if (!session?.user) {
    return { error: "Kamu harus login terlebih dahulu" };
  }
  if (!orderId || typeof orderId !== "string") {
    return { error: "order_id tidak valid" };
  }

  try {
    const result = await paymentService.reconcileFromGateway(
      orderId,
      session.user.id
    );
    if (!result.ok) {
      if (result.reason === "forbidden") {
        return { error: "Order ini bukan milikmu" };
      }
      if (result.reason === "not_found") {
        return { error: "Order tidak ditemukan" };
      }
      return { error: "Status pembayaran tidak cocok dengan tagihan" };
    }
    return { success: true as const, status: result.status };
  } catch (err) {
    return { error: (err as Error).message };
  }
}

/**
 * Peserta cancel booking PAID dengan refund request. Server menghitung
 * nominal refund pakai policy default (lib/refund-policy.ts) — client
 * cuma kirim bookingId untuk cegah tampering.
 */
export async function cancelBookingWithRefundAction(tripId: string) {
  const session = await getServerSession(authOptions);
  if (!session?.user) {
    return { error: "Kamu harus login terlebih dahulu" };
  }

  try {
    const booking = await bookingService.getByTripAndUser(
      tripId,
      session.user.id
    );
    if (!booking) {
      return { error: "Kamu tidak terdaftar di trip ini" };
    }

    const result = await refundService.requestUserCancellation({
      bookingId: booking.id,
      userId: session.user.id,
    });

    revalidatePath(`/trips/${tripId}`);
    revalidatePath("/trips");
    revalidatePath("/");
    revalidatePath("/profile");
    revalidatePath("/admin/refunds");

    return {
      success: true as const,
      kind: result.kind,
      refundAmount: result.refundAmount,
      days: result.days,
    };
  } catch (err) {
    return { error: (err as Error).message };
  }
}
