import { db, users, eq } from "@epicure/db";

export const USERNAME_PATTERN = /^[a-z0-9_]{3,20}$/;

/** Lowercase alnum-and-underscore slug, at least 3 chars, at most 20. */
function slugify(seed: string): string {
  const base = seed
    .split("@")[0]! // if seed is an email, drop the domain
    .toLowerCase()
    .replace(/[^a-z0-9_]/g, "")
    .slice(0, 20);
  return base.length >= 3 ? base : `${base}user`.slice(0, 20);
}

/**
 * Every user needs a username — it's the only thing profile pages, follows,
 * and people-search key on, but there's no signup-time or settings UI to set
 * one. Called from the user.create.before hook (lib/auth/server.ts) so every
 * account gets one automatically, generated from their name or email.
 */
export async function generateUniqueUsername(seed: string): Promise<string> {
  const base = slugify(seed);
  let candidate = base;
  let suffix = 0;

  while (true) {
    const existing = await db.query.users.findFirst({
      where: eq(users.username, candidate),
      columns: { id: true },
    });
    if (!existing) return candidate;
    suffix += 1;
    candidate = `${base}${suffix}`.slice(0, 20);
  }
}

/** True if `candidate` belongs to some other user — a user re-saving their own current username is not a conflict. */
export async function isUsernameTaken(candidate: string, excludeUserId: string): Promise<boolean> {
  const existing = await db.query.users.findFirst({
    where: eq(users.username, candidate),
    columns: { id: true },
  });
  return !!existing && existing.id !== excludeUserId;
}
