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

export interface PeopleFilters {
  city?: string;
  interest?: string;
  vibe?: Vibe;
}

export const userRepo = {
  async findByEmail(email: string) {
    return prisma.user.findUnique({ where: { email } });
  },

  async findById(id: string) {
    return prisma.user.findUnique({ where: { id } });
  },

  /** Profil publik (tanpa password) untuk halaman akun. */
  async findPublicProfileById(id: string) {
    return prisma.user.findUnique({
      where: { id },
      select: {
        id: true,
        name: true,
        email: true,
        image: true,
        createdAt: true,
      },
    });
  },

  /**
   * Profil sosial publik untuk halaman /u/[id]. JANGAN sertakan field sensitif
   * (email, password, KYC). Hanya yang user pilih untuk dibagikan.
   */
  async findSocialProfileById(id: string) {
    return prisma.user.findUnique({
      where: { id },
      select: {
        id: true,
        name: true,
        image: true,
        createdAt: true,
        profile: {
          select: {
            bio: true,
            city: true,
            interests: true,
            instagram: true,
            vibe: true,
          },
        },
        organizerVerification: { select: { status: true } },
      },
    });
  },

  /**
   * Discovery /people: ambil user yang punya profil sosial terisi (minimal salah
   * satu dari bio/city/interests/vibe). Filter optional by city/interest/vibe.
   * Tidak ekspos email/KYC.
   */
  async findPeople(filters?: PeopleFilters, limit = 60) {
    const profileWhere: Prisma.UserProfileWhereInput = {
      OR: [
        { bio: { not: null } },
        { city: { not: null } },
        { vibe: { not: null } },
        { interests: { isEmpty: false } },
      ],
    };

    if (filters?.city) {
      profileWhere.city = {
        contains: filters.city,
        mode: "insensitive",
      };
    }
    if (filters?.interest) {
      profileWhere.interests = { has: filters.interest.toLowerCase() };
    }
    if (filters?.vibe) {
      profileWhere.vibe = filters.vibe;
    }

    return prisma.user.findMany({
      where: { profile: { is: profileWhere } },
      select: {
        id: true,
        name: true,
        image: true,
        createdAt: true,
        profile: {
          select: {
            bio: true,
            city: true,
            interests: true,
            vibe: true,
          },
        },
        organizerVerification: { select: { status: true } },
      },
      orderBy: { createdAt: "desc" },
      take: limit,
    });
  },

  async create(data: Prisma.UserCreateInput) {
    return prisma.user.create({ data });
  },

  /**
   * Admin search: by email/name (case-insensitive contains) + filter
   * suspended status. Limit 100 supaya tidak load semua user di list page.
   */
  async searchForAdmin(filters: { q?: string; suspended?: boolean }) {
    const where: Prisma.UserWhereInput = {};
    if (filters.q) {
      where.OR = [
        { email: { contains: filters.q, mode: "insensitive" } },
        { name: { contains: filters.q, mode: "insensitive" } },
      ];
    }
    if (typeof filters.suspended === "boolean") {
      where.suspended = filters.suspended;
    }
    return prisma.user.findMany({
      where,
      select: {
        id: true,
        name: true,
        email: true,
        image: true,
        createdAt: true,
        suspended: true,
        suspendedAt: true,
        organizerVerification: { select: { status: true } },
        _count: {
          select: {
            trips: true,
            participations: { where: { status: { not: "CANCELLED" } } },
          },
        },
      },
      orderBy: { createdAt: "desc" },
      take: 100,
    });
  },

  /**
   * Detail user untuk admin: full profile + booking history + organized
   * trips + verification. Tidak ekspos password atau OAuth token.
   */
  async findByIdForAdmin(id: string) {
    return prisma.user.findUnique({
      where: { id },
      select: {
        id: true,
        name: true,
        email: true,
        image: true,
        createdAt: true,
        acceptedTermsAndPrivacy: true,
        acceptedAt: true,
        suspended: true,
        suspendedAt: true,
        suspendedReason: true,
        suspendedBy: { select: { id: true, name: true, email: true } },
        profile: true,
        organizerVerification: {
          select: {
            id: true,
            status: true,
            createdAt: true,
            reviewedAt: true,
            rejectionReason: true,
          },
        },
        trips: {
          select: {
            id: true,
            title: true,
            destination: true,
            date: true,
            status: true,
            price: true,
            _count: {
              select: {
                participants: { where: { status: { not: "CANCELLED" } } },
              },
            },
          },
          orderBy: { date: "desc" },
          take: 50,
        },
        bookings: {
          select: {
            id: true,
            amount: true,
            status: true,
            createdAt: true,
            trip: {
              select: { id: true, title: true, date: true, organizerId: true },
            },
          },
          orderBy: { createdAt: "desc" },
          take: 50,
        },
      },
    });
  },

  /** Cek cepat status suspended — dipakai auth guard di server actions. */
  async isSuspended(id: string): Promise<boolean> {
    const u = await prisma.user.findUnique({
      where: { id },
      select: { suspended: true },
    });
    return u?.suspended === true;
  },

  async setSuspension(
    id: string,
    data: {
      suspended: boolean;
      suspendedById?: string | null;
      suspendedReason?: string | null;
    }
  ) {
    return prisma.user.update({
      where: { id },
      data: {
        suspended: data.suspended,
        suspendedAt: data.suspended ? new Date() : null,
        suspendedById: data.suspended ? data.suspendedById ?? null : null,
        suspendedReason: data.suspended ? data.suspendedReason ?? null : null,
      },
    });
  },

  /**
   * Tandai user sudah accept T&C/Privacy. Idempotent: kalau sudah `true`,
   * tidak overwrite `acceptedAt` (audit trail pertama tetap akurat).
   */
  async markAcceptedTerms(id: string) {
    const result = await prisma.user.updateMany({
      where: { id, acceptedTermsAndPrivacy: false },
      data: { acceptedTermsAndPrivacy: true, acceptedAt: new Date() },
    });
    return { updated: result.count > 0 };
  },
};
