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

export const bookingRepo = {
  async findById(id: string) {
    return prisma.booking.findUnique({ where: { id } });
  },

  async findByParticipantId(participantId: string) {
    return prisma.booking.findUnique({
      where: { participantId },
      include: { payments: { orderBy: { createdAt: "desc" } } },
    });
  },

  async findByTripAndUser(tripId: string, userId: string) {
    return prisma.booking.findUnique({
      where: { tripId_userId: { tripId, userId } },
      include: { payments: { orderBy: { createdAt: "desc" } } },
    });
  },

  /**
   * Detail booking lengkap untuk admin investigation: payments (with raw
   * callback), refunds, payout, trip + organizer, user. Dipakai oleh
   * `/admin/bookings/[id]` untuk timeline lengkap money flow.
   */
  async findByIdForAdmin(id: string) {
    return prisma.booking.findUnique({
      where: { id },
      include: {
        trip: {
          select: {
            id: true,
            title: true,
            destination: true,
            location: true,
            date: true,
            endDate: true,
            price: true,
            status: true,
            organizer: { select: { id: true, name: true, email: true } },
          },
        },
        user: { select: { id: true, name: true, email: true, image: true } },
        participant: true,
        payments: { orderBy: { createdAt: "asc" } },
        refunds: {
          orderBy: { createdAt: "asc" },
          include: {
            reviewedBy: { select: { id: true, name: true, email: true } },
          },
        },
        payout: {
          include: {
            processedBy: { select: { id: true, name: true, email: true } },
          },
        },
      },
    });
  },

  async create(
    data: Pick<
      Prisma.BookingUncheckedCreateInput,
      "tripId" | "userId" | "participantId" | "amount" | "status"
    >
  ) {
    return prisma.booking.create({ data });
  },

  async updateStatus(id: string, status: Prisma.BookingUpdateInput["status"]) {
    return prisma.booking.update({
      where: { id },
      data: { status },
    });
  },

  async updateStatusByParticipantId(
    participantId: string,
    status: Prisma.BookingUpdateInput["status"]
  ) {
    return prisma.booking.updateMany({
      where: { participantId },
      data: { status },
    });
  },

  /**
   * Jumlah booking PAID/PARTIALLY_REFUNDED di trip. Dipakai untuk preview
   * dampak cancel-trip (berapa peserta yang akan dapat auto-refund).
   */
  async countSettledForTrip(tripId: string) {
    return prisma.booking.count({
      where: {
        tripId,
        status: { in: ["PAID", "PARTIALLY_REFUNDED"] },
      },
    });
  },
};
