import type {AuthUser} from '@/features/auth/types/auth';

/**
 * The mock user directory. Server-only — nothing here is ever bundled to the
 * client, because the only importers are route handlers.
 *
 * ── On the plaintext passwords ────────────────────────────────────────────
 * They are plaintext BECAUSE this is a fixture, and the fixture is the one
 * place where that is safe: it never leaves the server, and there is no real
 * credential in it. What matters architecturally is that `verifyCredentials`
 * below is the ONLY function that ever sees a password. When a real backend
 * arrives, that function's body becomes an HTTP call (or an argon2/bcrypt
 * comparison against a user table) and every other file in the app is
 * untouched — including the login form, which already only knows how to ask.
 *
 * Do not add a "demo" user that accepts any password. The whole point of this
 * layer is that wrong credentials fail.
 */

interface MockUserRecord extends AuthUser {
  password: string;
}

const USERS: MockUserRecord[] = [
  {
    id: 'usr_owner_01',
    email: 'aravind@nealre.in',
    name: 'Aravind',
    role: 'owner',
    organisation: 'Loyaly Retail Pvt Ltd',
    password: 'admin123',
  },
  {
    id: 'usr_owner_02',
    email: 'aravind@nearle.in',
    name: 'Aravind',
    role: 'owner',
    organisation: 'Loyaly Retail Pvt Ltd',
    password: 'admin123',
  },
  {
    id: 'usr_mgr_01',
    email: 'priya.sharma@loyaly.ai',
    name: 'Priya Sharma',
    role: 'manager',
    organisation: 'Loyaly Retail Pvt Ltd',
    password: 'indiranagar@01',
  },
  {
    id: 'usr_analyst_01',
    email: 'analyst@loyaly.ai',
    name: 'Rahul Menon',
    role: 'analyst',
    organisation: 'Loyaly Retail Pvt Ltd',
    password: 'reports@2026',
  },
];

/** Public projection — the record minus the credential. */
function toAuthUser(record: MockUserRecord): AuthUser {
  // Field-by-field rather than a rest-spread that drops `password`: a spread
  // silently carries anything added to the record later, and this projection
  // is the boundary that keeps credentials out of every response.
  return {
    id: record.id,
    email: record.email,
    name: record.name,
    role: record.role,
    organisation: record.organisation,
  };
}

export type CredentialCheck =
  | {outcome: 'ok'; user: AuthUser}
  | {outcome: 'unknown_email'}
  | {outcome: 'wrong_password'};

/**
 * The single credential-checking seam.
 *
 * Note the two distinct failure outcomes. That is a deliberate product choice
 * — the brief asks for "wrong email" and "wrong password" to read differently
 * — and it is worth knowing that it also makes the login form a user
 * enumeration oracle: an attacker can discover which addresses have accounts.
 * If that trade stops being acceptable, collapse both branches at the ROUTE
 * (map them to one 'invalid_credentials' message) rather than here, so the
 * distinction stays available to audit logging.
 */
export function verifyCredentials(
  email: string,
  password: string,
): CredentialCheck {
  const record = USERS.find(
    (u) => u.email.toLowerCase() === email.trim().toLowerCase(),
  );
  if (!record) return {outcome: 'unknown_email'};
  if (record.password !== password) return {outcome: 'wrong_password'};
  return {outcome: 'ok', user: toAuthUser(record)};
}

/** Used by the session endpoint to re-resolve a cookie subject to a user. */
export function findUserById(id: string): AuthUser | null {
  const record = USERS.find((u) => u.id === id);
  return record ? toAuthUser(record) : null;
}
