import { prisma } from "../../config/prisma";
import { OtpPurpose, Role } from "@prisma/client";

// ---------- USER ----------

export function findUserByEmail(email: string) {
  return prisma.user.findUnique({ where: { email } });
}

export function findUserByPhone(phone: string) {
  return prisma.user.findUnique({ where: { phone } });
}

export function findActiveUserByEmail(email: string) {
  return prisma.user.findFirst({
    where: { email, status: "ACTIVE" },
  });
}

export function findUserById(id: string) {
  return prisma.user.findUnique({
    where: { id },
    select: {
      id: true,
      name: true,
      email: true,
      phone: true,
      role: true,
      status: true,
      organizationId: true,
      passwordHash: true,
      avatarUrl: true,
      createdAt: true,
      updatedAt: true,
    },
  });
}

export function deleteUserById(id: string) {
  return prisma.user.delete({ where: { id } });
}

export function createUser(data: {
  organizationId?: string;
  name: string;
  email: string;
  passwordHash: string;
  phone?: string;
  role: Role;
}) {
  return prisma.user.create({
    data: {
      organizationId: data.organizationId,
      name: data.name,
      email: data.email,
      passwordHash: data.passwordHash,
      phone: data.phone,
      role: "ADMIN",
      status: "INACTIVE",
    },
  });
}

export function activateUser(userId: string) {
  return prisma.user.update({
    where: { id: userId },
    data: { status: "ACTIVE" },
  });
}

export function updateUserPassword(userId: string, passwordHash: string) {
  return prisma.user.update({
    where: { id: userId },
    data: { passwordHash },
  });
}

export function updateUserProfile(userId: string, data: { name?: string; phone?: string; avatarUrl?: string | null }) {
  return prisma.user.update({
    where: { id: userId },
    data,
  });
}

// ---------- ORGANIZATION ----------

export function findOrganizationById(id: string) {
  return prisma.organization.findUnique({ where: { id } });
}

// ---------- SESSION ----------

export function createSession(data: {
  userId: string;
  refreshToken: string;
  userAgent?: string;
  ipAddress?: string;
  expiresAt: Date;
}) {
  return prisma.session.create({ data });
}

export function findSessionByToken(refreshToken: string) {
  return prisma.session.findUnique({
    where: { refreshToken },
    include: { user: true },
  });
}

export function deleteSessionById(id: string) {
  return prisma.session.delete({ where: { id } }).catch(() => null);
}

export function deleteSessionByToken(refreshToken: string) {
  return prisma.session.delete({ where: { refreshToken } }).catch(() => null);
}

export function findSessionsByUser(userId: string) {
  return prisma.session.findMany({
    where: { userId },
    select: {
      id: true,
      userAgent: true,
      ipAddress: true,
      createdAt: true,
      expiresAt: true,
    },
    orderBy: { createdAt: "desc" },
  });
}

export function findSessionByIdAndUser(id: string, userId: string) {
  return prisma.session.findFirst({ where: { id, userId } });
}

export function deleteAllSessionsForUser(userId: string, exceptToken?: string) {
  return prisma.session.deleteMany({
    where: {
      userId,
      ...(exceptToken ? { NOT: { refreshToken: exceptToken } } : {}),
    },
  });
}

// ---------- OTP ----------

export function createOtp(data: {
  email: string;
  otp: string;
  purpose: OtpPurpose;
  expiresAt: Date;
}) {
  return prisma.otpVerification.create({
    data: { ...data, verified: false, attempts: 0 },
  });
}

export function findLatestOtp(email: string, purpose?: OtpPurpose) {
  return prisma.otpVerification.findFirst({
    where: purpose ? { email, purpose, verified: false } : { email, verified: false },
    orderBy: { createdAt: "desc" },
  });
}

export function findLatestVerifiedOtp(email: string, purpose: OtpPurpose) {
  return prisma.otpVerification.findFirst({
    where: { email, purpose, verified: true },
    orderBy: { createdAt: "desc" },
  });
}

export function incrementOtpAttempts(id: string) {
  return prisma.otpVerification.update({
    where: { id },
    data: { attempts: { increment: 1 } },
  });
}

export function markOtpVerified(id: string) {
  return prisma.otpVerification.update({
    where: { id },
    data: { verified: true },
  });
}

export function deleteOtpsByEmailAndPurpose(email: string, purpose: OtpPurpose) {
  return prisma.otpVerification.deleteMany({ where: { email, purpose } });
}