import { prisma } from "@/lib/prisma";

export type AdminSearchHit =
  | {
      type: "user";
      id: string;
      title: string;
      subtitle: string;
      href: string;
    }
  | {
      type: "trip";
      id: string;
      title: string;
      subtitle: string;
      href: string;
    }
  | {
      type: "booking";
      id: string;
      title: string;
      subtitle: string;
      href: string;
    };

/**
 * Resolve query admin search ke entity detail page yang paling relevan.
 * Dispatch berdasarkan pola input:
 * - email (`@`) → user lookup exact
 * - `midtrans-<bookingId>-<n>` / `manual-<bookingId>` → booking detail
 * - cuid (~25 char alphanumeric, mulai `cm`) → coba trip → booking → user
 * - sisanya → fuzzy search trip title/destination + user name
 */
export const adminSearchService = {
  async resolve(query: string, limit = 10): Promise<AdminSearchHit[]> {
    const q = query.trim();
    if (q.length < 2) return [];

    // Email exact
    if (q.includes("@")) {
      const user = await prisma.user.findUnique({
        where: { email: q.toLowerCase() },
        select: { id: true, name: true, email: true },
      });
      if (user) {
        return [
          {
            type: "user",
            id: user.id,
            title: user.name,
            subtitle: user.email,
            href: `/admin/users/${user.id}`,
          },
        ];
      }
    }

    // Midtrans / manual order_id pattern
    if (q.startsWith("midtrans-") || q.startsWith("manual-")) {
      const payment = await prisma.payment.findUnique({
        where: { externalOrderId: q },
        select: {
          bookingId: true,
          booking: {
            select: {
              trip: { select: { title: true } },
              user: { select: { name: true, email: true } },
            },
          },
        },
      });
      if (payment) {
        return [
          {
            type: "booking",
            id: payment.bookingId,
            title: `Booking: ${payment.booking.trip.title}`,
            subtitle: `${payment.booking.user.name} · ${payment.booking.user.email}`,
            href: `/admin/bookings/${payment.bookingId}`,
          },
        ];
      }
    }

    // CUID pattern — try trip → booking → user
    if (/^cm[a-z0-9]{10,}$/i.test(q)) {
      const [trip, booking, user] = await Promise.all([
        prisma.trip.findUnique({
          where: { id: q },
          select: { id: true, title: true, destination: true },
        }),
        prisma.booking.findUnique({
          where: { id: q },
          select: {
            id: true,
            trip: { select: { title: true } },
            user: { select: { name: true, email: true } },
          },
        }),
        prisma.user.findUnique({
          where: { id: q },
          select: { id: true, name: true, email: true },
        }),
      ]);
      const hits: AdminSearchHit[] = [];
      if (trip) {
        hits.push({
          type: "trip",
          id: trip.id,
          title: trip.title,
          subtitle: trip.destination,
          href: `/admin/trips/${trip.id}`,
        });
      }
      if (booking) {
        hits.push({
          type: "booking",
          id: booking.id,
          title: `Booking: ${booking.trip.title}`,
          subtitle: `${booking.user.name} · ${booking.user.email}`,
          href: `/admin/bookings/${booking.id}`,
        });
      }
      if (user) {
        hits.push({
          type: "user",
          id: user.id,
          title: user.name,
          subtitle: user.email,
          href: `/admin/users/${user.id}`,
        });
      }
      if (hits.length > 0) return hits;
    }

    // Fuzzy: trip + user
    const [trips, users] = await Promise.all([
      prisma.trip.findMany({
        where: {
          OR: [
            { title: { contains: q, mode: "insensitive" } },
            { destination: { contains: q, mode: "insensitive" } },
          ],
        },
        select: { id: true, title: true, destination: true, location: true },
        take: limit,
        orderBy: { date: "desc" },
      }),
      prisma.user.findMany({
        where: {
          OR: [
            { name: { contains: q, mode: "insensitive" } },
            { email: { contains: q, mode: "insensitive" } },
          ],
        },
        select: { id: true, name: true, email: true },
        take: limit,
        orderBy: { createdAt: "desc" },
      }),
    ]);

    return [
      ...users.map<AdminSearchHit>((u) => ({
        type: "user",
        id: u.id,
        title: u.name,
        subtitle: u.email,
        href: `/admin/users/${u.id}`,
      })),
      ...trips.map<AdminSearchHit>((t) => ({
        type: "trip",
        id: t.id,
        title: t.title,
        subtitle: `${t.destination} · ${t.location}`,
        href: `/admin/trips/${t.id}`,
      })),
    ].slice(0, limit);
  },
};
