import { type Prisma, type UserRole } from '@prisma/client';
import { type PrismaService } from '@modules/shared';
import {
  type UserListResult,
  type UserDetail,
} from '../../domain/repositories/admin-query.repository';

export async function getUsers(
  prisma: PrismaService,
  params: {
    page: number;
    limit: number;
    role?: string;
    isActive?: boolean;
    search?: string;
  },
): Promise<UserListResult> {
  const { page, limit, role, isActive, search } = params;
  const skip = (page - 1) * limit;

  const where: Prisma.UserWhereInput = {};
  if (role) where.role = role as UserRole;
  if (isActive !== undefined) where.isActive = isActive;
  if (search) {
    // With encrypted email/phone fields, LIKE search only works on fullName.
    // For exact email/phone lookups, use deterministic hash columns.
    const hashLookup = prisma.fieldEncryption.computeHash(search);
    const conditions: Prisma.UserWhereInput[] = [
      { fullName: { contains: search, mode: 'insensitive' } },
    ];
    if (hashLookup) {
      conditions.push({ emailHash: hashLookup });
      conditions.push({ phoneHash: hashLookup });
    }
    where.OR = conditions;
  }

  const [users, total] = await Promise.all([
    prisma.user.findMany({
      where,
      select: {
        id: true,
        email: true,
        phone: true,
        fullName: true,
        role: true,
        kycStatus: true,
        isActive: true,
        createdAt: true,
      },
      orderBy: { createdAt: 'desc' },
      skip,
      take: limit,
    }),
    prisma.user.count({ where }),
  ]);

  return {
    data: users,
    total,
    page,
    limit,
    totalPages: Math.ceil(total / limit),
  };
}

export async function getUserDetail(
  prisma: PrismaService,
  userId: string,
): Promise<UserDetail | null> {
  const user = await prisma.user.findUnique({
    where: { id: userId },
    include: {
      subscription: {
        include: { plan: { select: { tier: true } } },
      },
      listings: {
        select: { id: true, status: true },
        take: 100,
        orderBy: { createdAt: 'desc' },
      },
    },
  });

  if (!user) return null;

  const [transactionsCount, recentListings] = await Promise.all([
    prisma.transaction.count({
      where: { buyerId: userId },
    }),
    prisma.listing.findMany({
      where: { sellerId: userId },
      select: {
        id: true,
        status: true,
        createdAt: true,
        property: { select: { title: true } },
      },
      orderBy: { createdAt: 'desc' },
      take: 10,
    }),
  ]);

  const recentActivity = recentListings.map((l) => ({
    type: 'listing',
    description: `${l.property.title} — ${l.status}`,
    createdAt: l.createdAt,
  }));

  return {
    id: user.id,
    email: user.email,
    phone: user.phone,
    fullName: user.fullName,
    avatarUrl: user.avatarUrl,
    role: user.role,
    kycStatus: user.kycStatus,
    kycData: user.kycData,
    isActive: user.isActive,
    createdAt: user.createdAt,
    updatedAt: user.updatedAt,
    listingsCount: user.listings.length,
    activeListingsCount: user.listings.filter((l) => l.status === 'ACTIVE').length,
    transactionsCount,
    subscription: user.subscription
      ? {
          planTier: user.subscription.plan.tier,
          status: user.subscription.status,
          currentPeriodEnd: user.subscription.currentPeriodEnd,
        }
      : null,
    recentActivity,
  };
}
